forked from qt-creator/qt-creator
Cdb: Replace CdbResponse with DebuggerResponse.
Change-Id: I2fddd5904de665bc7e6731ee4be69639d82258a0 Reviewed-by: Niels Weber <niels.weber@theqtcompany.com>
This commit is contained in:
@@ -85,7 +85,7 @@ enum { debugSourceMapping = 0 };
|
|||||||
enum { debugWatches = 0 };
|
enum { debugWatches = 0 };
|
||||||
enum { debugBreakpoints = 0 };
|
enum { debugBreakpoints = 0 };
|
||||||
|
|
||||||
#define CB(callback) [this](const CdbResponse &r) { callback(r); }
|
#define CB(callback) [this](const DebuggerResponse &r) { callback(r); }
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
# define STATE_DEBUG(state, func, line, notifyFunc) qDebug("%s in %s at %s:%d", notifyFunc, stateName(state), func, line);
|
# define STATE_DEBUG(state, func, line, notifyFunc) qDebug("%s in %s at %s:%d", notifyFunc, stateName(state), func, line);
|
||||||
@@ -255,6 +255,7 @@ CdbEngine::CdbEngine(const DebuggerRunParameters &sp) :
|
|||||||
m_accessible(false),
|
m_accessible(false),
|
||||||
m_specialStopMode(NoSpecialStop),
|
m_specialStopMode(NoSpecialStop),
|
||||||
m_nextCommandToken(0),
|
m_nextCommandToken(0),
|
||||||
|
m_currentBuiltinResponseToken(-1),
|
||||||
m_extensionCommandPrefixBA("!" QT_CREATOR_CDB_EXT "."),
|
m_extensionCommandPrefixBA("!" QT_CREATOR_CDB_EXT "."),
|
||||||
m_operateByInstructionPending(true),
|
m_operateByInstructionPending(true),
|
||||||
m_operateByInstruction(true), // Default CDB setting
|
m_operateByInstruction(true), // Default CDB setting
|
||||||
@@ -293,6 +294,7 @@ void CdbEngine::init()
|
|||||||
m_accessible = false;
|
m_accessible = false;
|
||||||
m_specialStopMode = NoSpecialStop;
|
m_specialStopMode = NoSpecialStop;
|
||||||
m_nextCommandToken = 0;
|
m_nextCommandToken = 0;
|
||||||
|
m_currentBuiltinResponseToken = -1;
|
||||||
m_operateByInstructionPending = action(OperateByInstruction)->isChecked();
|
m_operateByInstructionPending = action(OperateByInstruction)->isChecked();
|
||||||
m_verboseLogPending = boolSetting(VerboseLog);
|
m_verboseLogPending = boolSetting(VerboseLog);
|
||||||
m_operateByInstruction = true; // Default CDB setting
|
m_operateByInstruction = true; // Default CDB setting
|
||||||
@@ -306,6 +308,7 @@ void CdbEngine::init()
|
|||||||
|
|
||||||
m_outputBuffer.clear();
|
m_outputBuffer.clear();
|
||||||
m_builtinCommandQueue.clear();
|
m_builtinCommandQueue.clear();
|
||||||
|
m_currentBuiltinResponse.clear();
|
||||||
m_extensionCommandQueue.clear();
|
m_extensionCommandQueue.clear();
|
||||||
m_extensionMessageBuffer.clear();
|
m_extensionMessageBuffer.clear();
|
||||||
m_pendingBreakpointMap.clear();
|
m_pendingBreakpointMap.clear();
|
||||||
@@ -495,9 +498,9 @@ void CdbEngine::createFullBacktrace()
|
|||||||
postBuiltinCommand("~*kp", CB(handleCreateFullBackTrace));
|
postBuiltinCommand("~*kp", CB(handleCreateFullBackTrace));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::handleCreateFullBackTrace(const CdbResponse &response)
|
void CdbEngine::handleCreateFullBackTrace(const DebuggerResponse &response)
|
||||||
{
|
{
|
||||||
Internal::openTextEditor(QLatin1String("Backtrace $"), QLatin1String(response.reply));
|
Internal::openTextEditor(QLatin1String("Backtrace $"), response.data.toLatin1());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::setupEngine()
|
void CdbEngine::setupEngine()
|
||||||
@@ -688,7 +691,7 @@ void CdbEngine::setupInferior()
|
|||||||
const BreakpointParameters bp(BreakpointAtMain);
|
const BreakpointParameters bp(BreakpointAtMain);
|
||||||
BreakpointModelId id(quint16(-1));
|
BreakpointModelId id(quint16(-1));
|
||||||
postBuiltinCommand(cdbAddBreakpointCommand(bp, m_sourcePathMappings, id, true),
|
postBuiltinCommand(cdbAddBreakpointCommand(bp, m_sourcePathMappings, id, true),
|
||||||
[this, id](const CdbResponse &r){ handleBreakInsert(r, id); });
|
[this, id](const DebuggerResponse &r) { handleBreakInsert(r, id); });
|
||||||
}
|
}
|
||||||
postCommand("sxn 0x4000001f"); // Do not break on WowX86 exceptions.
|
postCommand("sxn 0x4000001f"); // Do not break on WowX86 exceptions.
|
||||||
postCommand("sxn ibp"); // Do not break on initial breakpoints.
|
postCommand("sxn ibp"); // Do not break on initial breakpoints.
|
||||||
@@ -748,25 +751,25 @@ void CdbEngine::runEngine()
|
|||||||
const QByteArray debugModule = module + 'D';
|
const QByteArray debugModule = module + 'D';
|
||||||
const QByteArray wideFunc = QByteArray(CdbOptionsPage::crtDbgReport).append('W');
|
const QByteArray wideFunc = QByteArray(CdbOptionsPage::crtDbgReport).append('W');
|
||||||
postBuiltinCommand(breakAtFunctionCommand(CdbOptionsPage::crtDbgReport, module),
|
postBuiltinCommand(breakAtFunctionCommand(CdbOptionsPage::crtDbgReport, module),
|
||||||
[this](const CdbResponse &r){ handleBreakInsert(r, BreakpointModelId()); });
|
[this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); });
|
||||||
postBuiltinCommand(breakAtFunctionCommand(wideFunc, module),
|
postBuiltinCommand(breakAtFunctionCommand(wideFunc, module),
|
||||||
[this](const CdbResponse &r){ handleBreakInsert(r, BreakpointModelId()); });
|
[this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); });
|
||||||
postBuiltinCommand(breakAtFunctionCommand(CdbOptionsPage::crtDbgReport, debugModule),
|
postBuiltinCommand(breakAtFunctionCommand(CdbOptionsPage::crtDbgReport, debugModule),
|
||||||
[this](const CdbResponse &r){ handleBreakInsert(r, BreakpointModelId()); });
|
[this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); });
|
||||||
postBuiltinCommand(breakAtFunctionCommand(wideFunc, debugModule),
|
postBuiltinCommand(breakAtFunctionCommand(wideFunc, debugModule),
|
||||||
[this](const CdbResponse &r){ handleBreakInsert(r, BreakpointModelId()); });
|
[this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); });
|
||||||
}
|
}
|
||||||
if (boolSetting(BreakOnWarning)) {
|
if (boolSetting(BreakOnWarning)) {
|
||||||
postBuiltinCommand("bm /( QtCored4!qWarning", // 'bm': All overloads.
|
postBuiltinCommand("bm /( QtCored4!qWarning", // 'bm': All overloads.
|
||||||
[this](const CdbResponse &r){ handleBreakInsert(r, BreakpointModelId()); });
|
[this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); });
|
||||||
postBuiltinCommand("bm /( Qt5Cored!QMessageLogger::warning",
|
postBuiltinCommand("bm /( Qt5Cored!QMessageLogger::warning",
|
||||||
[this](const CdbResponse &r){ handleBreakInsert(r, BreakpointModelId()); });
|
[this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); });
|
||||||
}
|
}
|
||||||
if (boolSetting(BreakOnFatal)) {
|
if (boolSetting(BreakOnFatal)) {
|
||||||
postBuiltinCommand("bm /( QtCored4!qFatal", // 'bm': All overloads.
|
postBuiltinCommand("bm /( QtCored4!qFatal", // 'bm': All overloads.
|
||||||
[this](const CdbResponse &r){ handleBreakInsert(r, BreakpointModelId()); });
|
[this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); });
|
||||||
postBuiltinCommand("bm /( Qt5Cored!QMessageLogger::fatal",
|
postBuiltinCommand("bm /( Qt5Cored!QMessageLogger::fatal",
|
||||||
[this](const CdbResponse &r){ handleBreakInsert(r, BreakpointModelId()); });
|
[this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); });
|
||||||
}
|
}
|
||||||
if (runParameters().startMode == AttachCore) {
|
if (runParameters().startMode == AttachCore) {
|
||||||
QTC_ASSERT(!m_coreStopReason.isNull(), return; );
|
QTC_ASSERT(!m_coreStopReason.isNull(), return; );
|
||||||
@@ -1027,7 +1030,7 @@ void CdbEngine::executeRunToLine(const ContextData &data)
|
|||||||
bp.lineNumber = data.lineNumber;
|
bp.lineNumber = data.lineNumber;
|
||||||
}
|
}
|
||||||
postBuiltinCommand(cdbAddBreakpointCommand(bp, m_sourcePathMappings, BreakpointModelId(), true),
|
postBuiltinCommand(cdbAddBreakpointCommand(bp, m_sourcePathMappings, BreakpointModelId(), true),
|
||||||
[this](const CdbResponse &r){ handleBreakInsert(r, BreakpointModelId()); });
|
[this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); });
|
||||||
continueInferior();
|
continueInferior();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1038,7 +1041,7 @@ void CdbEngine::executeRunToFunction(const QString &functionName)
|
|||||||
bp.functionName = functionName;
|
bp.functionName = functionName;
|
||||||
|
|
||||||
postBuiltinCommand(cdbAddBreakpointCommand(bp, m_sourcePathMappings, BreakpointModelId(), true),
|
postBuiltinCommand(cdbAddBreakpointCommand(bp, m_sourcePathMappings, BreakpointModelId(), true),
|
||||||
[this](const CdbResponse &r){ handleBreakInsert(r, BreakpointModelId()); });
|
[this](const DebuggerResponse &r) { handleBreakInsert(r, BreakpointModelId()); });
|
||||||
continueInferior();
|
continueInferior();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1063,7 +1066,7 @@ void CdbEngine::executeJumpToLine(const ContextData &data)
|
|||||||
QByteArray cmd;
|
QByteArray cmd;
|
||||||
ByteArrayInputStream str(cmd);
|
ByteArrayInputStream str(cmd);
|
||||||
str << "? `" << QDir::toNativeSeparators(data.fileName) << ':' << data.lineNumber << '`';
|
str << "? `" << QDir::toNativeSeparators(data.fileName) << ':' << data.lineNumber << '`';
|
||||||
postBuiltinCommand(cmd, [this, data](const CdbResponse &r) { handleJumpToLineAddressResolution(r, data); });
|
postBuiltinCommand(cmd, [this, data](const DebuggerResponse &r) { handleJumpToLineAddressResolution(r, data); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1080,13 +1083,13 @@ void CdbEngine::jumpToAddress(quint64 address)
|
|||||||
postCommand(registerCmd);
|
postCommand(registerCmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::handleJumpToLineAddressResolution(const CdbResponse &response, const ContextData &context)
|
void CdbEngine::handleJumpToLineAddressResolution(const DebuggerResponse &response, const ContextData &context)
|
||||||
{
|
{
|
||||||
if (response.reply.isEmpty())
|
if (response.data.toLatin1().isEmpty())
|
||||||
return;
|
return;
|
||||||
// Evaluate expression: 5365511549 = 00000001`3fcf357d
|
// Evaluate expression: 5365511549 = 00000001`3fcf357d
|
||||||
// Set register 'rip' to hex address and goto lcoation
|
// Set register 'rip' to hex address and goto lcoation
|
||||||
QByteArray answer = response.reply.trimmed();
|
QByteArray answer = response.data.data().trimmed();
|
||||||
const int equalPos = answer.indexOf(" = ");
|
const int equalPos = answer.indexOf(" = ");
|
||||||
if (equalPos == -1)
|
if (equalPos == -1)
|
||||||
return;
|
return;
|
||||||
@@ -1148,18 +1151,18 @@ void CdbEngine::assignValueInDebugger(WatchItem *w, const QString &expr, const Q
|
|||||||
updateLocals();
|
updateLocals();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::handleThreads(const CdbResponse &response)
|
void CdbEngine::handleThreads(const DebuggerResponse &response)
|
||||||
{
|
{
|
||||||
if (debug)
|
if (debug) {
|
||||||
qDebug("CdbEngine::handleThreads success=%d", response.success);
|
qDebug("CdbEngine::handleThreads %s",
|
||||||
if (response.success) {
|
DebuggerResponse::stringFromResultClass(response.resultClass).data());
|
||||||
GdbMi data;
|
}
|
||||||
data.fromString(response.reply);
|
if (response.resultClass == ResultDone) {
|
||||||
threadsHandler()->updateThreads(data);
|
threadsHandler()->updateThreads(response.data);
|
||||||
// Continue sequence
|
// Continue sequence
|
||||||
reloadFullStack();
|
reloadFullStack();
|
||||||
} else {
|
} else {
|
||||||
showMessage(QString::fromLatin1(response.errorMessage), LogError);
|
showMessage(response.data["msg"].toLatin1(), LogError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1359,7 +1362,7 @@ void CdbEngine::doUpdateLocals(const UpdateParameters &updateParameters)
|
|||||||
str << blankSeparator << updateParameters.partialVariable;
|
str << blankSeparator << updateParameters.partialVariable;
|
||||||
|
|
||||||
postExtensionCommand("locals", arguments,
|
postExtensionCommand("locals", arguments,
|
||||||
[this, partialUpdate](const CdbResponse &r) { handleLocals(r, partialUpdate); });
|
[this, partialUpdate](const DebuggerResponse &r) { handleLocals(r, partialUpdate); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::updateAll()
|
void CdbEngine::updateAll()
|
||||||
@@ -1375,7 +1378,7 @@ void CdbEngine::selectThread(ThreadId threadId)
|
|||||||
threadsHandler()->setCurrentThread(threadId);
|
threadsHandler()->setCurrentThread(threadId);
|
||||||
|
|
||||||
const QByteArray cmd = '~' + QByteArray::number(threadId.raw()) + " s";
|
const QByteArray cmd = '~' + QByteArray::number(threadId.raw()) + " s";
|
||||||
postBuiltinCommand(cmd, [this](const CdbResponse &){
|
postBuiltinCommand(cmd, [this](const DebuggerResponse &) {
|
||||||
postExtensionCommand("stack", "unlimited", CB(handleStackTrace));
|
postExtensionCommand("stack", "unlimited", CB(handleStackTrace));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1423,7 +1426,7 @@ void CdbEngine::postDisassemblerCommand(quint64 address, quint64 endAddress,
|
|||||||
QByteArray cmd;
|
QByteArray cmd;
|
||||||
ByteArrayInputStream str(cmd);
|
ByteArrayInputStream str(cmd);
|
||||||
str << "u " << hex <<hexPrefixOn << address << ' ' << endAddress;
|
str << "u " << hex <<hexPrefixOn << address << ' ' << endAddress;
|
||||||
postBuiltinCommand(cmd, [this, agent](const CdbResponse &r) { handleDisassembler(r, agent); });
|
postBuiltinCommand(cmd, [this, agent](const DebuggerResponse &r) { handleDisassembler(r, agent); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::postResolveSymbol(const QString &module, const QString &function,
|
void CdbEngine::postResolveSymbol(const QString &module, const QString &function,
|
||||||
@@ -1436,7 +1439,7 @@ void CdbEngine::postResolveSymbol(const QString &module, const QString &function
|
|||||||
if (addresses.isEmpty()) {
|
if (addresses.isEmpty()) {
|
||||||
showMessage(QLatin1String("Resolving symbol: ") + symbol + QLatin1String("..."), LogMisc);
|
showMessage(QLatin1String("Resolving symbol: ") + symbol + QLatin1String("..."), LogMisc);
|
||||||
postBuiltinCommand(QByteArray("x ") + symbol.toLatin1(),
|
postBuiltinCommand(QByteArray("x ") + symbol.toLatin1(),
|
||||||
[this, symbol, agent](const CdbResponse &r) { handleResolveSymbol(r, symbol, agent); });
|
[this, symbol, agent](const DebuggerResponse &r) { handleResolveSymbol(r, symbol, agent); });
|
||||||
} else {
|
} else {
|
||||||
showMessage(QString::fromLatin1("Using cached addresses for %1.").
|
showMessage(QString::fromLatin1("Using cached addresses for %1.").
|
||||||
arg(symbol), LogMisc);
|
arg(symbol), LogMisc);
|
||||||
@@ -1461,12 +1464,12 @@ static inline quint64 resolvedAddress(const QByteArray &line)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::handleResolveSymbol(const CdbResponse &response, const QString &symbol,
|
void CdbEngine::handleResolveSymbol(const DebuggerResponse &response, const QString &symbol,
|
||||||
DisassemblerAgent *agent)
|
DisassemblerAgent *agent)
|
||||||
{
|
{
|
||||||
// Insert all matches of (potentially) ambiguous symbols
|
// Insert all matches of (potentially) ambiguous symbols
|
||||||
if (!response.reply.isEmpty()) {
|
if (!response.data.data().isEmpty()) {
|
||||||
foreach (QByteArray line, response.reply.split('\n')) {
|
foreach (QByteArray line, response.data.data().split('\n')) {
|
||||||
if (const quint64 address = resolvedAddress(line)) {
|
if (const quint64 address = resolvedAddress(line)) {
|
||||||
m_symbolAddressCache.insert(symbol, address);
|
m_symbolAddressCache.insert(symbol, address);
|
||||||
showMessage(QString::fromLatin1("Obtained 0x%1 for %2").
|
showMessage(QString::fromLatin1("Obtained 0x%1 for %2").
|
||||||
@@ -1475,7 +1478,7 @@ void CdbEngine::handleResolveSymbol(const CdbResponse &response, const QString &
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
showMessage(QLatin1String("Symbol resolution failed: ")
|
showMessage(QLatin1String("Symbol resolution failed: ")
|
||||||
+ QString::fromLatin1(response.reply),
|
+ response.data["msg"].toLatin1(),
|
||||||
LogError);
|
LogError);
|
||||||
}
|
}
|
||||||
handleResolveSymbolHelper(m_symbolAddressCache.values(symbol), agent);
|
handleResolveSymbolHelper(m_symbolAddressCache.values(symbol), agent);
|
||||||
@@ -1563,9 +1566,9 @@ void CdbEngine::handleResolveSymbolHelper(const QList<quint64> &addresses, Disas
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse: "00000000`77606060 cc int 3"
|
// Parse: "00000000`77606060 cc int 3"
|
||||||
void CdbEngine::handleDisassembler(const CdbResponse &response, DisassemblerAgent *agent)
|
void CdbEngine::handleDisassembler(const DebuggerResponse &response, DisassemblerAgent *agent)
|
||||||
{
|
{
|
||||||
agent->setContents(parseCdbDisassembler(response.reply));
|
agent->setContents(parseCdbDisassembler(response.data.data()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::fetchMemory(MemoryAgent *agent, QObject *editor, quint64 addr, quint64 length)
|
void CdbEngine::fetchMemory(MemoryAgent *agent, QObject *editor, quint64 addr, quint64 length)
|
||||||
@@ -1585,7 +1588,7 @@ void CdbEngine::postFetchMemory(const MemoryViewCookie &cookie)
|
|||||||
ByteArrayInputStream str(args);
|
ByteArrayInputStream str(args);
|
||||||
str << cookie.address << ' ' << cookie.length;
|
str << cookie.address << ' ' << cookie.length;
|
||||||
postExtensionCommand("memory", args,
|
postExtensionCommand("memory", args,
|
||||||
[this, cookie](const CdbResponse &r) { handleMemory(r, cookie); });
|
[this, cookie](const DebuggerResponse &r) { handleMemory(r, cookie); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::changeMemory(Internal::MemoryAgent *, QObject *, quint64 addr, const QByteArray &data)
|
void CdbEngine::changeMemory(Internal::MemoryAgent *, QObject *, quint64 addr, const QByteArray &data)
|
||||||
@@ -1599,15 +1602,15 @@ void CdbEngine::changeMemory(Internal::MemoryAgent *, QObject *, quint64 addr, c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::handleMemory(const CdbResponse &response, const MemoryViewCookie &memViewCookie)
|
void CdbEngine::handleMemory(const DebuggerResponse &response, const MemoryViewCookie &memViewCookie)
|
||||||
{
|
{
|
||||||
if (response.success && memViewCookie.agent) {
|
if (response.resultClass == ResultDone && memViewCookie.agent) {
|
||||||
const QByteArray data = QByteArray::fromBase64(response.reply);
|
const QByteArray data = QByteArray::fromBase64(response.data.data());
|
||||||
if (unsigned(data.size()) == memViewCookie.length)
|
if (unsigned(data.size()) == memViewCookie.length)
|
||||||
memViewCookie.agent->addLazyData(memViewCookie.editorToken,
|
memViewCookie.agent->addLazyData(memViewCookie.editorToken,
|
||||||
memViewCookie.address, data);
|
memViewCookie.address, data);
|
||||||
} else {
|
} else {
|
||||||
showMessage(QString::fromLocal8Bit(response.errorMessage), LogWarning);
|
showMessage(response.data["msg"].toLatin1(), LogWarning);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1651,31 +1654,29 @@ void CdbEngine::listBreakpoints()
|
|||||||
postExtensionCommand("breakpoints", QByteArray("-v"), CB(handleBreakPoints));
|
postExtensionCommand("breakpoints", QByteArray("-v"), CB(handleBreakPoints));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::handlePid(const CdbResponse &response)
|
void CdbEngine::handlePid(const DebuggerResponse &response)
|
||||||
{
|
{
|
||||||
// Fails for core dumps.
|
// Fails for core dumps.
|
||||||
if (response.success)
|
if (response.resultClass == ResultDone)
|
||||||
notifyInferiorPid(response.reply.toULongLong());
|
notifyInferiorPid(response.data.data().toULongLong());
|
||||||
if (response.success || runParameters().startMode == AttachCore) {
|
if (response.resultClass == ResultDone || runParameters().startMode == AttachCore) {
|
||||||
STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyInferiorSetupOk")
|
STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyInferiorSetupOk")
|
||||||
notifyInferiorSetupOk();
|
notifyInferiorSetupOk();
|
||||||
} else {
|
} else {
|
||||||
showMessage(QString::fromLatin1("Failed to determine inferior pid: %1").
|
showMessage(QString::fromLatin1("Failed to determine inferior pid: %1").
|
||||||
arg(QLatin1String(response.errorMessage)), LogError);
|
arg(response.data["msg"].toLatin1()), LogError);
|
||||||
STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyInferiorSetupFailed")
|
STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyInferiorSetupFailed")
|
||||||
notifyInferiorSetupFailed();
|
notifyInferiorSetupFailed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::handleModules(const CdbResponse &response)
|
void CdbEngine::handleModules(const DebuggerResponse &response)
|
||||||
{
|
{
|
||||||
if (response.success) {
|
if (response.resultClass == ResultDone) {
|
||||||
GdbMi value;
|
if (response.data.type() == GdbMi::List) {
|
||||||
value.fromString(response.reply);
|
|
||||||
if (value.type() == GdbMi::List) {
|
|
||||||
ModulesHandler *handler = modulesHandler();
|
ModulesHandler *handler = modulesHandler();
|
||||||
handler->beginUpdateAll();
|
handler->beginUpdateAll();
|
||||||
foreach (const GdbMi &gdbmiModule, value.children()) {
|
foreach (const GdbMi &gdbmiModule, response.data.children()) {
|
||||||
Module module;
|
Module module;
|
||||||
module.moduleName = QString::fromLatin1(gdbmiModule["name"].data());
|
module.moduleName = QString::fromLatin1(gdbmiModule["name"].data());
|
||||||
module.modulePath = QString::fromLatin1(gdbmiModule["image"].data());
|
module.modulePath = QString::fromLatin1(gdbmiModule["image"].data());
|
||||||
@@ -1688,22 +1689,20 @@ void CdbEngine::handleModules(const CdbResponse &response)
|
|||||||
handler->endUpdateAll();
|
handler->endUpdateAll();
|
||||||
} else {
|
} else {
|
||||||
showMessage(QString::fromLatin1("Parse error in modules response."), LogError);
|
showMessage(QString::fromLatin1("Parse error in modules response."), LogError);
|
||||||
qWarning("Parse error in modules response:\n%s", response.reply.constData());
|
qWarning("Parse error in modules response:\n%s", response.data.data().data());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
showMessage(QString::fromLatin1("Failed to determine modules: %1").
|
showMessage(QString::fromLatin1("Failed to determine modules: %1").
|
||||||
arg(QLatin1String(response.errorMessage)), LogError);
|
arg(response.data["msg"].toLatin1()), LogError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::handleRegistersExt(const CdbResponse &response)
|
void CdbEngine::handleRegistersExt(const DebuggerResponse &response)
|
||||||
{
|
{
|
||||||
if (response.success) {
|
if (response.resultClass == ResultDone) {
|
||||||
GdbMi value;
|
if (response.data.type() == GdbMi::List) {
|
||||||
value.fromString(response.reply);
|
|
||||||
if (value.type() == GdbMi::List) {
|
|
||||||
RegisterHandler *handler = registerHandler();
|
RegisterHandler *handler = registerHandler();
|
||||||
foreach (const GdbMi &item, value.children()) {
|
foreach (const GdbMi &item, response.data.children()) {
|
||||||
Register reg;
|
Register reg;
|
||||||
reg.name = item["name"].data();
|
reg.name = item["name"].data();
|
||||||
reg.description = item["description"].data();
|
reg.description = item["description"].data();
|
||||||
@@ -1715,43 +1714,38 @@ void CdbEngine::handleRegistersExt(const CdbResponse &response)
|
|||||||
handler->commitUpdates();
|
handler->commitUpdates();
|
||||||
} else {
|
} else {
|
||||||
showMessage(QString::fromLatin1("Parse error in registers response."), LogError);
|
showMessage(QString::fromLatin1("Parse error in registers response."), LogError);
|
||||||
qWarning("Parse error in registers response:\n%s", response.reply.constData());
|
qWarning("Parse error in registers response:\n%s", response.data.data().data());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
showMessage(QString::fromLatin1("Failed to determine registers: %1").
|
showMessage(QString::fromLatin1("Failed to determine registers: %1").
|
||||||
arg(QLatin1String(response.errorMessage)), LogError);
|
arg(response.data["msg"].toLatin1()), LogError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::handleLocals(const CdbResponse &response, bool partialUpdate)
|
void CdbEngine::handleLocals(const DebuggerResponse &response, bool partialUpdate)
|
||||||
{
|
{
|
||||||
if (response.success) {
|
if (response.resultClass == ResultDone) {
|
||||||
if (boolSetting(VerboseLog))
|
if (boolSetting(VerboseLog))
|
||||||
showMessage(QLatin1String("Locals: ") + QString::fromLatin1(response.reply), LogDebug);
|
showMessage(QLatin1String(response.data.toString()), LogDebug);
|
||||||
|
|
||||||
GdbMi data;
|
|
||||||
data.fromString(response.reply);
|
|
||||||
QTC_ASSERT(data.type() == GdbMi::List, return);
|
|
||||||
data.m_name = "data";
|
|
||||||
|
|
||||||
GdbMi partial;
|
GdbMi partial;
|
||||||
partial.m_name = "partial";
|
partial.m_name = "partial";
|
||||||
partial.m_data = QByteArray::number(partialUpdate ? 1 : 0);
|
partial.m_data = QByteArray::number(partialUpdate ? 1 : 0);
|
||||||
|
|
||||||
GdbMi all;
|
GdbMi all;
|
||||||
all.m_children.push_back(data);
|
all.m_children.push_back(response.data);
|
||||||
all.m_children.push_back(partial);
|
all.m_children.push_back(partial);
|
||||||
updateLocalsView(all);
|
updateLocalsView(all);
|
||||||
} else {
|
} else {
|
||||||
showMessage(QString::fromLatin1(response.errorMessage), LogWarning);
|
showMessage(response.data["msg"].toLatin1(), LogWarning);
|
||||||
}
|
}
|
||||||
watchHandler()->notifyUpdateFinished();
|
watchHandler()->notifyUpdateFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::handleExpandLocals(const CdbResponse &response)
|
void CdbEngine::handleExpandLocals(const DebuggerResponse &response)
|
||||||
{
|
{
|
||||||
if (!response.success)
|
if (response.resultClass != ResultDone)
|
||||||
showMessage(QString::fromLatin1(response.errorMessage), LogError);
|
showMessage(response.data["msg"].toLatin1(), LogError);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum CdbExecutionStatus {
|
enum CdbExecutionStatus {
|
||||||
@@ -1886,7 +1880,7 @@ unsigned CdbEngine::examineStopReason(const GdbMi &stopReason,
|
|||||||
exp.append('"');
|
exp.append('"');
|
||||||
}
|
}
|
||||||
postExtensionCommand("expression", exp,
|
postExtensionCommand("expression", exp,
|
||||||
[this, id, stopReason](const CdbResponse &r) { handleExpression(r, id, stopReason); });
|
[this, id, stopReason](const DebuggerResponse &r) { handleExpression(r, id, stopReason); });
|
||||||
|
|
||||||
return StopReportLog;
|
return StopReportLog;
|
||||||
}
|
}
|
||||||
@@ -2050,7 +2044,7 @@ void CdbEngine::processStop(const GdbMi &stopReason, bool conditionalBreakPointT
|
|||||||
return;
|
return;
|
||||||
case ParseStackWow64:
|
case ParseStackWow64:
|
||||||
postBuiltinCommand("lm m wow64",
|
postBuiltinCommand("lm m wow64",
|
||||||
[this, stack](const CdbResponse &r) { handleCheckWow64(r, stack); });
|
[this, stack](const DebuggerResponse &r) { handleCheckWow64(r, stack); });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -2079,9 +2073,9 @@ void CdbEngine::processStop(const GdbMi &stopReason, bool conditionalBreakPointT
|
|||||||
showStoppedByExceptionMessageBox(exceptionBoxMessage);
|
showStoppedByExceptionMessageBox(exceptionBoxMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::handleBreakInsert(const CdbResponse &response, const BreakpointModelId &bpId)
|
void CdbEngine::handleBreakInsert(const DebuggerResponse &response, const BreakpointModelId &bpId)
|
||||||
{
|
{
|
||||||
const QList<QByteArray> &reply = response.reply.split('\n');
|
const QList<QByteArray> &reply = response.data.data().split('\n');
|
||||||
if (reply.isEmpty())
|
if (reply.isEmpty())
|
||||||
return;
|
return;
|
||||||
foreach (const QByteArray &line, reply)
|
foreach (const QByteArray &line, reply)
|
||||||
@@ -2134,25 +2128,25 @@ void CdbEngine::handleBreakInsert(const CdbResponse &response, const BreakpointM
|
|||||||
attemptBreakpointSynchronization();
|
attemptBreakpointSynchronization();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::handleCheckWow64(const CdbResponse &response, const GdbMi &stack)
|
void CdbEngine::handleCheckWow64(const DebuggerResponse &response, const GdbMi &stack)
|
||||||
{
|
{
|
||||||
// Using the lm (list modules) command to check if there is a 32 bit subsystem in this debuggee.
|
// Using the lm (list modules) command to check if there is a 32 bit subsystem in this debuggee.
|
||||||
// expected reply if there is a 32 bit stack:
|
// expected reply if there is a 32 bit stack:
|
||||||
// start end module name
|
// start end module name
|
||||||
// 00000000`77490000 00000000`774d5000 wow64 (deferred)
|
// 00000000`77490000 00000000`774d5000 wow64 (deferred)
|
||||||
if (response.reply.contains("wow64")) {
|
if (response.data.data().contains("wow64")) {
|
||||||
postBuiltinCommand("k", [this, stack](const CdbResponse &r) { ensureUsing32BitStackInWow64(r, stack); });
|
postBuiltinCommand("k", [this, stack](const DebuggerResponse &r) { ensureUsing32BitStackInWow64(r, stack); });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_wow64State = noWow64Stack;
|
m_wow64State = noWow64Stack;
|
||||||
parseStackTrace(stack, false);
|
parseStackTrace(stack, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::ensureUsing32BitStackInWow64(const CdbResponse &response, const GdbMi &stack)
|
void CdbEngine::ensureUsing32BitStackInWow64(const DebuggerResponse &response, const GdbMi &stack)
|
||||||
{
|
{
|
||||||
// Parsing the header of the stack output to check which bitness
|
// Parsing the header of the stack output to check which bitness
|
||||||
// the cdb is currently using.
|
// the cdb is currently using.
|
||||||
foreach (const QByteArray &line, response.reply.split('\n')) {
|
foreach (const QByteArray &line, response.data.data().split('\n')) {
|
||||||
if (!line.startsWith("Child"))
|
if (!line.startsWith("Child"))
|
||||||
continue;
|
continue;
|
||||||
if (line.startsWith("ChildEBP")) {
|
if (line.startsWith("ChildEBP")) {
|
||||||
@@ -2169,11 +2163,11 @@ void CdbEngine::ensureUsing32BitStackInWow64(const CdbResponse &response, const
|
|||||||
parseStackTrace(stack, false);
|
parseStackTrace(stack, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::handleSwitchWow64Stack(const CdbResponse &response)
|
void CdbEngine::handleSwitchWow64Stack(const DebuggerResponse &response)
|
||||||
{
|
{
|
||||||
if (response.reply == "Switched to 32bit mode")
|
if (response.data.data() == "Switched to 32bit mode")
|
||||||
m_wow64State = wow64Stack32Bit;
|
m_wow64State = wow64Stack32Bit;
|
||||||
else if (response.reply == "Switched to 64bit mode")
|
else if (response.data.data() == "Switched to 64bit mode")
|
||||||
m_wow64State = wow64Stack64Bit;
|
m_wow64State = wow64Stack64Bit;
|
||||||
else
|
else
|
||||||
m_wow64State = noWow64Stack;
|
m_wow64State = noWow64Stack;
|
||||||
@@ -2272,13 +2266,23 @@ void CdbEngine::handleExtensionMessage(char t, int token, const QByteArray &what
|
|||||||
|
|
||||||
if (!command->handler)
|
if (!command->handler)
|
||||||
return;
|
return;
|
||||||
CdbResponse response;
|
DebuggerResponse response;
|
||||||
|
response.data.m_name = "data";
|
||||||
if (t == 'R') {
|
if (t == 'R') {
|
||||||
response.success = true;
|
response.resultClass = ResultDone;
|
||||||
response.reply = message;
|
response.data.fromString(message);
|
||||||
|
if (!response.data.isValid()) {
|
||||||
|
response.data.m_data = message;
|
||||||
|
response.data.m_type = GdbMi::Tuple;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
response.success = false;
|
response.resultClass = ResultError;
|
||||||
response.errorMessage = message;
|
GdbMi msg;
|
||||||
|
msg.m_name = "msg";
|
||||||
|
msg.m_data = message;
|
||||||
|
msg.m_type = GdbMi::Tuple;
|
||||||
|
response.data.m_type = GdbMi::Tuple;
|
||||||
|
response.data.m_children.push_back(msg);
|
||||||
}
|
}
|
||||||
command->handler(response);
|
command->handler(response);
|
||||||
return;
|
return;
|
||||||
@@ -2432,35 +2436,42 @@ void CdbEngine::parseOutputLine(QByteArray line)
|
|||||||
|
|
||||||
// If there is a current command, wait for end of output indicated by token,
|
// If there is a current command, wait for end of output indicated by token,
|
||||||
// command, trigger handler and finish, else append to its output.
|
// command, trigger handler and finish, else append to its output.
|
||||||
if (m_currentBuiltinResponse.token != -1) {
|
if (m_currentBuiltinResponseToken != -1) {
|
||||||
QTC_ASSERT(!isStartToken, return);
|
QTC_ASSERT(!isStartToken, return);
|
||||||
if (isCommandToken) {
|
if (isCommandToken) {
|
||||||
// Did the command finish? Invoke callback and remove from queue.
|
// Did the command finish? Invoke callback and remove from queue.
|
||||||
if (debug)
|
if (debug)
|
||||||
qDebug("### Completed builtin command for token=%d, %d lines, pending=%d",
|
qDebug("### Completed builtin command for token=%d, %d lines, pending=%d",
|
||||||
m_currentBuiltinResponse.token, m_currentBuiltinResponse.reply.count('\n'),
|
m_currentBuiltinResponseToken, m_currentBuiltinResponse.count('\n'),
|
||||||
m_builtinCommandQueue.size() - 1);
|
m_builtinCommandQueue.size() - 1);
|
||||||
QTC_ASSERT(token == m_currentBuiltinResponse.token, return);
|
QTC_ASSERT(token == m_currentBuiltinResponseToken, return);
|
||||||
if (boolSetting(VerboseLog))
|
if (boolSetting(VerboseLog))
|
||||||
showMessage(QLatin1String(m_currentBuiltinResponse.reply), LogMisc);
|
showMessage(QLatin1String(m_currentBuiltinResponse), LogMisc);
|
||||||
const int commandIndex = indexOfCommand(m_builtinCommandQueue, m_currentBuiltinResponse.token);
|
const int commandIndex = indexOfCommand(m_builtinCommandQueue, m_currentBuiltinResponseToken);
|
||||||
QTC_ASSERT(commandIndex >= 0 && commandIndex < m_builtinCommandQueue.size(), return);
|
QTC_ASSERT(commandIndex >= 0 && commandIndex < m_builtinCommandQueue.size(), return);
|
||||||
const CdbCommandPtr ¤tCommand = m_builtinCommandQueue.at(commandIndex);
|
const CdbCommandPtr ¤tCommand = m_builtinCommandQueue.at(commandIndex);
|
||||||
|
DebuggerResponse response;
|
||||||
|
response.token = token;
|
||||||
|
response.data.m_name = "data";
|
||||||
|
response.data.m_data = m_currentBuiltinResponse;
|
||||||
|
response.data.m_type = GdbMi::Tuple;
|
||||||
|
response.resultClass = ResultDone;
|
||||||
if (currentCommand->handler)
|
if (currentCommand->handler)
|
||||||
currentCommand->handler(m_currentBuiltinResponse);
|
currentCommand->handler(response);
|
||||||
m_builtinCommandQueue.removeAt(commandIndex);
|
m_builtinCommandQueue.removeAt(commandIndex);
|
||||||
|
m_currentBuiltinResponseToken = -1;
|
||||||
m_currentBuiltinResponse.clear();
|
m_currentBuiltinResponse.clear();
|
||||||
} else {
|
} else {
|
||||||
// Record output of current command
|
// Record output of current command
|
||||||
if (!m_currentBuiltinResponse.reply.isEmpty())
|
if (!m_currentBuiltinResponse.isEmpty())
|
||||||
m_currentBuiltinResponse.reply.push_back('\n');
|
m_currentBuiltinResponse.push_back('\n');
|
||||||
m_currentBuiltinResponse.reply.push_back(line);
|
m_currentBuiltinResponse.push_back(line);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (isCommandToken) {
|
if (isCommandToken) {
|
||||||
// Beginning command token encountered, start to record output.
|
// Beginning command token encountered, start to record output.
|
||||||
m_currentBuiltinResponse.token = token;
|
m_currentBuiltinResponseToken = token;
|
||||||
if (debug)
|
if (debug)
|
||||||
qDebug("### Gathering output for token %d", token);
|
qDebug("### Gathering output for token %d", token);
|
||||||
return;
|
return;
|
||||||
@@ -2700,11 +2711,11 @@ void CdbEngine::attemptBreakpointSynchronization()
|
|||||||
response.lineNumber = lineCorrection->fixLineNumber(parameters.fileName, parameters.lineNumber);
|
response.lineNumber = lineCorrection->fixLineNumber(parameters.fileName, parameters.lineNumber);
|
||||||
postBuiltinCommand(
|
postBuiltinCommand(
|
||||||
cdbAddBreakpointCommand(response, m_sourcePathMappings, id, false),
|
cdbAddBreakpointCommand(response, m_sourcePathMappings, id, false),
|
||||||
[this, id](const CdbResponse &r){ handleBreakInsert(r, id); });
|
[this, id](const DebuggerResponse &r) { handleBreakInsert(r, id); });
|
||||||
} else {
|
} else {
|
||||||
postBuiltinCommand(
|
postBuiltinCommand(
|
||||||
cdbAddBreakpointCommand(parameters, m_sourcePathMappings, id, false),
|
cdbAddBreakpointCommand(parameters, m_sourcePathMappings, id, false),
|
||||||
[this, id](const CdbResponse &r){ handleBreakInsert(r, id); });
|
[this, id](const DebuggerResponse &r) { handleBreakInsert(r, id); });
|
||||||
}
|
}
|
||||||
if (!parameters.enabled)
|
if (!parameters.enabled)
|
||||||
postCommand("bd " + QByteArray::number(breakPointIdToCdbId(id)));
|
postCommand("bd " + QByteArray::number(breakPointIdToCdbId(id)));
|
||||||
@@ -2737,7 +2748,7 @@ void CdbEngine::attemptBreakpointSynchronization()
|
|||||||
postCommand(cdbClearBreakpointCommand(id));
|
postCommand(cdbClearBreakpointCommand(id));
|
||||||
postBuiltinCommand(
|
postBuiltinCommand(
|
||||||
cdbAddBreakpointCommand(parameters, m_sourcePathMappings, id, false),
|
cdbAddBreakpointCommand(parameters, m_sourcePathMappings, id, false),
|
||||||
[this, id](const CdbResponse &r){ handleBreakInsert(r, id); });
|
[this, id](const DebuggerResponse &r) { handleBreakInsert(r, id); });
|
||||||
m_pendingBreakpointMap.insert(id, response);
|
m_pendingBreakpointMap.insert(id, response);
|
||||||
}
|
}
|
||||||
bp.notifyBreakpointChangeOk();
|
bp.notifyBreakpointChangeOk();
|
||||||
@@ -2885,21 +2896,19 @@ void CdbEngine::loadAdditionalQmlStack()
|
|||||||
postExtensionCommand("qmlstack", QByteArray(), CB(handleAdditionalQmlStack));
|
postExtensionCommand("qmlstack", QByteArray(), CB(handleAdditionalQmlStack));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::handleAdditionalQmlStack(const CdbResponse &response)
|
void CdbEngine::handleAdditionalQmlStack(const DebuggerResponse &response)
|
||||||
{
|
{
|
||||||
QString errorMessage;
|
QString errorMessage;
|
||||||
do {
|
do {
|
||||||
if (!response.success) {
|
if (response.resultClass != ResultDone) {
|
||||||
errorMessage = QLatin1String(response.errorMessage);
|
errorMessage = response.data["msg"].toLatin1();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
GdbMi stackGdbMi;
|
if (!response.data.isValid()) {
|
||||||
stackGdbMi.fromString(response.reply);
|
|
||||||
if (!stackGdbMi.isValid()) {
|
|
||||||
errorMessage = QLatin1String("GDBMI parser error");
|
errorMessage = QLatin1String("GDBMI parser error");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
StackFrames qmlFrames = parseFrames(stackGdbMi);
|
StackFrames qmlFrames = parseFrames(response.data);
|
||||||
const int qmlFrameCount = qmlFrames.size();
|
const int qmlFrameCount = qmlFrames.size();
|
||||||
if (!qmlFrameCount) {
|
if (!qmlFrameCount) {
|
||||||
errorMessage = QLatin1String("Empty stack");
|
errorMessage = QLatin1String("Empty stack");
|
||||||
@@ -2924,27 +2933,26 @@ void CdbEngine::mergeStartParametersSourcePathMap()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::handleStackTrace(const CdbResponse &response)
|
void CdbEngine::handleStackTrace(const DebuggerResponse &response)
|
||||||
{
|
{
|
||||||
if (response.success) {
|
GdbMi stack = response.data;
|
||||||
GdbMi stack;
|
if (response.resultClass == ResultDone) {
|
||||||
stack.fromString(response.reply);
|
|
||||||
if (parseStackTrace(stack, false) == ParseStackWow64) {
|
if (parseStackTrace(stack, false) == ParseStackWow64) {
|
||||||
postBuiltinCommand("lm m wow64",
|
postBuiltinCommand("lm m wow64",
|
||||||
[this, stack](const CdbResponse &r) { handleCheckWow64(r, stack); });
|
[this, stack](const DebuggerResponse &r) { handleCheckWow64(r, stack); });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
showMessage(QString::fromLocal8Bit(response.errorMessage), LogError);
|
showMessage(stack["msg"].toLatin1(), LogError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::handleExpression(const CdbResponse &response, BreakpointModelId id, const GdbMi &stopReason)
|
void CdbEngine::handleExpression(const DebuggerResponse &response, BreakpointModelId id, const GdbMi &stopReason)
|
||||||
{
|
{
|
||||||
int value = 0;
|
int value = 0;
|
||||||
if (response.success)
|
if (response.resultClass == ResultDone)
|
||||||
value = response.reply.toInt();
|
value = response.data.toInt();
|
||||||
else
|
else
|
||||||
showMessage(QString::fromLocal8Bit(response.errorMessage), LogError);
|
showMessage(response.data["msg"].toLatin1(), LogError);
|
||||||
// Is this a conditional breakpoint?
|
// Is this a conditional breakpoint?
|
||||||
const QString message = value ?
|
const QString message = value ?
|
||||||
tr("Value %1 obtained from evaluating the condition of breakpoint %2, stopping.").
|
tr("Value %1 obtained from evaluating the condition of breakpoint %2, stopping.").
|
||||||
@@ -2959,17 +2967,17 @@ void CdbEngine::handleExpression(const CdbResponse &response, BreakpointModelId
|
|||||||
doContinueInferior();
|
doContinueInferior();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::handleWidgetAt(const CdbResponse &response)
|
void CdbEngine::handleWidgetAt(const DebuggerResponse &response)
|
||||||
{
|
{
|
||||||
bool success = false;
|
bool success = false;
|
||||||
QString message;
|
QString message;
|
||||||
do {
|
do {
|
||||||
if (!response.success) {
|
if (response.resultClass != ResultDone) {
|
||||||
message = QString::fromLatin1(response.errorMessage);
|
message = response.data["msg"].toLatin1();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Should be "namespace::QWidget:0x555"
|
// Should be "namespace::QWidget:0x555"
|
||||||
QString watchExp = QString::fromLatin1(response.reply);
|
QString watchExp = response.data.toLatin1();
|
||||||
const int sepPos = watchExp.lastIndexOf(QLatin1Char(':'));
|
const int sepPos = watchExp.lastIndexOf(QLatin1Char(':'));
|
||||||
if (sepPos == -1) {
|
if (sepPos == -1) {
|
||||||
message = QString::fromLatin1("Invalid output: %1").arg(watchExp);
|
message = QString::fromLatin1("Invalid output: %1").arg(watchExp);
|
||||||
@@ -3009,33 +3017,29 @@ static inline void formatCdbBreakPointResponse(BreakpointModelId id, const Break
|
|||||||
str << '\n';
|
str << '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::handleBreakPoints(const CdbResponse &response)
|
void CdbEngine::handleBreakPoints(const DebuggerResponse &response)
|
||||||
{
|
{
|
||||||
if (debugBreakpoints)
|
if (true) {
|
||||||
qDebug("CdbEngine::handleBreakPoints: success=%d: %s", response.success, response.reply.constData());
|
qDebug("CdbEngine::handleBreakPoints: success=%d: %s",
|
||||||
if (!response.success) {
|
response.resultClass == ResultDone, QLatin1String(response.data.toString()).data());
|
||||||
showMessage(QString::fromLatin1(response.errorMessage), LogError);
|
}
|
||||||
|
if (response.resultClass != ResultDone) {
|
||||||
|
showMessage(response.data["msg"].toLatin1(), LogError);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
GdbMi value;
|
if (response.data.type() != GdbMi::List) {
|
||||||
value.fromString(response.reply);
|
showMessage(QString::fromLatin1("Unable to parse breakpoints reply"), LogError);
|
||||||
if (value.type() != GdbMi::List) {
|
|
||||||
showMessage(QString::fromLatin1("Unabled to parse breakpoints reply"), LogError);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
handleBreakPoints(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CdbEngine::handleBreakPoints(const GdbMi &value)
|
|
||||||
{
|
|
||||||
// Report all obtained parameters back. Note that not all parameters are reported
|
// Report all obtained parameters back. Note that not all parameters are reported
|
||||||
// back, so, match by id and complete
|
// back, so, match by id and complete
|
||||||
if (debugBreakpoints)
|
if (debugBreakpoints)
|
||||||
qDebug("\nCdbEngine::handleBreakPoints with %d", value.childCount());
|
qDebug("\nCdbEngine::handleBreakPoints with %d", response.data.childCount());
|
||||||
QString message;
|
QString message;
|
||||||
QTextStream str(&message);
|
QTextStream str(&message);
|
||||||
BreakHandler *handler = breakHandler();
|
BreakHandler *handler = breakHandler();
|
||||||
foreach (const GdbMi &breakPointG, value.children()) {
|
foreach (const GdbMi &breakPointG, response.data.children()) {
|
||||||
BreakpointResponse reportedResponse;
|
BreakpointResponse reportedResponse;
|
||||||
parseBreakPoint(breakPointG, &reportedResponse);
|
parseBreakPoint(breakPointG, &reportedResponse);
|
||||||
if (debugBreakpoints)
|
if (debugBreakpoints)
|
||||||
|
|||||||
@@ -54,35 +54,13 @@ struct MemoryViewCookie;
|
|||||||
class ByteArrayInputStream;
|
class ByteArrayInputStream;
|
||||||
class GdbMi;
|
class GdbMi;
|
||||||
|
|
||||||
class CdbResponse
|
|
||||||
{
|
|
||||||
// TODO: replace with DebuggerResponse
|
|
||||||
public:
|
|
||||||
CdbResponse()
|
|
||||||
: token(-1), success(false)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void clear()
|
|
||||||
{
|
|
||||||
token = -1;
|
|
||||||
reply.clear();
|
|
||||||
errorMessage.clear();
|
|
||||||
success = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int token;
|
|
||||||
QByteArray reply;
|
|
||||||
QByteArray errorMessage;
|
|
||||||
bool success;
|
|
||||||
};
|
|
||||||
|
|
||||||
class CdbEngine : public DebuggerEngine
|
class CdbEngine : public DebuggerEngine
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef QSharedPointer<CdbCommand> CdbCommandPtr;
|
typedef QSharedPointer<CdbCommand> CdbCommandPtr;
|
||||||
typedef std::function<void(const CdbResponse &)> CommandHandler;
|
typedef std::function<void(const DebuggerResponse &)> CommandHandler;
|
||||||
|
|
||||||
CdbEngine(const DebuggerRunParameters &sp);
|
CdbEngine(const DebuggerRunParameters &sp);
|
||||||
~CdbEngine();
|
~CdbEngine();
|
||||||
@@ -224,32 +202,31 @@ private:
|
|||||||
void postResolveSymbol(const QString &module, const QString &function,
|
void postResolveSymbol(const QString &module, const QString &function,
|
||||||
DisassemblerAgent *agent);
|
DisassemblerAgent *agent);
|
||||||
// Builtin commands
|
// Builtin commands
|
||||||
void handleStackTrace(const CdbResponse &);
|
void handleStackTrace(const DebuggerResponse &);
|
||||||
void handleRegisters(const CdbResponse &);
|
void handleRegisters(const DebuggerResponse &);
|
||||||
void handleDisassembler(const CdbResponse &, DisassemblerAgent *agent);
|
void handleDisassembler(const DebuggerResponse &, DisassemblerAgent *agent);
|
||||||
void handleJumpToLineAddressResolution(const CdbResponse &response, const ContextData &context);
|
void handleJumpToLineAddressResolution(const DebuggerResponse &response, const ContextData &context);
|
||||||
void handleExpression(const CdbResponse &command, BreakpointModelId id, const GdbMi &stopReason);
|
void handleExpression(const DebuggerResponse &command, BreakpointModelId id, const GdbMi &stopReason);
|
||||||
void handleResolveSymbol(const CdbResponse &command, const QString &symbol, DisassemblerAgent *agent);
|
void handleResolveSymbol(const DebuggerResponse &command, const QString &symbol, DisassemblerAgent *agent);
|
||||||
void handleResolveSymbolHelper(const QList<quint64> &addresses, DisassemblerAgent *agent);
|
void handleResolveSymbolHelper(const QList<quint64> &addresses, DisassemblerAgent *agent);
|
||||||
void handleBreakInsert(const CdbResponse &response, const BreakpointModelId &bpId);
|
void handleBreakInsert(const DebuggerResponse &response, const BreakpointModelId &bpId);
|
||||||
void handleCheckWow64(const CdbResponse &response, const GdbMi &stack);
|
void handleCheckWow64(const DebuggerResponse &response, const GdbMi &stack);
|
||||||
void ensureUsing32BitStackInWow64(const CdbResponse &response, const GdbMi &stack);
|
void ensureUsing32BitStackInWow64(const DebuggerResponse &response, const GdbMi &stack);
|
||||||
void handleSwitchWow64Stack(const CdbResponse &response);
|
void handleSwitchWow64Stack(const DebuggerResponse &response);
|
||||||
void jumpToAddress(quint64 address);
|
void jumpToAddress(quint64 address);
|
||||||
void handleCreateFullBackTrace(const CdbResponse &response);
|
void handleCreateFullBackTrace(const DebuggerResponse &response);
|
||||||
|
|
||||||
// Extension commands
|
// Extension commands
|
||||||
void handleThreads(const CdbResponse &response);
|
void handleThreads(const DebuggerResponse &response);
|
||||||
void handlePid(const CdbResponse &response);
|
void handlePid(const DebuggerResponse &response);
|
||||||
void handleLocals(const CdbResponse &response, bool partialUpdate);
|
void handleLocals(const DebuggerResponse &response, bool partialUpdate);
|
||||||
void handleExpandLocals(const CdbResponse &response);
|
void handleExpandLocals(const DebuggerResponse &response);
|
||||||
void handleRegistersExt(const CdbResponse &response);
|
void handleRegistersExt(const DebuggerResponse &response);
|
||||||
void handleModules(const CdbResponse &response);
|
void handleModules(const DebuggerResponse &response);
|
||||||
void handleMemory(const CdbResponse &response, const MemoryViewCookie &memViewCookie);
|
void handleMemory(const DebuggerResponse &response, const MemoryViewCookie &memViewCookie);
|
||||||
void handleWidgetAt(const CdbResponse &response);
|
void handleWidgetAt(const DebuggerResponse &response);
|
||||||
void handleBreakPoints(const CdbResponse &response);
|
void handleBreakPoints(const DebuggerResponse &response);
|
||||||
void handleBreakPoints(const GdbMi &value);
|
void handleAdditionalQmlStack(const DebuggerResponse &response);
|
||||||
void handleAdditionalQmlStack(const CdbResponse &response);
|
|
||||||
NormalizedSourceFileName sourceMapNormalizeFileNameFromDebugger(const QString &f);
|
NormalizedSourceFileName sourceMapNormalizeFileNameFromDebugger(const QString &f);
|
||||||
void doUpdateLocals(const UpdateParameters ¶ms) override;
|
void doUpdateLocals(const UpdateParameters ¶ms) override;
|
||||||
void updateAll() override;
|
void updateAll() override;
|
||||||
@@ -269,7 +246,8 @@ private:
|
|||||||
ProjectExplorer::DeviceProcessSignalOperation::Ptr m_signalOperation;
|
ProjectExplorer::DeviceProcessSignalOperation::Ptr m_signalOperation;
|
||||||
int m_nextCommandToken;
|
int m_nextCommandToken;
|
||||||
QList<CdbCommandPtr> m_builtinCommandQueue;
|
QList<CdbCommandPtr> m_builtinCommandQueue;
|
||||||
CdbResponse m_currentBuiltinResponse; //!< Current command whose output is recorded.
|
QByteArray m_currentBuiltinResponse;
|
||||||
|
int m_currentBuiltinResponseToken;
|
||||||
QList<CdbCommandPtr> m_extensionCommandQueue;
|
QList<CdbCommandPtr> m_extensionCommandQueue;
|
||||||
QMap<QString, NormalizedSourceFileName> m_normalizedFileCache;
|
QMap<QString, NormalizedSourceFileName> m_normalizedFileCache;
|
||||||
const QByteArray m_extensionCommandPrefixBA; //!< Library name used as prefix
|
const QByteArray m_extensionCommandPrefixBA; //!< Library name used as prefix
|
||||||
|
|||||||
Reference in New Issue
Block a user