Commit 5b6ab144 authored by Friedemann Kleint's avatar Friedemann Kleint
Browse files

CDB: Make disassembly work.

parent 1e7cee62
......@@ -36,6 +36,23 @@
#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 Internal {
......@@ -89,7 +106,7 @@ class DisassemblerOutputParser
{
Q_DISABLE_COPY(DisassemblerOutputParser)
public:
explicit DisassemblerOutputParser(QTextStream &str, int addressFieldWith = 0);
explicit DisassemblerOutputParser(QTextStream &str, int addressFieldWidth = 0);
void parse(const QStringList &l);
......@@ -97,14 +114,14 @@ private:
enum ParseResult { ParseOk, ParseIgnore, ParseFailed };
ParseResult parseDisassembled(const QString &in);
const int m_addressFieldWith;
const int m_addressFieldWidth;
QTextStream &m_str;
QString m_sourceSymbol;
int m_sourceSymbolOffset;
};
DisassemblerOutputParser::DisassemblerOutputParser(QTextStream &str, int addressFieldWith) :
m_addressFieldWith(addressFieldWith),
DisassemblerOutputParser::DisassemblerOutputParser(QTextStream &str, int addressFieldWidth) :
m_addressFieldWidth(addressFieldWidth),
m_str(str),
m_sourceSymbolOffset(0)
{
......@@ -151,16 +168,10 @@ DisassemblerOutputParser::ParseResult
// which is important for setting the marker.
const int addressToken = hasSourceFile ? 2 : 0;
m_str << "0x";
if (m_str.fieldWidth() == m_addressFieldWith) {
if (m_str.fieldWidth() == m_addressFieldWidth) {
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);
formatAddress(m_str, tokens.at(addressToken), m_addressFieldWidth);
}
m_str << ' ';
// Symbol display: Do we know a symbol? -> Display with offset.
......@@ -200,7 +211,7 @@ bool dissassemble(CIDebugClient *client,
ULONG64 offset,
unsigned long beforeLines,
unsigned long afterLines,
int addressFieldWith,
int addressFieldWidth,
QTextStream &str,
QString *errorMessage)
{
......@@ -224,7 +235,7 @@ bool dissassemble(CIDebugClient *client,
arg(offset, 0, 16).arg(msgComFailed("OutputDisassemblyLines", hr));
return false;
}
DisassemblerOutputParser parser(str, addressFieldWith);
DisassemblerOutputParser parser(str, addressFieldWidth);
parser.parse(stringHandler.result().split(QLatin1Char('\n')));
return true;
}
......
......@@ -56,7 +56,7 @@ bool dissassemble(CIDebugClient *client,
ULONG64 offset,
unsigned long beforeLines,
unsigned long afterLines,
int addressFieldWith /* = 0*/,
int addressFieldWidth /* = 0*/,
QTextStream &str,
QString *errorMessage);
......
......@@ -330,7 +330,7 @@ bool CdbDebugEnginePrivate::init(QString *errorMessage)
return false;
}
m_cif.debugControl->SetCodeLevel(DEBUG_LEVEL_SOURCE);
setCodeLevel();
hr = lib.debugCreate( __uuidof(IDebugSystemObjects4), reinterpret_cast<void**>(&m_cif.debugSystemObjects));
if (FAILED(hr)) {
......@@ -382,6 +382,34 @@ IDebuggerEngine *CdbDebugEngine::create(DebuggerManager *parent,
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()
{
cleanStackTrace();
......@@ -565,6 +593,7 @@ bool CdbDebugEngine::startDebugger(const QSharedPointer<DebuggerStartParameters>
bool rc = false;
bool needWatchTimer = false;
m_d->clearForRun();
m_d->setCodeLevel();
switch (mode) {
case AttachExternal:
case AttachCrashedExternal:
......@@ -863,6 +892,7 @@ void CdbDebugEngine::stepExec()
qDebug() << Q_FUNC_INFO;
m_d->clearForRun();
m_d->setCodeLevel();
const HRESULT hr = m_d->m_cif.debugControl->SetExecutionStatus(DEBUG_STATUS_STEP_INTO);
if (FAILED(hr))
warning(msgFunctionFailed(Q_FUNC_INFO, msgComFailed("SetExecutionStatus", hr)));
......@@ -919,6 +949,7 @@ void CdbDebugEngine::nextExec()
qDebug() << Q_FUNC_INFO;
m_d->clearForRun();
m_d->setCodeLevel();
const HRESULT hr = m_d->m_cif.debugControl->SetExecutionStatus(DEBUG_STATUS_STEP_OVER);
if (SUCCEEDED(hr)) {
startWatchTimer();
......@@ -938,6 +969,7 @@ void CdbDebugEngine::nextIExec()
qDebug() << Q_FUNC_INFO;
m_d->clearForRun();
m_d->setCodeLevel();
const HRESULT hr = m_d->m_cif.debugControl->Execute(DEBUG_OUTCTL_THIS_CLIENT, "p", 0);
if (SUCCEEDED(hr)) {
startWatchTimer();
......@@ -948,7 +980,7 @@ void CdbDebugEngine::nextIExec()
void CdbDebugEngine::continueInferior()
{
QString errorMessage;
QString errorMessage;
if (!m_d->continueInferior(&errorMessage))
warning(msgFunctionFailed(Q_FUNC_INFO, errorMessage));
}
......@@ -987,6 +1019,7 @@ bool CdbDebugEnginePrivate::continueInferior(QString *errorMessage)
}
clearForRun();
setCodeLevel();
m_engine->killWatchTimer();
m_debuggerManager->resetLocation();
m_debuggerManagerAccess->notifyInferiorRunningRequested();
......@@ -1289,8 +1322,8 @@ void CdbDebugEngine::fetchDisassembler(DisassemblerViewAgent *agent,
}
QString disassembly;
QApplication::setOverrideCursor(Qt::WaitCursor);
ok = dissassemble(m_d->m_cif.debugClient, m_d->m_cif.debugControl, offset, addressFieldWith,
ContextLines, ContextLines, QTextStream(&disassembly), &errorMessage);
ok = dissassemble(m_d->m_cif.debugClient, m_d->m_cif.debugControl, offset,
ContextLines, ContextLines, addressFieldWith, QTextStream(&disassembly), &errorMessage);
QApplication::restoreOverrideCursor();
if (!ok)
break;
......
......@@ -146,6 +146,8 @@ struct CdbDebugEnginePrivate
QStringList symbolPaths() const;
bool setSymbolPaths(const QStringList &s, QString *errorMessage);
bool setCodeLevel();
const QSharedPointer<CdbOptions> m_options;
HANDLE m_hDebuggeeProcess;
HANDLE m_hDebuggeeThread;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment