Commit 66df65b2 authored by David Schulz's avatar David Schulz

Cdb: Unify the cdb builtin and extension command reply.

Change-Id: Icaee4aee4fbb22b2a55f64cc43effdaebbe63a55
Reviewed-by: default avatarhjk <hjk@theqtcompany.com>
Reviewed-by: default avatarNiels Weber <niels.weber@theqtcompany.com>
parent d26fe608
...@@ -200,15 +200,12 @@ public: ...@@ -200,15 +200,12 @@ public:
: commandSequence(0), success(false) : commandSequence(0), success(false)
{} {}
QByteArray joinedReply() const;
QByteArray command; QByteArray command;
// Continue with other commands as specified in CommandSequenceFlags // Continue with other commands as specified in CommandSequenceFlags
unsigned commandSequence; unsigned commandSequence;
QList<QByteArray> builtinReply; QByteArray reply;
QByteArray extensionReply;
QByteArray errorMessage; QByteArray errorMessage;
bool success; bool success;
}; };
...@@ -235,19 +232,6 @@ public: ...@@ -235,19 +232,6 @@ public:
CdbResponse response; // FIXME: remove. CdbResponse response; // FIXME: remove.
}; };
QByteArray CdbResponse::joinedReply() const
{
if (builtinReply.isEmpty())
return QByteArray();
QByteArray answer;
answer.reserve(120 * builtinReply.size());
foreach (const QByteArray &l, builtinReply) {
answer += l;
answer += '\n';
}
return answer;
}
template <class CommandPtrType> template <class CommandPtrType>
int indexOfCommand(const QList<CommandPtrType> &l, int token) int indexOfCommand(const QList<CommandPtrType> &l, int token)
{ {
...@@ -537,7 +521,7 @@ void CdbEngine::createFullBacktrace() ...@@ -537,7 +521,7 @@ void CdbEngine::createFullBacktrace()
void CdbEngine::handleCreateFullBackTrace(const CdbResponse &response) void CdbEngine::handleCreateFullBackTrace(const CdbResponse &response)
{ {
Internal::openTextEditor(QLatin1String("Backtrace $"), QLatin1String(response.joinedReply())); Internal::openTextEditor(QLatin1String("Backtrace $"), QLatin1String(response.reply));
} }
void CdbEngine::setupEngine() void CdbEngine::setupEngine()
...@@ -1122,11 +1106,11 @@ void CdbEngine::jumpToAddress(quint64 address) ...@@ -1122,11 +1106,11 @@ void CdbEngine::jumpToAddress(quint64 address)
void CdbEngine::handleJumpToLineAddressResolution(const CdbResponse &response, const ContextData &context) void CdbEngine::handleJumpToLineAddressResolution(const CdbResponse &response, const ContextData &context)
{ {
if (response.builtinReply.isEmpty()) if (response.reply.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.builtinReply.front().trimmed(); QByteArray answer = response.reply.trimmed();
const int equalPos = answer.indexOf(" = "); const int equalPos = answer.indexOf(" = ");
if (equalPos == -1) if (equalPos == -1)
return; return;
...@@ -1194,7 +1178,7 @@ void CdbEngine::handleThreads(const CdbResponse &response) ...@@ -1194,7 +1178,7 @@ void CdbEngine::handleThreads(const CdbResponse &response)
qDebug("CdbEngine::handleThreads success=%d", response.success); qDebug("CdbEngine::handleThreads success=%d", response.success);
if (response.success) { if (response.success) {
GdbMi data; GdbMi data;
data.fromString(response.extensionReply); data.fromString(response.reply);
threadsHandler()->updateThreads(data); threadsHandler()->updateThreads(data);
// Continue sequence // Continue sequence
postCommandSequence(response.commandSequence); postCommandSequence(response.commandSequence);
...@@ -1505,17 +1489,17 @@ void CdbEngine::handleResolveSymbol(const CdbResponse &response, const QString & ...@@ -1505,17 +1489,17 @@ void CdbEngine::handleResolveSymbol(const CdbResponse &response, const QString &
DisassemblerAgent *agent) DisassemblerAgent *agent)
{ {
// Insert all matches of (potentially) ambiguous symbols // Insert all matches of (potentially) ambiguous symbols
if (const int size = response.builtinReply.size()) { if (!response.reply.isEmpty()) {
for (int i = 0; i < size; i++) { foreach (QByteArray line, response.reply.split('\n')) {
if (const quint64 address = resolvedAddress(response.builtinReply.at(i))) { if (const quint64 address = resolvedAddress(line)) {
m_symbolAddressCache.insert(symbol, address); m_symbolAddressCache.insert(symbol, address);
showMessage(QString::fromLatin1("Obtained 0x%1 for %2 (#%3)"). showMessage(QString::fromLatin1("Obtained 0x%1 for %2").
arg(address, 0, 16).arg(symbol).arg(i + 1), LogMisc); arg(address, 0, 16).arg(symbol), LogMisc);
} }
} }
} else { } else {
showMessage(QLatin1String("Symbol resolution failed: ") showMessage(QLatin1String("Symbol resolution failed: ")
+ QString::fromLatin1(response.joinedReply()), + QString::fromLatin1(response.reply),
LogError); LogError);
} }
handleResolveSymbolHelper(m_symbolAddressCache.values(symbol), agent); handleResolveSymbolHelper(m_symbolAddressCache.values(symbol), agent);
...@@ -1605,7 +1589,7 @@ void CdbEngine::handleResolveSymbolHelper(const QList<quint64> &addresses, Disas ...@@ -1605,7 +1589,7 @@ 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 CdbResponse &response, DisassemblerAgent *agent)
{ {
agent->setContents(parseCdbDisassembler(response.builtinReply)); agent->setContents(parseCdbDisassembler(response.reply));
} }
void CdbEngine::fetchMemory(MemoryAgent *agent, QObject *editor, quint64 addr, quint64 length) void CdbEngine::fetchMemory(MemoryAgent *agent, QObject *editor, quint64 addr, quint64 length)
...@@ -1642,7 +1626,7 @@ void CdbEngine::changeMemory(Internal::MemoryAgent *, QObject *, quint64 addr, c ...@@ -1642,7 +1626,7 @@ void CdbEngine::changeMemory(Internal::MemoryAgent *, QObject *, quint64 addr, c
void CdbEngine::handleMemory(const CdbResponse &response, const MemoryViewCookie &memViewCookie) void CdbEngine::handleMemory(const CdbResponse &response, const MemoryViewCookie &memViewCookie)
{ {
if (response.success && memViewCookie.agent) { if (response.success && memViewCookie.agent) {
const QByteArray data = QByteArray::fromBase64(response.extensionReply); const QByteArray data = QByteArray::fromBase64(response.reply);
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);
...@@ -1689,7 +1673,7 @@ void CdbEngine::handlePid(const CdbResponse &response) ...@@ -1689,7 +1673,7 @@ void CdbEngine::handlePid(const CdbResponse &response)
{ {
// Fails for core dumps. // Fails for core dumps.
if (response.success) if (response.success)
notifyInferiorPid(response.extensionReply.toULongLong()); notifyInferiorPid(response.reply.toULongLong());
if (response.success || runParameters().startMode == AttachCore) { if (response.success || runParameters().startMode == AttachCore) {
STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyInferiorSetupOk") STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyInferiorSetupOk")
notifyInferiorSetupOk(); notifyInferiorSetupOk();
...@@ -1705,7 +1689,7 @@ void CdbEngine::handleModules(const CdbResponse &response) ...@@ -1705,7 +1689,7 @@ void CdbEngine::handleModules(const CdbResponse &response)
{ {
if (response.success) { if (response.success) {
GdbMi value; GdbMi value;
value.fromString(response.extensionReply); value.fromString(response.reply);
if (value.type() == GdbMi::List) { if (value.type() == GdbMi::List) {
ModulesHandler *handler = modulesHandler(); ModulesHandler *handler = modulesHandler();
handler->beginUpdateAll(); handler->beginUpdateAll();
...@@ -1722,7 +1706,7 @@ void CdbEngine::handleModules(const CdbResponse &response) ...@@ -1722,7 +1706,7 @@ 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.extensionReply.constData()); qWarning("Parse error in modules response:\n%s", response.reply.constData());
} }
} else { } else {
showMessage(QString::fromLatin1("Failed to determine modules: %1"). showMessage(QString::fromLatin1("Failed to determine modules: %1").
...@@ -1736,7 +1720,7 @@ void CdbEngine::handleRegistersExt(const CdbResponse &response) ...@@ -1736,7 +1720,7 @@ void CdbEngine::handleRegistersExt(const CdbResponse &response)
{ {
if (response.success) { if (response.success) {
GdbMi value; GdbMi value;
value.fromString(response.extensionReply); value.fromString(response.reply);
if (value.type() == GdbMi::List) { if (value.type() == GdbMi::List) {
RegisterHandler *handler = registerHandler(); RegisterHandler *handler = registerHandler();
foreach (const GdbMi &item, value.children()) { foreach (const GdbMi &item, value.children()) {
...@@ -1751,7 +1735,7 @@ void CdbEngine::handleRegistersExt(const CdbResponse &response) ...@@ -1751,7 +1735,7 @@ 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.extensionReply.constData()); qWarning("Parse error in registers response:\n%s", response.reply.constData());
} }
} else { } else {
showMessage(QString::fromLatin1("Failed to determine registers: %1"). showMessage(QString::fromLatin1("Failed to determine registers: %1").
...@@ -1764,10 +1748,10 @@ void CdbEngine::handleLocals(const CdbResponse &response, bool partialUpdate) ...@@ -1764,10 +1748,10 @@ void CdbEngine::handleLocals(const CdbResponse &response, bool partialUpdate)
{ {
if (response.success) { if (response.success) {
if (boolSetting(VerboseLog)) if (boolSetting(VerboseLog))
showMessage(QLatin1String("Locals: ") + QString::fromLatin1(response.extensionReply), LogDebug); showMessage(QLatin1String("Locals: ") + QString::fromLatin1(response.reply), LogDebug);
GdbMi data; GdbMi data;
data.fromString(response.extensionReply); data.fromString(response.reply);
QTC_ASSERT(data.type() == GdbMi::List, return); QTC_ASSERT(data.type() == GdbMi::List, return);
data.m_name = "data"; data.m_name = "data";
...@@ -2118,7 +2102,7 @@ void CdbEngine::processStop(const GdbMi &stopReason, bool conditionalBreakPointT ...@@ -2118,7 +2102,7 @@ void CdbEngine::processStop(const GdbMi &stopReason, bool conditionalBreakPointT
void CdbEngine::handleBreakInsert(const CdbResponse &response) void CdbEngine::handleBreakInsert(const CdbResponse &response)
{ {
const QList<QByteArray> &reply = response.builtinReply; const QList<QByteArray> &reply = response.reply.split('\n');
if (reply.isEmpty()) if (reply.isEmpty())
return; return;
foreach (const QByteArray &line, reply) foreach (const QByteArray &line, reply)
...@@ -2186,7 +2170,7 @@ void CdbEngine::handleCheckWow64(const CdbResponse &response, const GdbMi &stack ...@@ -2186,7 +2170,7 @@ void CdbEngine::handleCheckWow64(const CdbResponse &response, const GdbMi &stack
// 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.builtinReply.value(1).contains("wow64")) { if (response.reply.contains("wow64")) {
postBuiltinCommand("k", [this, stack](const CdbResponse &r) { ensureUsing32BitStackInWow64(r, stack); }); postBuiltinCommand("k", [this, stack](const CdbResponse &r) { ensureUsing32BitStackInWow64(r, stack); });
return; return;
} }
...@@ -2198,7 +2182,7 @@ void CdbEngine::ensureUsing32BitStackInWow64(const CdbResponse &response, const ...@@ -2198,7 +2182,7 @@ void CdbEngine::ensureUsing32BitStackInWow64(const CdbResponse &response, const
{ {
// 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.builtinReply) { foreach (const QByteArray &line, response.reply.split('\n')) {
if (!line.startsWith("Child")) if (!line.startsWith("Child"))
continue; continue;
if (line.startsWith("ChildEBP")) { if (line.startsWith("ChildEBP")) {
...@@ -2217,9 +2201,9 @@ void CdbEngine::ensureUsing32BitStackInWow64(const CdbResponse &response, const ...@@ -2217,9 +2201,9 @@ void CdbEngine::ensureUsing32BitStackInWow64(const CdbResponse &response, const
void CdbEngine::handleSwitchWow64Stack(const CdbResponse &response) void CdbEngine::handleSwitchWow64Stack(const CdbResponse &response)
{ {
if (response.builtinReply.first() == "Switched to 32bit mode") if (response.reply == "Switched to 32bit mode")
m_wow64State = wow64Stack32Bit; m_wow64State = wow64Stack32Bit;
else if (response.builtinReply.first() == "Switched to 64bit mode") else if (response.reply == "Switched to 64bit mode")
m_wow64State = wow64Stack64Bit; m_wow64State = wow64Stack64Bit;
else else
m_wow64State = noWow64Stack; m_wow64State = noWow64Stack;
...@@ -2314,7 +2298,7 @@ void CdbEngine::handleExtensionMessage(char t, int token, const QByteArray &what ...@@ -2314,7 +2298,7 @@ void CdbEngine::handleExtensionMessage(char t, int token, const QByteArray &what
const CdbCommandPtr command = m_extensionCommandQueue.takeAt(index); const CdbCommandPtr command = m_extensionCommandQueue.takeAt(index);
if (t == 'R') { if (t == 'R') {
command->response.success = true; command->response.success = true;
command->response.extensionReply = message; command->response.reply = message;
} else { } else {
command->response.success = false; command->response.success = false;
command->response.errorMessage = message; command->response.errorMessage = message;
...@@ -2484,10 +2468,10 @@ void CdbEngine::parseOutputLine(QByteArray line) ...@@ -2484,10 +2468,10 @@ void CdbEngine::parseOutputLine(QByteArray line)
if (debug) if (debug)
qDebug("### Completed builtin command '%s', token=%d, %d lines, pending=%d", qDebug("### Completed builtin command '%s', token=%d, %d lines, pending=%d",
currentCommand->response.command.constData(), currentCommand->token, currentCommand->response.command.constData(), currentCommand->token,
currentCommand->response.builtinReply.size(), m_builtinCommandQueue.size() - 1); currentCommand->response.reply.count('\n'), m_builtinCommandQueue.size() - 1);
QTC_ASSERT(token == currentCommand->token, return; ); QTC_ASSERT(token == currentCommand->token, return; );
if (boolSetting(VerboseLog)) if (boolSetting(VerboseLog))
showMessage(QLatin1String(currentCommand->response.builtinReply.join(' ')), LogMisc); showMessage(QLatin1String(currentCommand->response.reply), LogMisc);
if (currentCommand->handler) { if (currentCommand->handler) {
currentCommand->handler(currentCommand->response); currentCommand->handler(currentCommand->response);
} }
...@@ -2495,7 +2479,9 @@ void CdbEngine::parseOutputLine(QByteArray line) ...@@ -2495,7 +2479,9 @@ void CdbEngine::parseOutputLine(QByteArray line)
m_currentBuiltinCommandIndex = -1; m_currentBuiltinCommandIndex = -1;
} else { } else {
// Record output of current command // Record output of current command
currentCommand->response.builtinReply.push_back(line); if (!currentCommand->response.reply.isEmpty())
currentCommand->response.reply.push_back('\n');
currentCommand->response.reply.push_back(line);
} }
return; return;
} // m_currentCommandIndex } // m_currentCommandIndex
...@@ -2939,7 +2925,7 @@ void CdbEngine::handleAdditionalQmlStack(const CdbResponse &response) ...@@ -2939,7 +2925,7 @@ void CdbEngine::handleAdditionalQmlStack(const CdbResponse &response)
break; break;
} }
GdbMi stackGdbMi; GdbMi stackGdbMi;
stackGdbMi.fromString(response.extensionReply); stackGdbMi.fromString(response.reply);
if (!stackGdbMi.isValid()) { if (!stackGdbMi.isValid()) {
errorMessage = QLatin1String("GDBMI parser error"); errorMessage = QLatin1String("GDBMI parser error");
break; break;
...@@ -2973,7 +2959,7 @@ void CdbEngine::handleStackTrace(const CdbResponse &response) ...@@ -2973,7 +2959,7 @@ void CdbEngine::handleStackTrace(const CdbResponse &response)
{ {
if (response.success) { if (response.success) {
GdbMi stack; GdbMi stack;
stack.fromString(response.extensionReply); 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 CdbResponse &r) { handleCheckWow64(r, stack); });
...@@ -2988,7 +2974,7 @@ void CdbEngine::handleExpression(const CdbResponse &response, BreakpointModelId ...@@ -2988,7 +2974,7 @@ void CdbEngine::handleExpression(const CdbResponse &response, BreakpointModelId
{ {
int value = 0; int value = 0;
if (response.success) if (response.success)
value = response.extensionReply.toInt(); value = response.reply.toInt();
else else
showMessage(QString::fromLocal8Bit(response.errorMessage), LogError); showMessage(QString::fromLocal8Bit(response.errorMessage), LogError);
// Is this a conditional breakpoint? // Is this a conditional breakpoint?
...@@ -3052,7 +3038,7 @@ void CdbEngine::handleWidgetAt(const CdbResponse &response) ...@@ -3052,7 +3038,7 @@ void CdbEngine::handleWidgetAt(const CdbResponse &response)
break; break;
} }
// Should be "namespace::QWidget:0x555" // Should be "namespace::QWidget:0x555"
QString watchExp = QString::fromLatin1(response.extensionReply); QString watchExp = QString::fromLatin1(response.reply);
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);
...@@ -3095,13 +3081,13 @@ static inline void formatCdbBreakPointResponse(BreakpointModelId id, const Break ...@@ -3095,13 +3081,13 @@ static inline void formatCdbBreakPointResponse(BreakpointModelId id, const Break
void CdbEngine::handleBreakPoints(const CdbResponse &response) void CdbEngine::handleBreakPoints(const CdbResponse &response)
{ {
if (debugBreakpoints) if (debugBreakpoints)
qDebug("CdbEngine::handleBreakPoints: success=%d: %s", response.success, response.extensionReply.constData()); qDebug("CdbEngine::handleBreakPoints: success=%d: %s", response.success, response.reply.constData());
if (!response.success) { if (!response.success) {
showMessage(QString::fromLatin1(response.errorMessage), LogError); showMessage(QString::fromLatin1(response.errorMessage), LogError);
return; return;
} }
GdbMi value; GdbMi value;
value.fromString(response.extensionReply); value.fromString(response.reply);
if (value.type() != GdbMi::List) { if (value.type() != GdbMi::List) {
showMessage(QString::fromLatin1("Unabled to parse breakpoints reply"), LogError); showMessage(QString::fromLatin1("Unabled to parse breakpoints reply"), LogError);
return; return;
......
...@@ -548,7 +548,7 @@ bool parseCdbDisassemblerLine(const QString &line, DisassemblerLine *dLine, uint ...@@ -548,7 +548,7 @@ bool parseCdbDisassemblerLine(const QString &line, DisassemblerLine *dLine, uint
return true; return true;
} }
DisassemblerLines parseCdbDisassembler(const QList<QByteArray> &a) DisassemblerLines parseCdbDisassembler(const QByteArray &a)
{ {
DisassemblerLines result; DisassemblerLines result;
quint64 functionAddress = 0; quint64 functionAddress = 0;
...@@ -557,7 +557,7 @@ DisassemblerLines parseCdbDisassembler(const QList<QByteArray> &a) ...@@ -557,7 +557,7 @@ DisassemblerLines parseCdbDisassembler(const QList<QByteArray> &a)
quint64 functionOffset = 0; quint64 functionOffset = 0;
QString sourceFile; QString sourceFile;
foreach (const QByteArray &lineBA, a) { foreach (const QByteArray &lineBA, a.split('\n')) {
const QString line = QString::fromLatin1(lineBA); const QString line = QString::fromLatin1(lineBA);
// New function. Append as comment line. // New function. Append as comment line.
if (parseCdbDisassemblerFunctionLine(line, &currentFunction, &functionOffset, &sourceFile)) { if (parseCdbDisassemblerFunctionLine(line, &currentFunction, &functionOffset, &sourceFile)) {
......
...@@ -82,7 +82,7 @@ QByteArray cdbWriteMemoryCommand(quint64 addr, const QByteArray &data); ...@@ -82,7 +82,7 @@ QByteArray cdbWriteMemoryCommand(quint64 addr, const QByteArray &data);
QString debugByteArray(const QByteArray &a); QString debugByteArray(const QByteArray &a);
QString StringFromBase64EncodedUtf16(const QByteArray &a); QString StringFromBase64EncodedUtf16(const QByteArray &a);
DisassemblerLines parseCdbDisassembler(const QList<QByteArray> &a); DisassemblerLines parseCdbDisassembler(const QByteArray &a);
// Model EXCEPTION_RECORD + firstchance // Model EXCEPTION_RECORD + firstchance
struct WinException struct WinException
......
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