diff --git a/src/plugins/debugger/cdb/cdbassembler.cpp b/src/plugins/debugger/cdb/cdbassembler.cpp index 2a05cb3e6e80ec1897bc4cbfea99be1c06d6bfb3..1f3bf61107de4a43fbd19357524644f444e89671 100644 --- a/src/plugins/debugger/cdb/cdbassembler.cpp +++ b/src/plugins/debugger/cdb/cdbassembler.cpp @@ -32,7 +32,6 @@ #include "cdbdebugengine_p.h" #include "cdbsymbolgroupcontext.h" -#include "disassemblerhandler.h" #include "registerhandler.h" #include <QtCore/QVector> @@ -40,8 +39,6 @@ namespace Debugger { namespace Internal { -typedef QList<DisassemblerLine> DisassemblerLineList; - bool getRegisters(CIDebugControl *ctl, CIDebugRegisters *ireg, QList<Register> *registers, @@ -90,35 +87,39 @@ bool getRegisters(CIDebugControl *ctl, // it uses that symbol. class DisassemblerOutputParser { + Q_DISABLE_COPY(DisassemblerOutputParser) public: - explicit DisassemblerOutputParser(DisassemblerLineList *list); + explicit DisassemblerOutputParser(QTextStream &str, int addressFieldWith = 0); void parse(const QStringList &l); private: enum ParseResult { ParseOk, ParseIgnore, ParseFailed }; - ParseResult parseDisassembled(const QString &in, DisassemblerLine* l); + ParseResult parseDisassembled(const QString &in); - DisassemblerLineList *m_list; + const int m_addressFieldWith; + QTextStream &m_str; QString m_sourceSymbol; int m_sourceSymbolOffset; }; -DisassemblerOutputParser::DisassemblerOutputParser(DisassemblerLineList *list) : - m_list(list), +DisassemblerOutputParser::DisassemblerOutputParser(QTextStream &str, int addressFieldWith) : + m_addressFieldWith(addressFieldWith), + m_str(str), m_sourceSymbolOffset(0) { } -// Parse a disassembler line: -// module!class::foo: -// 004017cf cc int 3 -// 77 mainwindow.cpp 004018ff 8d4da8 lea ecx,[ebp-0x58] +/* Parse a disassembler line: + * \code +module!class::foo: + 004017cf cc int 3 +77 mainwindow.cpp 004018ff 8d4da8 lea ecx,[ebp-0x58] +\endcode */ + DisassemblerOutputParser::ParseResult - DisassemblerOutputParser::parseDisassembled(const QString &in, DisassemblerLine* l) + DisassemblerOutputParser::parseDisassembled(const QString &in) { - l->clear(); - // Check if there is a source file if (in.size() < 7) return ParseIgnore; @@ -129,9 +130,11 @@ DisassemblerOutputParser::ParseResult if (simplified.isEmpty()) return ParseIgnore; - QStringList tokens = simplified.split(QLatin1Char(' '), QString::SkipEmptyParts); + const QStringList tokens = simplified.split(QLatin1Char(' '), QString::SkipEmptyParts); + const int tokenCount = tokens.size(); // Check for symbols as 'module!class::foo:' (start of function encountered) - if (tokens.size() == 1) { + // and store as state. + if (tokenCount == 1) { QString symbol = tokens.front(); if (symbol.endsWith(QLatin1Char(':')) && symbol.contains(QLatin1Char('!'))) { symbol.truncate(symbol.size() - 1); @@ -140,51 +143,49 @@ DisassemblerOutputParser::ParseResult } return ParseIgnore; } - if (tokens.size() < 2) + if (tokenCount < 2) return ParseIgnore; - // Symbol display: Do we know a symbol? - if (!m_sourceSymbol.isEmpty()) { - l->symbol = QString(QLatin1Char('<')); - l->symbol += m_sourceSymbol; - if (m_sourceSymbolOffset) { - l->symbol += QLatin1Char('+'); - l->symbol += QString::number(m_sourceSymbolOffset); - } - l->symbol += QLatin1Char('>'); - m_sourceSymbolOffset++; + if (tokenCount < 3) + return ParseFailed; + // Format line. Start with address with the field width given, + // which is important for setting the marker. + const int addressToken = hasSourceFile ? 2 : 0; + m_str << "0x"; + if (m_str.fieldWidth() == m_addressFieldWith) { + m_str << tokens.at(addressToken); + } else { + const QChar oldPadChar = m_str.padChar(); + const int oldFieldWidth = m_str.fieldWidth(); + m_str.setFieldWidth(m_addressFieldWith); + m_str.setPadChar(QLatin1Char('0')); + m_str << tokens.at(addressToken); + m_str.setFieldWidth(oldFieldWidth); + m_str.setPadChar(oldPadChar); } - // Read source file information: If we don't know a symbol yet, - // use the source file. - if (hasSourceFile) { - if (l->symbol.isEmpty()) { - l->symbol = tokens.at(1); - l->symbol += QLatin1Char('+'); - l->symbol += tokens.front(); - } - tokens.pop_front(); - tokens.pop_front(); + m_str << ' '; + // Symbol display: Do we know a symbol? -> Display with offset. + // Else default to source file information. + if (m_sourceSymbol.isEmpty()) { + if (hasSourceFile) + m_str << tokens.at(1) << '+' << tokens.front(); + } else { + m_str << '<' << m_sourceSymbol; + if (m_sourceSymbolOffset) + m_str << '+' << m_sourceSymbolOffset; + m_str << '>'; + m_sourceSymbolOffset++; } - l->symbolDisplay = l->symbol; - // Get offset address and instruction - if (tokens.size() < 3) - return ParseFailed; - l->addressDisplay = l->address = tokens.front(); - tokens.pop_front(); - // The rest is effective address & instructions - if (tokens.size() > 1) - tokens.pop_front(); - l->mnemonic = tokens.join(QString(QLatin1Char(' '))); + for (int i = addressToken + 1; i < tokenCount; i++) + m_str << ' ' << tokens.at(i); + m_str << '\n'; return ParseOk; } void DisassemblerOutputParser::parse(const QStringList &l) { - DisassemblerLine dLine; foreach(const QString &line, l) { - switch (parseDisassembled(line, &dLine)) { + switch (parseDisassembled(line)) { case ParseOk: - m_list->push_back(dLine); - break; case ParseIgnore: break; case ParseFailed: @@ -199,12 +200,13 @@ bool dissassemble(CIDebugClient *client, ULONG64 offset, unsigned long beforeLines, unsigned long afterLines, - QList<DisassemblerLine> *lines, + int addressFieldWith, + QTextStream &str, QString *errorMessage) { if (debugCDB) qDebug() << Q_FUNC_INFO << offset; - lines->clear(); + const ULONG flags = DEBUG_DISASM_MATCHING_SYMBOLS|DEBUG_DISASM_SOURCE_LINE_NUMBER|DEBUG_DISASM_SOURCE_FILE_NAME; // Catch the output by temporarily setting another handler. // We use the method that outputs to the output handler as it @@ -219,10 +221,10 @@ bool dissassemble(CIDebugClient *client, offset, flags, 0, 0, 0, 0); if (FAILED(hr)) { *errorMessage= QString::fromLatin1("Unable to dissamble at 0x%1: %2"). - arg(QString::number(offset, 16), msgComFailed("OutputDisassemblyLines", hr)); + arg(offset, 0, 16).arg(msgComFailed("OutputDisassemblyLines", hr)); return false; } - DisassemblerOutputParser parser(lines); + DisassemblerOutputParser parser(str, addressFieldWith); parser.parse(stringHandler.result().split(QLatin1Char('\n'))); return true; } diff --git a/src/plugins/debugger/cdb/cdbassembler.h b/src/plugins/debugger/cdb/cdbassembler.h index ef55505849ed0b680f9cdbbc995605f16f96a695..03207551eeac2943652bb5c774ec0b796d33d74e 100644 --- a/src/plugins/debugger/cdb/cdbassembler.h +++ b/src/plugins/debugger/cdb/cdbassembler.h @@ -35,11 +35,13 @@ #include "cdbcom.h" +QT_BEGIN_NAMESPACE +class QTextStream; +QT_END_NAMESPACE + namespace Debugger { namespace Internal { -class DisassemblerLine; - // Utilities related to assembler code. class Register; @@ -54,7 +56,8 @@ bool dissassemble(CIDebugClient *client, ULONG64 offset, unsigned long beforeLines, unsigned long afterLines, - QList<DisassemblerLine> *lines, + int addressFieldWith /* = 0*/, + QTextStream &str, QString *errorMessage); } // namespace Internal diff --git a/src/plugins/debugger/cdb/cdbdebugengine.cpp b/src/plugins/debugger/cdb/cdbdebugengine.cpp index 0855102892e72c2b41ffba099e6d47d8b506b050..733d1d423ad9fcb1d5ff77c10f3d00a487b7bb47 100644 --- a/src/plugins/debugger/cdb/cdbdebugengine.cpp +++ b/src/plugins/debugger/cdb/cdbdebugengine.cpp @@ -37,6 +37,7 @@ #include "cdbassembler.h" #include "cdboptionspage.h" #include "cdboptions.h" +#include "debuggeragents.h" #include "debuggeractions.h" #include "debuggermanager.h" @@ -45,7 +46,6 @@ #include "watchhandler.h" #include "registerhandler.h" #include "moduleshandler.h" -#include "disassemblerhandler.h" #include "watchutils.h" #include <coreplugin/icore.h> @@ -1258,37 +1258,50 @@ bool CdbDebugEnginePrivate::attemptBreakpointSynchronization(QString *errorMessa } void CdbDebugEngine::fetchDisassembler(DisassemblerViewAgent *agent, - const StackFrame &frame) + const StackFrame & frame) { - // was: void CdbDebugEngine::reloadDisassembler() - // use agent->address() to create a listing - -/* enum { ContextLines = 40 }; - // Do we have a top stack frame? - const ULONG64 offset = m_d->m_currentStackTrace ? m_d->m_currentStackTrace->instructionOffset() : ULONG64(0); - if (debugCDB) - qDebug() << Q_FUNC_INFO << offset; + bool ok = false; + QString errorMessage; + do { + // get address + QString address; + if (!frame.file.isEmpty()) + address = frame.address; + if (address.isEmpty()) + address = agent->address(); + if (debugCDB) + qDebug() << "fetchDisassembler" << address << " Agent: " << agent->address() + << " Frame" << frame.file << frame.line << frame.address; + if (address.isEmpty()) { // Clear window + agent->setContents(QString()); + ok = true; + break; + } + if (address.startsWith(QLatin1String("0x"))) + address.remove(0, 2); + const int addressFieldWith = address.size(); // For the Marker - DisassemblerHandler *dh = m_d->m_debuggerManagerAccess->disassemblerHandler(); - if (offset) { - QList<DisassemblerLine> lines; - QString errorMessage; + const ULONG64 offset = address.toULongLong(&ok, 16); + if (!ok) { + errorMessage = QString::fromLatin1("Internal error: Invalid address for disassembly: '%1'.").arg(agent->address()); + break; + } + QString disassembly; QApplication::setOverrideCursor(Qt::WaitCursor); - const bool drc = dissassemble(m_d->m_cif.debugClient, m_d->m_cif.debugControl, offset, - ContextLines, ContextLines, &lines, &errorMessage); + ok = dissassemble(m_d->m_cif.debugClient, m_d->m_cif.debugControl, offset, addressFieldWith, + ContextLines, ContextLines, QTextStream(&disassembly), &errorMessage); QApplication::restoreOverrideCursor(); - if (drc) { - dh->setLines(lines); - if (lines.size() > ContextLines) - dh->setCurrentLine(ContextLines); - } else { - warning(msgFunctionFailed(Q_FUNC_INFO, errorMessage)); - } - } else { - dh->setLines(QList<DisassemblerLine>()); + if (!ok) + break; + agent->setContents(disassembly); + + } while (false); + + if (!ok) { + agent->setContents(QString()); + warning(errorMessage); } -*/ } void CdbDebugEngine::reloadModules() diff --git a/src/plugins/debugger/cdb/cdbdebugoutput.cpp b/src/plugins/debugger/cdb/cdbdebugoutput.cpp index fb2e0e21da10409654d8da0043ddbba00b6fae62..b3c8a76575f5518e71c86c4aa116574bcb7e2d27 100644 --- a/src/plugins/debugger/cdb/cdbdebugoutput.cpp +++ b/src/plugins/debugger/cdb/cdbdebugoutput.cpp @@ -81,7 +81,7 @@ STDMETHODIMP CdbDebugOutputBase::Output( ) { const QString msg = QString::fromUtf16(reinterpret_cast<const ushort *>(text)); - output(mask, msg.trimmed()); + output(mask, msg); return S_OK; } @@ -124,10 +124,8 @@ CdbDebugOutput::CdbDebugOutput() { } -void CdbDebugOutput::output(ULONG mask, const QString &_msg) +void CdbDebugOutput::output(ULONG mask, const QString &msg) { - QString msg = _msg + '\n'; - if (debugCDB > 1) qDebug() << Q_FUNC_INFO << "\n " << msg; diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp index 72a59a1921f8bddc29c293cb07a80ac2b4b6da36..2c6f6b78b7c92292008981dde5bc3b92a310de89 100644 --- a/src/plugins/debugger/debuggermanager.cpp +++ b/src/plugins/debugger/debuggermanager.cpp @@ -47,6 +47,7 @@ #include "moduleshandler.h" #include "registerhandler.h" #include "stackhandler.h" +#include "stackframe.h" #include "watchhandler.h" #include "debuggerdialogs.h" diff --git a/src/plugins/debugger/debuggermanager.h b/src/plugins/debugger/debuggermanager.h index 2df7d9c5ab582da93ff18e54faf8fed51255b942..ab5f1e06104153e180c9de849cdeac34e0801935 100644 --- a/src/plugins/debugger/debuggermanager.h +++ b/src/plugins/debugger/debuggermanager.h @@ -76,7 +76,7 @@ class BreakpointData; class ModulesHandler; class RegisterHandler; class SourceFilesWindow; -class StackFrame; +struct StackFrame; class StackHandler; class Symbol; class ThreadsHandler; diff --git a/src/plugins/debugger/debuggerplugin.h b/src/plugins/debugger/debuggerplugin.h index 74928abe447de7a0f03a7723eff45ba2ec26fbe5..a4cf504412ddadce63fce891db5bdcdff2c01932 100644 --- a/src/plugins/debugger/debuggerplugin.h +++ b/src/plugins/debugger/debuggerplugin.h @@ -62,7 +62,7 @@ class DebuggerManager; class DebuggerRunner; class DebugMode; class DisassemblerViewAgent; -class StackFrame; +struct StackFrame; class DebuggerPlugin : public ExtensionSystem::IPlugin { diff --git a/src/plugins/debugger/idebuggerengine.h b/src/plugins/debugger/idebuggerengine.h index 9bc57194699681ad9f628be9ca2f9625e36b481d..abfacb97463667a9ded822ce5f914608f113b048 100644 --- a/src/plugins/debugger/idebuggerengine.h +++ b/src/plugins/debugger/idebuggerengine.h @@ -49,7 +49,7 @@ namespace Internal { class DebuggerStartParameters; class DisassemblerViewAgent; class MemoryViewAgent; -class StackFrame; +struct StackFrame; class Symbol; class WatchData; @@ -98,8 +98,8 @@ public: virtual void watchPoint(const QPoint &) {} virtual void fetchMemory(MemoryViewAgent *, quint64 addr, quint64 length) { Q_UNUSED(addr); Q_UNUSED(length); } - virtual void fetchDisassembler(DisassemblerViewAgent *, const StackFrame &frame) - { Q_UNUSED(frame); } + virtual void fetchDisassembler(DisassemblerViewAgent *, const StackFrame & /* frame */) + { } }; } // namespace Internal diff --git a/src/plugins/debugger/stackframe.h b/src/plugins/debugger/stackframe.h index 35108aef3eff8843252dc161b5fd8e16bd68e9c1..8a9f1c2a41667f3e09852d76439b1a5acbee6b20 100644 --- a/src/plugins/debugger/stackframe.h +++ b/src/plugins/debugger/stackframe.h @@ -31,7 +31,7 @@ #define DEBUGGER_STACKFRAME_H #include <QtCore/QString> -#include <QtCore/QVariant> +#include <QtCore/QMetaType> namespace Debugger { namespace Internal {