CDB: Make disassembly work.

This commit is contained in:
Friedemann Kleint
2009-08-18 09:59:15 +02:00
parent 1e7cee620b
commit 5b6ab144c6
4 changed files with 65 additions and 19 deletions

View File

@@ -36,6 +36,23 @@
#include <QtCore/QVector> #include <QtCore/QVector>
// Format a hex address with a given field width if possible. Convert
// to number to ensure it is not truncated should it be larger than the
// field width.
static inline void formatAddress(QTextStream &str, const QString &hexAddressS, int fieldWidth)
{
const QChar oldPadChar = str.padChar();
const int oldFieldWidth = str.fieldWidth();
const int oldIntegerBase = str.integerBase();
str.setFieldWidth(fieldWidth);
str.setPadChar(QLatin1Char('0'));
str.setIntegerBase(16);
str << hexAddressS.toULongLong(0, 16);
str.setFieldWidth(oldFieldWidth);
str.setPadChar(oldPadChar);
str.setIntegerBase(oldIntegerBase);
}
namespace Debugger { namespace Debugger {
namespace Internal { namespace Internal {
@@ -89,7 +106,7 @@ class DisassemblerOutputParser
{ {
Q_DISABLE_COPY(DisassemblerOutputParser) Q_DISABLE_COPY(DisassemblerOutputParser)
public: public:
explicit DisassemblerOutputParser(QTextStream &str, int addressFieldWith = 0); explicit DisassemblerOutputParser(QTextStream &str, int addressFieldWidth = 0);
void parse(const QStringList &l); void parse(const QStringList &l);
@@ -97,14 +114,14 @@ private:
enum ParseResult { ParseOk, ParseIgnore, ParseFailed }; enum ParseResult { ParseOk, ParseIgnore, ParseFailed };
ParseResult parseDisassembled(const QString &in); ParseResult parseDisassembled(const QString &in);
const int m_addressFieldWith; const int m_addressFieldWidth;
QTextStream &m_str; QTextStream &m_str;
QString m_sourceSymbol; QString m_sourceSymbol;
int m_sourceSymbolOffset; int m_sourceSymbolOffset;
}; };
DisassemblerOutputParser::DisassemblerOutputParser(QTextStream &str, int addressFieldWith) : DisassemblerOutputParser::DisassemblerOutputParser(QTextStream &str, int addressFieldWidth) :
m_addressFieldWith(addressFieldWith), m_addressFieldWidth(addressFieldWidth),
m_str(str), m_str(str),
m_sourceSymbolOffset(0) m_sourceSymbolOffset(0)
{ {
@@ -151,16 +168,10 @@ DisassemblerOutputParser::ParseResult
// which is important for setting the marker. // which is important for setting the marker.
const int addressToken = hasSourceFile ? 2 : 0; const int addressToken = hasSourceFile ? 2 : 0;
m_str << "0x"; m_str << "0x";
if (m_str.fieldWidth() == m_addressFieldWith) { if (m_str.fieldWidth() == m_addressFieldWidth) {
m_str << tokens.at(addressToken); m_str << tokens.at(addressToken);
} else { } else {
const QChar oldPadChar = m_str.padChar(); formatAddress(m_str, tokens.at(addressToken), m_addressFieldWidth);
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);
} }
m_str << ' '; m_str << ' ';
// Symbol display: Do we know a symbol? -> Display with offset. // Symbol display: Do we know a symbol? -> Display with offset.
@@ -200,7 +211,7 @@ bool dissassemble(CIDebugClient *client,
ULONG64 offset, ULONG64 offset,
unsigned long beforeLines, unsigned long beforeLines,
unsigned long afterLines, unsigned long afterLines,
int addressFieldWith, int addressFieldWidth,
QTextStream &str, QTextStream &str,
QString *errorMessage) QString *errorMessage)
{ {
@@ -224,7 +235,7 @@ bool dissassemble(CIDebugClient *client,
arg(offset, 0, 16).arg(msgComFailed("OutputDisassemblyLines", hr)); arg(offset, 0, 16).arg(msgComFailed("OutputDisassemblyLines", hr));
return false; return false;
} }
DisassemblerOutputParser parser(str, addressFieldWith); DisassemblerOutputParser parser(str, addressFieldWidth);
parser.parse(stringHandler.result().split(QLatin1Char('\n'))); parser.parse(stringHandler.result().split(QLatin1Char('\n')));
return true; return true;
} }

View File

@@ -56,7 +56,7 @@ bool dissassemble(CIDebugClient *client,
ULONG64 offset, ULONG64 offset,
unsigned long beforeLines, unsigned long beforeLines,
unsigned long afterLines, unsigned long afterLines,
int addressFieldWith /* = 0*/, int addressFieldWidth /* = 0*/,
QTextStream &str, QTextStream &str,
QString *errorMessage); QString *errorMessage);

View File

@@ -330,7 +330,7 @@ bool CdbDebugEnginePrivate::init(QString *errorMessage)
return false; return false;
} }
m_cif.debugControl->SetCodeLevel(DEBUG_LEVEL_SOURCE); setCodeLevel();
hr = lib.debugCreate( __uuidof(IDebugSystemObjects4), reinterpret_cast<void**>(&m_cif.debugSystemObjects)); hr = lib.debugCreate( __uuidof(IDebugSystemObjects4), reinterpret_cast<void**>(&m_cif.debugSystemObjects));
if (FAILED(hr)) { if (FAILED(hr)) {
@@ -382,6 +382,34 @@ IDebuggerEngine *CdbDebugEngine::create(DebuggerManager *parent,
return 0; return 0;
} }
// Adapt code level setting to the setting of the action.
static inline const char *codeLevelName(ULONG level)
{
return level == DEBUG_LEVEL_ASSEMBLY ? "assembly" : "source";
}
bool CdbDebugEnginePrivate::setCodeLevel()
{
const ULONG codeLevel = theDebuggerBoolSetting(StepByInstruction) ?
DEBUG_LEVEL_ASSEMBLY : DEBUG_LEVEL_SOURCE;
ULONG currentCodeLevel = DEBUG_LEVEL_ASSEMBLY;
HRESULT hr = m_cif.debugControl->GetCodeLevel(&currentCodeLevel);
if (FAILED(hr)) {
m_engine->warning(QString::fromLatin1("Cannot determine code level: %1").arg(msgComFailed("GetCodeLevel", hr)));
return true;
}
if (debugCDB)
qDebug() << Q_FUNC_INFO << "\nSetting code level to " << codeLevelName(codeLevel) << " (was" << codeLevelName(currentCodeLevel) << ')';
if (currentCodeLevel == currentCodeLevel)
return false;
hr = m_cif.debugControl->SetCodeLevel(codeLevel);
if (FAILED(hr)) {
m_engine->warning(QString::fromLatin1("Cannot set code level: %1").arg(msgComFailed("SetCodeLevel", hr)));
return false;
}
return true;
}
CdbDebugEnginePrivate::~CdbDebugEnginePrivate() CdbDebugEnginePrivate::~CdbDebugEnginePrivate()
{ {
cleanStackTrace(); cleanStackTrace();
@@ -565,6 +593,7 @@ bool CdbDebugEngine::startDebugger(const QSharedPointer<DebuggerStartParameters>
bool rc = false; bool rc = false;
bool needWatchTimer = false; bool needWatchTimer = false;
m_d->clearForRun(); m_d->clearForRun();
m_d->setCodeLevel();
switch (mode) { switch (mode) {
case AttachExternal: case AttachExternal:
case AttachCrashedExternal: case AttachCrashedExternal:
@@ -863,6 +892,7 @@ void CdbDebugEngine::stepExec()
qDebug() << Q_FUNC_INFO; qDebug() << Q_FUNC_INFO;
m_d->clearForRun(); m_d->clearForRun();
m_d->setCodeLevel();
const HRESULT hr = m_d->m_cif.debugControl->SetExecutionStatus(DEBUG_STATUS_STEP_INTO); const HRESULT hr = m_d->m_cif.debugControl->SetExecutionStatus(DEBUG_STATUS_STEP_INTO);
if (FAILED(hr)) if (FAILED(hr))
warning(msgFunctionFailed(Q_FUNC_INFO, msgComFailed("SetExecutionStatus", hr))); warning(msgFunctionFailed(Q_FUNC_INFO, msgComFailed("SetExecutionStatus", hr)));
@@ -919,6 +949,7 @@ void CdbDebugEngine::nextExec()
qDebug() << Q_FUNC_INFO; qDebug() << Q_FUNC_INFO;
m_d->clearForRun(); m_d->clearForRun();
m_d->setCodeLevel();
const HRESULT hr = m_d->m_cif.debugControl->SetExecutionStatus(DEBUG_STATUS_STEP_OVER); const HRESULT hr = m_d->m_cif.debugControl->SetExecutionStatus(DEBUG_STATUS_STEP_OVER);
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
startWatchTimer(); startWatchTimer();
@@ -938,6 +969,7 @@ void CdbDebugEngine::nextIExec()
qDebug() << Q_FUNC_INFO; qDebug() << Q_FUNC_INFO;
m_d->clearForRun(); m_d->clearForRun();
m_d->setCodeLevel();
const HRESULT hr = m_d->m_cif.debugControl->Execute(DEBUG_OUTCTL_THIS_CLIENT, "p", 0); const HRESULT hr = m_d->m_cif.debugControl->Execute(DEBUG_OUTCTL_THIS_CLIENT, "p", 0);
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
startWatchTimer(); startWatchTimer();
@@ -948,7 +980,7 @@ void CdbDebugEngine::nextIExec()
void CdbDebugEngine::continueInferior() void CdbDebugEngine::continueInferior()
{ {
QString errorMessage; QString errorMessage;
if (!m_d->continueInferior(&errorMessage)) if (!m_d->continueInferior(&errorMessage))
warning(msgFunctionFailed(Q_FUNC_INFO, errorMessage)); warning(msgFunctionFailed(Q_FUNC_INFO, errorMessage));
} }
@@ -987,6 +1019,7 @@ bool CdbDebugEnginePrivate::continueInferior(QString *errorMessage)
} }
clearForRun(); clearForRun();
setCodeLevel();
m_engine->killWatchTimer(); m_engine->killWatchTimer();
m_debuggerManager->resetLocation(); m_debuggerManager->resetLocation();
m_debuggerManagerAccess->notifyInferiorRunningRequested(); m_debuggerManagerAccess->notifyInferiorRunningRequested();
@@ -1289,8 +1322,8 @@ void CdbDebugEngine::fetchDisassembler(DisassemblerViewAgent *agent,
} }
QString disassembly; QString disassembly;
QApplication::setOverrideCursor(Qt::WaitCursor); QApplication::setOverrideCursor(Qt::WaitCursor);
ok = dissassemble(m_d->m_cif.debugClient, m_d->m_cif.debugControl, offset, addressFieldWith, ok = dissassemble(m_d->m_cif.debugClient, m_d->m_cif.debugControl, offset,
ContextLines, ContextLines, QTextStream(&disassembly), &errorMessage); ContextLines, ContextLines, addressFieldWith, QTextStream(&disassembly), &errorMessage);
QApplication::restoreOverrideCursor(); QApplication::restoreOverrideCursor();
if (!ok) if (!ok)
break; break;

View File

@@ -146,6 +146,8 @@ struct CdbDebugEnginePrivate
QStringList symbolPaths() const; QStringList symbolPaths() const;
bool setSymbolPaths(const QStringList &s, QString *errorMessage); bool setSymbolPaths(const QStringList &s, QString *errorMessage);
bool setCodeLevel();
const QSharedPointer<CdbOptions> m_options; const QSharedPointer<CdbOptions> m_options;
HANDLE m_hDebuggeeProcess; HANDLE m_hDebuggeeProcess;
HANDLE m_hDebuggeeThread; HANDLE m_hDebuggeeThread;