aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@nokia.com>2009-08-17 16:03:27 +0200
committerFriedemann Kleint <Friedemann.Kleint@nokia.com>2009-08-17 16:03:27 +0200
commit9fe978fe3933164a8540bab668502d1bcebbb07c (patch)
tree6f734b8d0a20b578d8a1a95f0b0f2ad4206887c3
parent7fb0de70e5090d8d35812791c79f052b961b7759 (diff)
CDB: Compile, new Disassembler architecture.
-rw-r--r--src/plugins/debugger/cdb/cdbassembler.cpp114
-rw-r--r--src/plugins/debugger/cdb/cdbassembler.h9
-rw-r--r--src/plugins/debugger/cdb/cdbdebugengine.cpp65
-rw-r--r--src/plugins/debugger/cdb/cdbdebugoutput.cpp6
-rw-r--r--src/plugins/debugger/debuggermanager.cpp1
-rw-r--r--src/plugins/debugger/debuggermanager.h2
-rw-r--r--src/plugins/debugger/debuggerplugin.h2
-rw-r--r--src/plugins/debugger/idebuggerengine.h6
-rw-r--r--src/plugins/debugger/stackframe.h2
9 files changed, 112 insertions, 95 deletions
diff --git a/src/plugins/debugger/cdb/cdbassembler.cpp b/src/plugins/debugger/cdb/cdbassembler.cpp
index 2a05cb3e6e8..1f3bf61107d 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 ef55505849e..03207551eea 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 0855102892e..733d1d423ad 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 fb2e0e21da1..b3c8a76575f 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 72a59a1921f..2c6f6b78b7c 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 2df7d9c5ab5..ab5f1e06104 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 74928abe447..a4cf504412d 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 9bc57194699..abfacb97463 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 35108aef3ef..8a9f1c2a416 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 {