forked from qt-creator/qt-creator
Implement disassembler for cdb.
Filter debugging output correctly, some glitches. Extract base class for debugging output to be able to intercept debugging output for other purposes (such as disassembling).
This commit is contained in:
@@ -84,16 +84,17 @@ void BreakWindow::resizeEvent(QResizeEvent *ev)
|
||||
void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
|
||||
{
|
||||
QMenu menu;
|
||||
QModelIndex index = indexAt(ev->pos());
|
||||
const QModelIndex index = indexAt(ev->pos());
|
||||
const bool indexIsValid = index.isValid();
|
||||
QAction *act0 = new QAction(tr("Delete breakpoint"), &menu);
|
||||
act0->setEnabled(index.isValid());
|
||||
act0->setEnabled(indexIsValid);
|
||||
QAction *act1 = new QAction(tr("Adjust column widths to contents"), &menu);
|
||||
QAction *act2 = new QAction(tr("Always adjust column widths to contents"), &menu);
|
||||
act2->setCheckable(true);
|
||||
act2->setChecked(m_alwaysResizeColumnsToContents);
|
||||
QAction *act3 = new QAction(tr("Edit condition..."), &menu);
|
||||
act0->setEnabled(index.isValid());
|
||||
QAction *act4 = new QAction(tr("Syncronize breakpoints"), &menu);
|
||||
act3->setEnabled(indexIsValid);
|
||||
QAction *act4 = new QAction(tr("Synchronize breakpoints"), &menu);
|
||||
|
||||
menu.addAction(act0);
|
||||
menu.addAction(act3);
|
||||
|
@@ -28,15 +28,20 @@
|
||||
**************************************************************************/
|
||||
|
||||
#include "cdbassembler.h"
|
||||
#include "registerhandler.h"
|
||||
#include "cdbdebugoutput.h"
|
||||
#include "cdbdebugengine_p.h"
|
||||
#include "cdbsymbolgroupcontext.h"
|
||||
|
||||
#include "disassemblerhandler.h"
|
||||
#include "registerhandler.h"
|
||||
|
||||
#include <QtCore/QVector>
|
||||
|
||||
namespace Debugger {
|
||||
namespace Internal {
|
||||
|
||||
typedef QList<DisassemblerLine> DisassemblerLineList;
|
||||
|
||||
bool getRegisters(IDebugControl4 *ctl,
|
||||
IDebugRegisters2 *ireg,
|
||||
QList<Register> *registers,
|
||||
@@ -79,5 +84,151 @@ bool getRegisters(IDebugControl4 *ctl,
|
||||
return true;
|
||||
}
|
||||
|
||||
// Output parser for disassembler lines.
|
||||
// It uses the source file lines as symbol until it encounters
|
||||
// a C++ symbol (function entered), from which then on
|
||||
// it uses that symbol.
|
||||
class DisassemblerOutputParser
|
||||
{
|
||||
public:
|
||||
explicit DisassemblerOutputParser(DisassemblerLineList *list);
|
||||
|
||||
void parse(const QStringList &l);
|
||||
|
||||
private:
|
||||
enum ParseResult { ParseOk, ParseIgnore, ParseFailed };
|
||||
ParseResult parseDisassembled(const QString &in, DisassemblerLine* l);
|
||||
|
||||
DisassemblerLineList *m_list;
|
||||
QString m_sourceSymbol;
|
||||
int m_sourceSymbolOffset;
|
||||
};
|
||||
|
||||
DisassemblerOutputParser::DisassemblerOutputParser(DisassemblerLineList *list) :
|
||||
m_list(list),
|
||||
m_sourceSymbolOffset(0)
|
||||
{
|
||||
}
|
||||
|
||||
// Parse a disassembler line:
|
||||
// module!class::foo:
|
||||
// 004017cf cc int 3
|
||||
// 77 mainwindow.cpp 004018ff 8d4da8 lea ecx,[ebp-0x58]
|
||||
DisassemblerOutputParser::ParseResult
|
||||
DisassemblerOutputParser::parseDisassembled(const QString &in, DisassemblerLine* l)
|
||||
{
|
||||
l->clear();
|
||||
|
||||
// Check if there is a source file
|
||||
if (in.size() < 7)
|
||||
return ParseIgnore;
|
||||
const bool hasSourceFile = !in.at(6).isSpace();
|
||||
|
||||
// Sometimes, empty lines occur
|
||||
const QString simplified = in.simplified();
|
||||
if (simplified.isEmpty())
|
||||
return ParseIgnore;
|
||||
|
||||
QStringList tokens = simplified.split(QLatin1Char(' '), QString::SkipEmptyParts);
|
||||
// Check for symbols as 'module!class::foo:' (start of function encountered)
|
||||
if (tokens.size() == 1) {
|
||||
QString symbol = tokens.front();
|
||||
if (symbol.endsWith(QLatin1Char(':')) && symbol.contains(QLatin1Char('!'))) {
|
||||
symbol.truncate(symbol.size() - 1);
|
||||
m_sourceSymbol = symbol;
|
||||
m_sourceSymbolOffset = 0;
|
||||
}
|
||||
return ParseIgnore;
|
||||
}
|
||||
if (tokens.size() < 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++;
|
||||
}
|
||||
// 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();
|
||||
}
|
||||
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(' ')));
|
||||
return ParseOk;
|
||||
}
|
||||
|
||||
void DisassemblerOutputParser::parse(const QStringList &l)
|
||||
{
|
||||
DisassemblerLine dLine;
|
||||
foreach(const QString &line, l) {
|
||||
switch (parseDisassembled(line, &dLine)) {
|
||||
case ParseOk:
|
||||
m_list->push_back(dLine);
|
||||
break;
|
||||
case ParseIgnore:
|
||||
break;
|
||||
case ParseFailed:
|
||||
qWarning("Failed to parse '%s'\n", qPrintable(line));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool dissassemble(IDebugClient5 *client,
|
||||
IDebugControl4 *ctl,
|
||||
ULONG64 offset,
|
||||
unsigned long beforeLines,
|
||||
unsigned long afterLines,
|
||||
QList<DisassemblerLine> *lines,
|
||||
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
|
||||
// conveniently provides the 'beforeLines' context (stepping back
|
||||
// in assembler code). We build a complete string first as line breaks
|
||||
// may occur in-between messages.
|
||||
StringOutputHandler stringHandler;
|
||||
IDebugOutputCallbacksWide *oldHandler = CdbDebugOutputBase::getOutputCallback(client);
|
||||
client->SetOutputCallbacksWide(&stringHandler);
|
||||
// For some reason, we need to output to "all clients"
|
||||
const HRESULT hr = ctl->OutputDisassemblyLines(DEBUG_OUTCTL_ALL_CLIENTS,
|
||||
beforeLines, beforeLines + afterLines,
|
||||
offset, flags, 0, 0, 0, 0);
|
||||
client->SetOutputCallbacksWide(oldHandler);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
*errorMessage= QString::fromLatin1("Unable to dissamble at 0x%1: %2").
|
||||
arg(QString::number(offset, 16), msgComFailed("OutputDisassemblyLines", hr));
|
||||
return false;
|
||||
}
|
||||
DisassemblerOutputParser parser(lines);
|
||||
parser.parse(stringHandler.result().split(QLatin1Char('\n')));
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -39,6 +39,8 @@
|
||||
namespace Debugger {
|
||||
namespace Internal {
|
||||
|
||||
class DisassemblerLine;
|
||||
|
||||
// Utilities related to assembler code.
|
||||
class Register;
|
||||
|
||||
@@ -47,6 +49,14 @@ bool getRegisters(IDebugControl4 *ctl,
|
||||
QList<Register> *registers,
|
||||
QString *errorMessage,
|
||||
int base = 10 /* 16 for hex, etc */);
|
||||
|
||||
bool dissassemble(IDebugClient5 *client,
|
||||
IDebugControl4 *ctl,
|
||||
ULONG64 offset,
|
||||
unsigned long beforeLines,
|
||||
unsigned long afterLines,
|
||||
QList<DisassemblerLine> *lines,
|
||||
QString *errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -42,6 +42,7 @@
|
||||
#include "watchhandler.h"
|
||||
#include "registerhandler.h"
|
||||
#include "moduleshandler.h"
|
||||
#include "disassemblerhandler.h"
|
||||
#include "watchutils.h"
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
@@ -56,6 +57,7 @@
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtGui/QMessageBox>
|
||||
#include <QtGui/QMainWindow>
|
||||
#include <QtGui/QApplication>
|
||||
|
||||
#define DBGHELP_TRANSLATE_TCHAR
|
||||
#include <inc/Dbghelp.h>
|
||||
@@ -195,7 +197,6 @@ CdbDebugEnginePrivate::CdbDebugEnginePrivate(DebuggerManager *parent, CdbDebugEn
|
||||
m_breakEventMode(BreakEventHandle),
|
||||
m_watchTimer(-1),
|
||||
m_debugEventCallBack(engine),
|
||||
m_debugOutputCallBack(engine),
|
||||
m_pDebugClient(0),
|
||||
m_pDebugControl(0),
|
||||
m_pDebugSystemObjects(0),
|
||||
@@ -225,7 +226,7 @@ bool CdbDebugEnginePrivate::init(QString *errorMessage)
|
||||
return false;
|
||||
}
|
||||
|
||||
m_pDebugClient->SetOutputCallbacks(&m_debugOutputCallBack);
|
||||
m_pDebugClient->SetOutputCallbacksWide(&m_debugOutputCallBack);
|
||||
m_pDebugClient->SetEventCallbacks(&m_debugEventCallBack);
|
||||
|
||||
hr = lib.debugCreate( __uuidof(IDebugControl4), reinterpret_cast<void**>(&m_pDebugControl));
|
||||
@@ -317,6 +318,10 @@ CdbDebugEngine::CdbDebugEngine(DebuggerManager *parent) :
|
||||
m_d->m_debuggerManager, SLOT(showDebuggerOutput(QString,QString)));
|
||||
connect(&m_d->m_debugOutputCallBack, SIGNAL(debuggerInputPrompt(QString,QString)),
|
||||
m_d->m_debuggerManager, SLOT(showDebuggerInput(QString,QString)));
|
||||
connect(&m_d->m_debugOutputCallBack, SIGNAL(debuggeeOutput(QString)),
|
||||
m_d->m_debuggerManager, SLOT(showApplicationOutput(QString)));
|
||||
connect(&m_d->m_debugOutputCallBack, SIGNAL(debuggeeInputPrompt(QString)),
|
||||
m_d->m_debuggerManager, SLOT(showApplicationOutput(QString)));
|
||||
}
|
||||
|
||||
CdbDebugEngine::~CdbDebugEngine()
|
||||
@@ -1041,6 +1046,30 @@ void CdbDebugEngine::saveSessionData()
|
||||
|
||||
void CdbDebugEngine::reloadDisassembler()
|
||||
{
|
||||
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;
|
||||
|
||||
DisassemblerHandler *dh = m_d->m_debuggerManagerAccess->disassemblerHandler();
|
||||
if (offset) {
|
||||
QList<DisassemblerLine> lines;
|
||||
QString errorMessage;
|
||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
const bool drc = dissassemble(m_d->m_pDebugClient, m_d->m_pDebugControl, offset,
|
||||
ContextLines, ContextLines, &lines, &errorMessage);
|
||||
QApplication::restoreOverrideCursor();
|
||||
if (drc) {
|
||||
dh->setLines(lines);
|
||||
if (lines.size() > ContextLines)
|
||||
dh->setCurrentLine(ContextLines);
|
||||
} else {
|
||||
qWarning("reloadDisassembler: %s\n", qPrintable(errorMessage));
|
||||
}
|
||||
} else {
|
||||
dh->setLines(QList<DisassemblerLine>());
|
||||
}
|
||||
}
|
||||
|
||||
void CdbDebugEngine::reloadModules()
|
||||
|
@@ -27,7 +27,6 @@
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
#include "cdbdebugoutput.h"
|
||||
#include "cdbdebugengine.h"
|
||||
#include "cdbdebugengine_p.h"
|
||||
@@ -38,12 +37,11 @@
|
||||
namespace Debugger {
|
||||
namespace Internal {
|
||||
|
||||
CdbDebugOutput::CdbDebugOutput(CdbDebugEngine* engine) :
|
||||
m_pEngine(engine)
|
||||
CdbDebugOutputBase::CdbDebugOutputBase()
|
||||
{
|
||||
}
|
||||
|
||||
STDMETHODIMP CdbDebugOutput::QueryInterface(
|
||||
STDMETHODIMP CdbDebugOutputBase::QueryInterface(
|
||||
THIS_
|
||||
IN REFIID InterfaceId,
|
||||
OUT PVOID* Interface
|
||||
@@ -52,9 +50,9 @@ STDMETHODIMP CdbDebugOutput::QueryInterface(
|
||||
*Interface = NULL;
|
||||
|
||||
if (IsEqualIID(InterfaceId, __uuidof(IUnknown)) ||
|
||||
IsEqualIID(InterfaceId, __uuidof(IDebugOutputCallbacks)))
|
||||
IsEqualIID(InterfaceId, __uuidof(IDebugOutputCallbacksWide)))
|
||||
{
|
||||
*Interface = (IDebugOutputCallbacks *)this;
|
||||
*Interface = (IDebugOutputCallbacksWide*)this;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
} else {
|
||||
@@ -62,27 +60,43 @@ STDMETHODIMP CdbDebugOutput::QueryInterface(
|
||||
}
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG) CdbDebugOutput::AddRef(THIS)
|
||||
STDMETHODIMP_(ULONG) CdbDebugOutputBase::AddRef(THIS)
|
||||
{
|
||||
// This class is designed to be static so
|
||||
// there's no true refcount.
|
||||
return 1;
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG) CdbDebugOutput::Release(THIS)
|
||||
STDMETHODIMP_(ULONG) CdbDebugOutputBase::Release(THIS)
|
||||
{
|
||||
// This class is designed to be static so
|
||||
// there's no true refcount.
|
||||
return 0;
|
||||
}
|
||||
|
||||
STDMETHODIMP CdbDebugOutputBase::Output(
|
||||
THIS_
|
||||
IN ULONG mask,
|
||||
IN PCWSTR text
|
||||
)
|
||||
{
|
||||
output(mask, QString::fromUtf16(text));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IDebugOutputCallbacksWide *CdbDebugOutputBase::getOutputCallback(IDebugClient5 *client)
|
||||
{
|
||||
IDebugOutputCallbacksWide *rc;
|
||||
if (FAILED(client->GetOutputCallbacksWide(&rc)))
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
// ------------------------- CdbDebugOutput
|
||||
|
||||
// Return a prefix for debugger messages
|
||||
static QString prefix(ULONG mask)
|
||||
{
|
||||
if (mask & (DEBUG_OUTPUT_DEBUGGEE|DEBUG_OUTPUT_DEBUGGEE_PROMPT|DEBUG_OUTPUT_DEBUGGEE_PROMPT)) {
|
||||
static const QString p = QLatin1String("target:");
|
||||
return p;
|
||||
}
|
||||
if (mask & (DEBUG_OUTPUT_PROMPT_REGISTERS)) {
|
||||
static const QString p = QLatin1String("registers:");
|
||||
return p;
|
||||
@@ -103,23 +117,42 @@ static QString prefix(ULONG mask)
|
||||
return commonPrefix;
|
||||
}
|
||||
|
||||
STDMETHODIMP CdbDebugOutput::Output(
|
||||
THIS_
|
||||
IN ULONG mask,
|
||||
IN PCSTR text
|
||||
)
|
||||
{
|
||||
const QString msg = QString::fromLocal8Bit(text);
|
||||
enum OutputKind { DebuggerOutput, DebuggerPromptOutput, DebuggeeOutput, DebuggeePromptOutput };
|
||||
|
||||
static inline OutputKind outputKind(ULONG mask)
|
||||
{
|
||||
if (mask & DEBUG_OUTPUT_DEBUGGEE)
|
||||
return DebuggeeOutput;
|
||||
if (mask & DEBUG_OUTPUT_DEBUGGEE_PROMPT)
|
||||
return DebuggeePromptOutput;
|
||||
if (mask & DEBUG_OUTPUT_PROMPT)
|
||||
return DebuggerPromptOutput;
|
||||
return DebuggerOutput;
|
||||
}
|
||||
|
||||
CdbDebugOutput::CdbDebugOutput()
|
||||
{
|
||||
}
|
||||
|
||||
void CdbDebugOutput::output(ULONG mask, const QString &msg)
|
||||
{
|
||||
if (debugCDB > 1)
|
||||
qDebug() << Q_FUNC_INFO << "\n " << msg;
|
||||
|
||||
if (mask & (DEBUG_OUTPUT_PROMPT|DEBUG_OUTPUT_DEBUGGEE_PROMPT)) {
|
||||
switch (outputKind(mask)) {
|
||||
case DebuggerOutput:
|
||||
debuggerOutput(prefix(mask), msg);
|
||||
break;
|
||||
case DebuggerPromptOutput:
|
||||
emit debuggerInputPrompt(prefix(mask), msg);
|
||||
} else {
|
||||
emit debuggerOutput(prefix(mask), msg);
|
||||
break;
|
||||
case DebuggeeOutput:
|
||||
emit debuggeeOutput(msg);
|
||||
break;
|
||||
case DebuggeePromptOutput:
|
||||
emit debuggeeInputPrompt(msg);
|
||||
break;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
|
@@ -38,14 +38,12 @@
|
||||
namespace Debugger {
|
||||
namespace Internal {
|
||||
|
||||
class CdbDebugEngine;
|
||||
// CdbDebugOutputBase is a base class for output handlers
|
||||
// that takes care of the Active X magic and conversion to QString.
|
||||
|
||||
class CdbDebugOutput : public QObject, public IDebugOutputCallbacks
|
||||
class CdbDebugOutputBase : public IDebugOutputCallbacksWide
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CdbDebugOutput(CdbDebugEngine* engine);
|
||||
|
||||
// IUnknown.
|
||||
STDMETHOD(QueryInterface)(
|
||||
THIS_
|
||||
@@ -63,15 +61,48 @@ public:
|
||||
STDMETHOD(Output)(
|
||||
THIS_
|
||||
IN ULONG mask,
|
||||
IN PCSTR text
|
||||
IN PCWSTR text
|
||||
);
|
||||
|
||||
// Helpers to retrieve the output callbacks IF
|
||||
static IDebugOutputCallbacksWide *getOutputCallback(IDebugClient5 *client);
|
||||
|
||||
protected:
|
||||
CdbDebugOutputBase();
|
||||
virtual void output(ULONG mask, const QString &message) = 0;
|
||||
};
|
||||
|
||||
// Standard CDB output handler
|
||||
class CdbDebugOutput : public QObject, public CdbDebugOutputBase
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CdbDebugOutput();
|
||||
|
||||
protected:
|
||||
virtual void output(ULONG mask, const QString &message);
|
||||
|
||||
signals:
|
||||
void debuggerOutput(const QString &prefix, const QString &message);
|
||||
void debuggerInputPrompt(const QString &prefix, const QString &message);
|
||||
void debuggeeOutput(const QString &message);
|
||||
void debuggeeInputPrompt(const QString &message);
|
||||
};
|
||||
|
||||
// An output handler that adds lines to a string (to be
|
||||
// used for cases in which linebreaks occur in-between calls
|
||||
// to output).
|
||||
class StringOutputHandler : public CdbDebugOutputBase
|
||||
{
|
||||
public:
|
||||
StringOutputHandler() {}
|
||||
QString result() const { return m_result; }
|
||||
|
||||
protected:
|
||||
virtual void output(ULONG, const QString &message) { m_result += message; }
|
||||
|
||||
private:
|
||||
CdbDebugEngine* m_pEngine;
|
||||
QString m_result;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
@@ -40,7 +40,8 @@ namespace Internal {
|
||||
CdbStackTraceContext::CdbStackTraceContext(IDebugSystemObjects4* pDebugSystemObjects,
|
||||
IDebugSymbols3* pDebugSymbols) :
|
||||
m_pDebugSystemObjects(pDebugSystemObjects),
|
||||
m_pDebugSymbols(pDebugSymbols)
|
||||
m_pDebugSymbols(pDebugSymbols),
|
||||
m_instructionOffset(0)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -95,6 +96,8 @@ bool CdbStackTraceContext::init(unsigned long frameCount, QString * /*errorMessa
|
||||
for (ULONG i=0; i < frameCount; ++i) {
|
||||
StackFrame frame(i);
|
||||
const ULONG64 instructionOffset = m_cdbFrames[i].InstructionOffset;
|
||||
if (i == 0)
|
||||
m_instructionOffset = instructionOffset;
|
||||
frame.address = QString::fromLatin1("0x%1").arg(instructionOffset, 0, 16);
|
||||
|
||||
m_pDebugSymbols->GetNameByOffsetWide(instructionOffset, wszBuf, MAX_PATH, 0, 0);
|
||||
|
@@ -66,6 +66,9 @@ public:
|
||||
QList<StackFrame> frames() const { return m_frames; }
|
||||
inline int frameCount() const { return m_frames.size(); }
|
||||
|
||||
// Top-Level instruction offset for disassembler
|
||||
ULONG64 instructionOffset() const { return m_instructionOffset; }
|
||||
|
||||
CdbSymbolGroupContext *symbolGroupContextAt(int index, QString *errorMessage);
|
||||
|
||||
private:
|
||||
@@ -78,6 +81,7 @@ private:
|
||||
DEBUG_STACK_FRAME m_cdbFrames[maxFrames];
|
||||
QVector <CdbSymbolGroupContext*> m_symbolContexts;
|
||||
QList<StackFrame> m_frames;
|
||||
ULONG64 m_instructionOffset;
|
||||
};
|
||||
|
||||
}
|
||||
|
@@ -213,6 +213,8 @@ void DebuggerManager::init()
|
||||
QAbstractItemView *disassemblerView =
|
||||
qobject_cast<QAbstractItemView *>(m_disassemblerWindow);
|
||||
disassemblerView->setModel(m_disassemblerHandler->model());
|
||||
connect(m_disassemblerWindow, SIGNAL(reloadDisassemblerRequested()),
|
||||
this, SLOT(reloadDisassembler()));
|
||||
|
||||
// Breakpoints
|
||||
m_breakHandler = new BreakHandler;
|
||||
|
@@ -39,6 +39,14 @@
|
||||
using namespace Debugger;
|
||||
using namespace Debugger::Internal;
|
||||
|
||||
void DisassemblerLine::clear()
|
||||
{
|
||||
address.clear();
|
||||
symbol.clear();
|
||||
addressDisplay.clear();
|
||||
symbolDisplay.clear();
|
||||
mnemonic.clear();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
@@ -41,6 +41,8 @@ namespace Internal {
|
||||
class DisassemblerLine
|
||||
{
|
||||
public:
|
||||
void clear();
|
||||
|
||||
QString address;
|
||||
QString symbol;
|
||||
QString addressDisplay;
|
||||
|
Reference in New Issue
Block a user