Debugger: Replace the QVariant callback cookies by direct parameters

Lambda makes it possible.

Change-Id: I26a4df71dcd24b76a4f0d6d67545b2e1c6ba2412
Reviewed-by: hjk <hjk@theqtcompany.com>
This commit is contained in:
hjk
2015-02-06 01:26:47 +01:00
parent d9e7a6e6af
commit 968ba7b74d
10 changed files with 160 additions and 261 deletions

View File

@@ -191,7 +191,6 @@ public:
int token; int token;
ResultClass resultClass; ResultClass resultClass;
GdbMi data; GdbMi data;
QVariant cookie;
QByteArray logStreamOutput; QByteArray logStreamOutput;
QByteArray consoleStreamOutput; QByteArray consoleStreamOutput;
}; };

View File

@@ -39,8 +39,6 @@
namespace Debugger { namespace Debugger {
namespace Internal { namespace Internal {
#define CB(callback) [this](const DebuggerResponse &r) { callback(r); }
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
// //
// AttachGdbAdapter // AttachGdbAdapter
@@ -69,7 +67,8 @@ void GdbAttachEngine::setupInferior()
{ {
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
const qint64 pid = startParameters().attachPID; const qint64 pid = startParameters().attachPID;
postCommand("attach " + QByteArray::number(pid), CB(handleAttach)); postCommand("attach " + QByteArray::number(pid), NoFlags,
[this](const DebuggerResponse &r) { handleAttach(r); });
// Task 254674 does not want to remove them // Task 254674 does not want to remove them
//qq->breakHandler()->removeAllBreakpoints(); //qq->breakHandler()->removeAllBreakpoints();
} }

View File

@@ -213,7 +213,7 @@ void GdbCoreEngine::setupInferior()
// Do that first, otherwise no symbols are loaded. // Do that first, otherwise no symbols are loaded.
QFileInfo fi(m_executable); QFileInfo fi(m_executable);
QByteArray path = fi.absoluteFilePath().toLocal8Bit(); QByteArray path = fi.absoluteFilePath().toLocal8Bit();
postCommand("-file-exec-and-symbols \"" + path + '"', postCommand("-file-exec-and-symbols \"" + path + '"', NoFlags,
CB(handleFileExecAndSymbols)); CB(handleFileExecAndSymbols));
} }
@@ -223,7 +223,7 @@ void GdbCoreEngine::handleFileExecAndSymbols(const DebuggerResponse &response)
QString core = coreFileName(); QString core = coreFileName();
if (response.resultClass == ResultDone) { if (response.resultClass == ResultDone) {
showMessage(tr("Symbols found."), StatusBar); showMessage(tr("Symbols found."), StatusBar);
postCommand("target core " + core.toLocal8Bit(), postCommand("target core " + core.toLocal8Bit(), NoFlags,
CB(handleTargetCore)); CB(handleTargetCore));
return; return;
} }
@@ -246,9 +246,9 @@ void GdbCoreEngine::handleTargetCore(const DebuggerResponse &response)
handleInferiorPrepared(); handleInferiorPrepared();
// Due to the auto-solib-add off setting, we don't have any // Due to the auto-solib-add off setting, we don't have any
// symbols yet. Load them in order of importance. // symbols yet. Load them in order of importance.
reloadStack(true); reloadStack();
reloadModulesInternal(); reloadModulesInternal();
postCommand("p 5", CB(handleRoundTrip)); postCommand("p 5", NoFlags, CB(handleRoundTrip));
return; return;
} }
QString msg = tr("Attach to core \"%1\" failed:") QString msg = tr("Attach to core \"%1\" failed:")

View File

@@ -59,6 +59,7 @@ public:
bool isCore; bool isCore;
}; };
static CoreInfo readExecutableNameFromCore(const QString &debuggerCmd, const QString &coreFile); static CoreInfo readExecutableNameFromCore(const QString &debuggerCmd, const QString &coreFile);
private: private:
void setupEngine(); void setupEngine();
void setupInferior(); void setupInferior();

View File

@@ -858,25 +858,14 @@ void GdbEngine::runCommand(const DebuggerCommand &command)
postCommand("python theDumper." + cmd); postCommand("python theDumper." + cmd);
} }
void GdbEngine::postCommand(const QByteArray &command, GdbCommandCallback callback,
const QVariant &cookie)
{
postCommand(command, NoFlags, callback, cookie);
}
void GdbEngine::postCommand(const QByteArray &command, GdbCommandFlags flags, void GdbEngine::postCommand(const QByteArray &command, GdbCommandFlags flags,
GdbCommandCallback callback, const QVariant &cookie) GdbCommandCallback callback)
{ {
GdbCommand cmd; GdbCommand cmd;
cmd.command = command; cmd.command = command;
cmd.flags = flags; cmd.flags = flags;
cmd.callback = callback; cmd.callback = callback;
cmd.cookie = cookie;
postCommandHelper(cmd);
}
void GdbEngine::postCommandHelper(const GdbCommand &cmd)
{
if (!stateAcceptsGdbCommands(state())) { if (!stateAcceptsGdbCommands(state())) {
PENDING_DEBUG(_("NO GDB PROCESS RUNNING, CMD IGNORED: " + cmd.command)); PENDING_DEBUG(_("NO GDB PROCESS RUNNING, CMD IGNORED: " + cmd.command));
showMessage(_("NO GDB PROCESS RUNNING, CMD IGNORED: %1 %2") showMessage(_("NO GDB PROCESS RUNNING, CMD IGNORED: %1 %2")
@@ -1138,8 +1127,6 @@ void GdbEngine::handleResultRecord(DebuggerResponse *response)
return; return;
} }
response->cookie = cmd.cookie;
bool isExpectedResult = bool isExpectedResult =
(response->resultClass == ResultError) // Can always happen. (response->resultClass == ResultError) // Can always happen.
|| (response->resultClass == ResultRunning && (cmd.flags & RunRequest)) || (response->resultClass == ResultRunning && (cmd.flags & RunRequest))
@@ -1241,10 +1228,10 @@ void GdbEngine::updateAll()
QTC_CHECK(state() == InferiorUnrunnable || state() == InferiorStopOk); QTC_CHECK(state() == InferiorUnrunnable || state() == InferiorStopOk);
reloadModulesInternal(); reloadModulesInternal();
int depth = action(MaximalStackDepth)->value().toInt(); int depth = action(MaximalStackDepth)->value().toInt();
postCommand(stackCommand(depth), CB(handleStackListFrames), postCommand(stackCommand(depth), NoFlags,
QVariant::fromValue<StackCookie>(StackCookie(false, true))); [this](const DebuggerResponse &r) { handleStackListFrames(r, false); });
stackHandler()->setCurrentIndex(0); stackHandler()->setCurrentIndex(0);
postCommand("-thread-info", CB(handleThreadInfo), 0); postCommand("-thread-info", NoFlags, CB(handleThreadInfo));
reloadRegisters(); reloadRegisters();
updateLocals(); updateLocals();
} }
@@ -1295,7 +1282,7 @@ void GdbEngine::handleExecuteJumpToLine(const DebuggerResponse &response)
// This happens on old gdb. Trigger the effect of a '*stopped'. // This happens on old gdb. Trigger the effect of a '*stopped'.
showStatusMessage(tr("Jumped. Stopped")); showStatusMessage(tr("Jumped. Stopped"));
notifyInferiorSpontaneousStop(); notifyInferiorSpontaneousStop();
handleStop2(response); handleStop2(response.data);
} }
} }
@@ -1373,7 +1360,7 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
if (!m_fullStartDone) { if (!m_fullStartDone) {
m_fullStartDone = true; m_fullStartDone = true;
postCommand("sharedlibrary .*"); postCommand("sharedlibrary .*");
postCommand("p 3", CB(handleStop1)); postCommand("p 3", NoFlags, [this, data](const DebuggerResponse &) { handleStop1(data); });
gotoHandleStop1 = false; gotoHandleStop1 = false;
} }
@@ -1468,11 +1455,6 @@ static QByteArray stopSignal(const Abi &abi)
return (abi.os() == Abi::WindowsOS) ? QByteArray("SIGTRAP") : QByteArray("SIGINT"); return (abi.os() == Abi::WindowsOS) ? QByteArray("SIGTRAP") : QByteArray("SIGINT");
} }
void GdbEngine::handleStop1(const DebuggerResponse &response)
{
handleStop1(response.cookie.value<GdbMi>());
}
void GdbEngine::handleStop1(const GdbMi &data) void GdbEngine::handleStop1(const GdbMi &data)
{ {
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state()); QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
@@ -1545,11 +1527,6 @@ void GdbEngine::handleStop1(const GdbMi &data)
handleStop2(data); handleStop2(data);
} }
void GdbEngine::handleStop2(const DebuggerResponse &response)
{
handleStop2(response.cookie.value<GdbMi>());
}
void GdbEngine::handleStop2(const GdbMi &data) void GdbEngine::handleStop2(const GdbMi &data)
{ {
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state()); QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
@@ -1776,7 +1753,7 @@ void GdbEngine::handleExecuteContinue(const DebuggerResponse &response)
flushQueuedCommands(); flushQueuedCommands();
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state()); QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
showStatusMessage(tr("Stopped."), 5000); showStatusMessage(tr("Stopped."), 5000);
reloadStack(true); reloadStack();
} else if (msg.startsWith("Cannot access memory at address")) { } else if (msg.startsWith("Cannot access memory at address")) {
// Happens on single step on ARM prolog and epilogs. // Happens on single step on ARM prolog and epilogs.
} else if (msg.startsWith("\"finish\" not meaningful in the outermost frame")) { } else if (msg.startsWith("\"finish\" not meaningful in the outermost frame")) {
@@ -2466,9 +2443,8 @@ QByteArray GdbEngine::breakpointLocation2(const BreakpointParameters &data)
+ QByteArray::number(data.lineNumber); + QByteArray::number(data.lineNumber);
} }
void GdbEngine::handleWatchInsert(const DebuggerResponse &response) void GdbEngine::handleWatchInsert(const DebuggerResponse &response, Breakpoint bp)
{ {
Breakpoint bp = response.cookie.value<Breakpoint>();
if (bp && response.resultClass == ResultDone) { if (bp && response.resultClass == ResultDone) {
BreakpointResponse br = bp.response(); BreakpointResponse br = bp.response();
// "Hardware watchpoint 2: *0xbfffed40\n" // "Hardware watchpoint 2: *0xbfffed40\n"
@@ -2502,9 +2478,8 @@ void GdbEngine::handleWatchInsert(const DebuggerResponse &response)
} }
} }
void GdbEngine::handleCatchInsert(const DebuggerResponse &response) void GdbEngine::handleCatchInsert(const DebuggerResponse &response, Breakpoint bp)
{ {
Breakpoint bp = response.cookie.value<Breakpoint>();
if (bp && response.resultClass == ResultDone) if (bp && response.resultClass == ResultDone)
bp.notifyBreakpointInsertOk(); bp.notifyBreakpointInsertOk();
} }
@@ -2548,9 +2523,8 @@ void GdbEngine::handleBkpt(const GdbMi &bkpt, Breakpoint bp)
bp.setResponse(br); bp.setResponse(br);
} }
void GdbEngine::handleBreakInsert1(const DebuggerResponse &response) void GdbEngine::handleBreakInsert1(const DebuggerResponse &response, Breakpoint bp)
{ {
Breakpoint bp = response.cookie.value<Breakpoint>();
if (bp.state() == BreakpointRemoveRequested) { if (bp.state() == BreakpointRemoveRequested) {
if (response.resultClass == ResultDone) { if (response.resultClass == ResultDone) {
// This delete was deferred. Act now. // This delete was deferred. Act now.
@@ -2597,14 +2571,13 @@ void GdbEngine::handleBreakInsert1(const DebuggerResponse &response)
// again with MI. // again with MI.
QByteArray cmd = "break " + breakpointLocation2(bp.parameters()); QByteArray cmd = "break " + breakpointLocation2(bp.parameters());
postCommand(cmd, NeedsStop | RebuildBreakpointModel, postCommand(cmd, NeedsStop | RebuildBreakpointModel,
CB(handleBreakInsert2), QVariant::fromValue(bp)); [this, bp](const DebuggerResponse &r) { handleBreakInsert2(r, bp); });
} }
} }
void GdbEngine::handleBreakInsert2(const DebuggerResponse &response) void GdbEngine::handleBreakInsert2(const DebuggerResponse &response, Breakpoint bp)
{ {
if (response.resultClass == ResultDone) { if (response.resultClass == ResultDone) {
Breakpoint bp = response.cookie.value<Breakpoint>();
QTC_ASSERT(bp, return); QTC_ASSERT(bp, return);
bp.notifyBreakpointInsertOk(); bp.notifyBreakpointInsertOk();
} else { } else {
@@ -2615,19 +2588,17 @@ void GdbEngine::handleBreakInsert2(const DebuggerResponse &response)
} }
} }
void GdbEngine::handleBreakDelete(const DebuggerResponse &response) void GdbEngine::handleBreakDelete(const DebuggerResponse &response, Breakpoint bp)
{ {
Breakpoint bp = response.cookie.value<Breakpoint>();
if (response.resultClass == ResultDone) if (response.resultClass == ResultDone)
bp.notifyBreakpointRemoveOk(); bp.notifyBreakpointRemoveOk();
else else
bp.notifyBreakpointRemoveFailed(); bp.notifyBreakpointRemoveFailed();
} }
void GdbEngine::handleBreakDisable(const DebuggerResponse &response) void GdbEngine::handleBreakDisable(const DebuggerResponse &response, Breakpoint bp)
{ {
QTC_CHECK(response.resultClass == ResultDone); QTC_CHECK(response.resultClass == ResultDone);
Breakpoint bp = response.cookie.value<Breakpoint>();
// This should only be the requested state. // This should only be the requested state.
QTC_ASSERT(!bp.isEnabled(), /* Prevent later recursion */); QTC_ASSERT(!bp.isEnabled(), /* Prevent later recursion */);
BreakpointResponse br = bp.response(); BreakpointResponse br = bp.response();
@@ -2636,10 +2607,9 @@ void GdbEngine::handleBreakDisable(const DebuggerResponse &response)
changeBreakpoint(bp); // Maybe there's more to do. changeBreakpoint(bp); // Maybe there's more to do.
} }
void GdbEngine::handleBreakEnable(const DebuggerResponse &response) void GdbEngine::handleBreakEnable(const DebuggerResponse &response, Breakpoint bp)
{ {
QTC_CHECK(response.resultClass == ResultDone); QTC_CHECK(response.resultClass == ResultDone);
Breakpoint bp = response.cookie.value<Breakpoint>();
// This should only be the requested state. // This should only be the requested state.
QTC_ASSERT(bp.isEnabled(), /* Prevent later recursion */); QTC_ASSERT(bp.isEnabled(), /* Prevent later recursion */);
BreakpointResponse br = bp.response(); BreakpointResponse br = bp.response();
@@ -2648,10 +2618,9 @@ void GdbEngine::handleBreakEnable(const DebuggerResponse &response)
changeBreakpoint(bp); // Maybe there's more to do. changeBreakpoint(bp); // Maybe there's more to do.
} }
void GdbEngine::handleBreakThreadSpec(const DebuggerResponse &response) void GdbEngine::handleBreakThreadSpec(const DebuggerResponse &response, Breakpoint bp)
{ {
QTC_CHECK(response.resultClass == ResultDone); QTC_CHECK(response.resultClass == ResultDone);
Breakpoint bp = response.cookie.value<Breakpoint>();
BreakpointResponse br = bp.response(); BreakpointResponse br = bp.response();
br.threadSpec = bp.threadSpec(); br.threadSpec = bp.threadSpec();
bp.setResponse(br); bp.setResponse(br);
@@ -2659,10 +2628,9 @@ void GdbEngine::handleBreakThreadSpec(const DebuggerResponse &response)
insertBreakpoint(bp); insertBreakpoint(bp);
} }
void GdbEngine::handleBreakLineNumber(const DebuggerResponse &response) void GdbEngine::handleBreakLineNumber(const DebuggerResponse &response, Breakpoint bp)
{ {
QTC_CHECK(response.resultClass == ResultDone); QTC_CHECK(response.resultClass == ResultDone);
Breakpoint bp = response.cookie.value<Breakpoint>();
BreakpointResponse br = bp.response(); BreakpointResponse br = bp.response();
br.lineNumber = bp.lineNumber(); br.lineNumber = bp.lineNumber();
bp.setResponse(br); bp.setResponse(br);
@@ -2670,7 +2638,7 @@ void GdbEngine::handleBreakLineNumber(const DebuggerResponse &response)
insertBreakpoint(bp); insertBreakpoint(bp);
} }
void GdbEngine::handleBreakIgnore(const DebuggerResponse &response) void GdbEngine::handleBreakIgnore(const DebuggerResponse &response, Breakpoint bp)
{ {
// gdb 6.8: // gdb 6.8:
// ignore 2 0: // ignore 2 0:
@@ -2684,7 +2652,6 @@ void GdbEngine::handleBreakIgnore(const DebuggerResponse &response)
// gdb 6.3 does not produce any console output // gdb 6.3 does not produce any console output
QTC_CHECK(response.resultClass == ResultDone); QTC_CHECK(response.resultClass == ResultDone);
//QString msg = _(response.consoleStreamOutput); //QString msg = _(response.consoleStreamOutput);
Breakpoint bp = response.cookie.value<Breakpoint>();
BreakpointResponse br = bp.response(); BreakpointResponse br = bp.response();
//if (msg.contains(__("Will stop next time breakpoint"))) //if (msg.contains(__("Will stop next time breakpoint")))
// response.ignoreCount = _("0"); // response.ignoreCount = _("0");
@@ -2698,11 +2665,10 @@ void GdbEngine::handleBreakIgnore(const DebuggerResponse &response)
changeBreakpoint(bp); // Maybe there's more to do. changeBreakpoint(bp); // Maybe there's more to do.
} }
void GdbEngine::handleBreakCondition(const DebuggerResponse &response) void GdbEngine::handleBreakCondition(const DebuggerResponse &, Breakpoint bp)
{ {
// Can happen at invalid condition strings. // Can happen at invalid condition strings.
//QTC_CHECK(response.resultClass == ResultDone) //QTC_CHECK(response.resultClass == ResultDone)
Breakpoint bp = response.cookie.value<Breakpoint>();
// We just assume it was successful. Otherwise we had to parse // We just assume it was successful. Otherwise we had to parse
// the output stream data. // the output stream data.
// The following happens on Mac: // The following happens on Mac:
@@ -2747,7 +2713,6 @@ void GdbEngine::insertBreakpoint(Breakpoint bp)
bp.notifyBreakpointInsertProceeding(); bp.notifyBreakpointInsertProceeding();
const BreakpointParameters &data = bp.parameters(); const BreakpointParameters &data = bp.parameters();
QVariant vid = QVariant::fromValue(bp);
if (!data.isCppBreakpoint()) { if (!data.isCppBreakpoint()) {
DebuggerCommand cmd("insertQmlBreakpoint"); DebuggerCommand cmd("insertQmlBreakpoint");
@@ -2761,22 +2726,22 @@ void GdbEngine::insertBreakpoint(Breakpoint bp)
if (type == WatchpointAtAddress) { if (type == WatchpointAtAddress) {
postCommand("watch " + addressSpec(bp.address()), postCommand("watch " + addressSpec(bp.address()),
NeedsStop | RebuildBreakpointModel | ConsoleCommand, NeedsStop | RebuildBreakpointModel | ConsoleCommand,
CB(handleWatchInsert), vid); [this, bp](const DebuggerResponse &r) { handleWatchInsert(r, bp); });
return; return;
} }
if (type == WatchpointAtExpression) { if (type == WatchpointAtExpression) {
postCommand("watch " + bp.expression().toLocal8Bit(), postCommand("watch " + bp.expression().toLocal8Bit(),
NeedsStop | RebuildBreakpointModel | ConsoleCommand, NeedsStop | RebuildBreakpointModel | ConsoleCommand,
CB(handleWatchInsert), vid); [this, bp](const DebuggerResponse &r) { handleWatchInsert(r, bp); });
return; return;
} }
if (type == BreakpointAtFork) { if (type == BreakpointAtFork) {
postCommand("catch fork", postCommand("catch fork",
NeedsStop | RebuildBreakpointModel | ConsoleCommand, NeedsStop | RebuildBreakpointModel | ConsoleCommand,
CB(handleCatchInsert), vid); [this, bp](const DebuggerResponse &r) { handleCatchInsert(r, bp); });
postCommand("catch vfork", postCommand("catch vfork",
NeedsStop | RebuildBreakpointModel | ConsoleCommand, NeedsStop | RebuildBreakpointModel | ConsoleCommand,
CB(handleCatchInsert), vid); [this, bp](const DebuggerResponse &r) { handleCatchInsert(r, bp); });
return; return;
} }
//if (type == BreakpointAtVFork) { //if (type == BreakpointAtVFork) {
@@ -2787,13 +2752,13 @@ void GdbEngine::insertBreakpoint(Breakpoint bp)
if (type == BreakpointAtExec) { if (type == BreakpointAtExec) {
postCommand("catch exec", postCommand("catch exec",
NeedsStop | RebuildBreakpointModel | ConsoleCommand, NeedsStop | RebuildBreakpointModel | ConsoleCommand,
CB(handleCatchInsert), vid); [this, bp](const DebuggerResponse &r) { handleCatchInsert(r, bp); });
return; return;
} }
if (type == BreakpointAtSysCall) { if (type == BreakpointAtSysCall) {
postCommand("catch syscall", postCommand("catch syscall",
NeedsStop | RebuildBreakpointModel | ConsoleCommand, NeedsStop | RebuildBreakpointModel | ConsoleCommand,
CB(handleCatchInsert), vid); [this, bp](const DebuggerResponse &r) { handleCatchInsert(r, bp); });
return; return;
} }
@@ -2823,7 +2788,7 @@ void GdbEngine::insertBreakpoint(Breakpoint bp)
cmd += breakpointLocation(bp.parameters()); cmd += breakpointLocation(bp.parameters());
postCommand(cmd, NeedsStop | RebuildBreakpointModel, postCommand(cmd, NeedsStop | RebuildBreakpointModel,
CB(handleBreakInsert1), vid); [this, bp](const DebuggerResponse &r) { handleBreakInsert1(r, bp); });
} }
void GdbEngine::changeBreakpoint(Breakpoint bp) void GdbEngine::changeBreakpoint(Breakpoint bp)
@@ -2838,20 +2803,19 @@ void GdbEngine::changeBreakpoint(Breakpoint bp)
bp.notifyBreakpointChangeProceeding(); bp.notifyBreakpointChangeProceeding();
const BreakpointState state2 = bp.state(); const BreakpointState state2 = bp.state();
QTC_ASSERT(state2 == BreakpointChangeProceeding, qDebug() << state2); QTC_ASSERT(state2 == BreakpointChangeProceeding, qDebug() << state2);
QVariant vid = QVariant::fromValue(bp);
if (!response.pending && data.threadSpec != response.threadSpec) { if (!response.pending && data.threadSpec != response.threadSpec) {
// The only way to change this seems to be to re-set the bp completely. // The only way to change this seems to be to re-set the bp completely.
postCommand("-break-delete " + bpnr, postCommand("-break-delete " + bpnr,
NeedsStop | RebuildBreakpointModel, NeedsStop | RebuildBreakpointModel,
CB(handleBreakThreadSpec), vid); [this, bp](const DebuggerResponse &r) { handleBreakThreadSpec(r, bp); });
return; return;
} }
if (!response.pending && data.lineNumber != response.lineNumber) { if (!response.pending && data.lineNumber != response.lineNumber) {
// The only way to change this seems to be to re-set the bp completely. // The only way to change this seems to be to re-set the bp completely.
postCommand("-break-delete " + bpnr, postCommand("-break-delete " + bpnr,
NeedsStop | RebuildBreakpointModel, NeedsStop | RebuildBreakpointModel,
CB(handleBreakLineNumber), vid); [this, bp](const DebuggerResponse &r) { handleBreakLineNumber(r, bp); });
return; return;
} }
if (data.command != response.command) { if (data.command != response.command) {
@@ -2864,31 +2828,31 @@ void GdbEngine::changeBreakpoint(Breakpoint bp)
} }
} }
postCommand(breakCommand, NeedsStop | RebuildBreakpointModel, postCommand(breakCommand, NeedsStop | RebuildBreakpointModel,
CB(handleBreakIgnore), vid); [this, bp](const DebuggerResponse &r) { handleBreakIgnore(r, bp); });
return; return;
} }
if (!data.conditionsMatch(response.condition)) { if (!data.conditionsMatch(response.condition)) {
postCommand("condition " + bpnr + ' ' + data.condition, postCommand("condition " + bpnr + ' ' + data.condition,
NeedsStop | RebuildBreakpointModel, NeedsStop | RebuildBreakpointModel,
CB(handleBreakCondition), vid); [this, bp](const DebuggerResponse &r) { handleBreakCondition(r, bp); });
return; return;
} }
if (data.ignoreCount != response.ignoreCount) { if (data.ignoreCount != response.ignoreCount) {
postCommand("ignore " + bpnr + ' ' + QByteArray::number(data.ignoreCount), postCommand("ignore " + bpnr + ' ' + QByteArray::number(data.ignoreCount),
NeedsStop | RebuildBreakpointModel, NeedsStop | RebuildBreakpointModel,
CB(handleBreakIgnore), vid); [this, bp](const DebuggerResponse &r) { handleBreakIgnore(r, bp); });
return; return;
} }
if (!data.enabled && response.enabled) { if (!data.enabled && response.enabled) {
postCommand("-break-disable " + bpnr, postCommand("-break-disable " + bpnr,
NeedsStop | RebuildBreakpointModel, NeedsStop | RebuildBreakpointModel,
CB(handleBreakDisable), vid); [this, bp](const DebuggerResponse &r) { handleBreakDisable(r, bp); });
return; return;
} }
if (data.enabled && !response.enabled) { if (data.enabled && !response.enabled) {
postCommand("-break-enable " + bpnr, postCommand("-break-enable " + bpnr,
NeedsStop | RebuildBreakpointModel, NeedsStop | RebuildBreakpointModel,
CB(handleBreakEnable), vid); [this, bp](const DebuggerResponse &r) { handleBreakEnable(r, bp); });
return; return;
} }
bp.notifyBreakpointChangeOk(); bp.notifyBreakpointChangeOk();
@@ -2909,13 +2873,12 @@ void GdbEngine::removeBreakpoint(Breakpoint bp)
} }
if (br.id.isValid()) { if (br.id.isValid()) {
QVariant vid = QVariant::fromValue(bp);
// We already have a fully inserted breakpoint. // We already have a fully inserted breakpoint.
bp.notifyBreakpointRemoveProceeding(); bp.notifyBreakpointRemoveProceeding();
showMessage(_("DELETING BP %1 IN %2").arg(br.id.toString()).arg(bp.fileName())); showMessage(_("DELETING BP %1 IN %2").arg(br.id.toString()).arg(bp.fileName()));
postCommand("-break-delete " + br.id.toByteArray(), postCommand("-break-delete " + br.id.toByteArray(),
NeedsStop | RebuildBreakpointModel, NeedsStop | RebuildBreakpointModel,
CB(handleBreakDelete), vid); [this, bp](const DebuggerResponse &r) { handleBreakDelete(r, bp); });
} else { } else {
// Breakpoint was scheduled to be inserted, but we haven't had // Breakpoint was scheduled to be inserted, but we haven't had
// an answer so far. Postpone activity by doing nothing. // an answer so far. Postpone activity by doing nothing.
@@ -2934,7 +2897,7 @@ void GdbEngine::loadSymbols(const QString &modulePath)
// FIXME: gdb does not understand quoted names here (tested with 6.8) // FIXME: gdb does not understand quoted names here (tested with 6.8)
postCommand("sharedlibrary " + dotEscape(modulePath.toLocal8Bit())); postCommand("sharedlibrary " + dotEscape(modulePath.toLocal8Bit()));
reloadModulesInternal(); reloadModulesInternal();
reloadStack(true); reloadStack();
updateLocals(); updateLocals();
} }
@@ -2942,7 +2905,7 @@ void GdbEngine::loadAllSymbols()
{ {
postCommand("sharedlibrary .*"); postCommand("sharedlibrary .*");
reloadModulesInternal(); reloadModulesInternal();
reloadStack(true); reloadStack();
updateLocals(); updateLocals();
} }
@@ -2965,29 +2928,14 @@ void GdbEngine::loadSymbolsForStack()
} }
if (needUpdate) { if (needUpdate) {
//reloadModulesInternal(); //reloadModulesInternal();
reloadStack(true); reloadStack();
updateLocals(); updateLocals();
} }
} }
void GdbEngine::requestModuleSymbols(const QString &modulePath) static void handleShowModuleSymbols(const DebuggerResponse &response,
const QString &modulePath, const QString &fileName)
{ {
QTemporaryFile tf(QDir::tempPath() + _("/gdbsymbols"));
if (!tf.open())
return;
QString fileName = tf.fileName();
tf.close();
postCommand("maint print msymbols \"" + fileName.toLocal8Bit()
+ "\" " + modulePath.toLocal8Bit(),
NeedsStop, CB(handleShowModuleSymbols),
QVariant(modulePath + QLatin1Char('@') + fileName));
}
void GdbEngine::handleShowModuleSymbols(const DebuggerResponse &response)
{
const QString cookie = response.cookie.toString();
const QString modulePath = cookie.section(QLatin1Char('@'), 0, 0);
const QString fileName = cookie.section(QLatin1Char('@'), 1, 1);
if (response.resultClass == ResultDone) { if (response.resultClass == ResultDone) {
Symbols symbols; Symbols symbols;
QFile file(fileName); QFile file(fileName);
@@ -3039,24 +2987,38 @@ void GdbEngine::handleShowModuleSymbols(const DebuggerResponse &response)
file.remove(); file.remove();
Internal::showModuleSymbols(modulePath, symbols); Internal::showModuleSymbols(modulePath, symbols);
} else { } else {
AsynchronousMessageBox::critical(tr("Cannot Read Symbols"), AsynchronousMessageBox::critical(GdbEngine::tr("Cannot Read Symbols"),
tr("Cannot read symbols for module \"%1\".").arg(fileName)); GdbEngine::tr("Cannot read symbols for module \"%1\".").arg(fileName));
} }
} }
void GdbEngine::requestModuleSymbols(const QString &modulePath)
{
QTemporaryFile tf(QDir::tempPath() + _("/gdbsymbols"));
if (!tf.open())
return;
QString fileName = tf.fileName();
tf.close();
postCommand("maint print msymbols \"" + fileName.toLocal8Bit()
+ "\" " + modulePath.toLocal8Bit(), NeedsStop,
[modulePath, fileName](const DebuggerResponse &r) {
handleShowModuleSymbols(r, modulePath, fileName); });
}
void GdbEngine::requestModuleSections(const QString &moduleName) void GdbEngine::requestModuleSections(const QString &moduleName)
{ {
// There seems to be no way to get the symbols from a single .so. // There seems to be no way to get the symbols from a single .so.
postCommand("maint info section ALLOBJ", postCommand("maint info section ALLOBJ", NeedsStop,
NeedsStop, CB(handleShowModuleSections), moduleName); [this, moduleName](const DebuggerResponse &r) {
handleShowModuleSections(r, moduleName); });
} }
void GdbEngine::handleShowModuleSections(const DebuggerResponse &response) void GdbEngine::handleShowModuleSections(const DebuggerResponse &response,
const QString &moduleName)
{ {
// ~" Object file: /usr/lib/i386-linux-gnu/libffi.so.6\n" // ~" Object file: /usr/lib/i386-linux-gnu/libffi.so.6\n"
// ~" 0xb44a6114->0xb44a6138 at 0x00000114: .note.gnu.build-id ALLOC LOAD READONLY DATA HAS_CONTENTS\n" // ~" 0xb44a6114->0xb44a6138 at 0x00000114: .note.gnu.build-id ALLOC LOAD READONLY DATA HAS_CONTENTS\n"
if (response.resultClass == ResultDone) { if (response.resultClass == ResultDone) {
const QString moduleName = response.cookie.toString();
const QStringList lines = QString::fromLocal8Bit(response.consoleStreamOutput).split(QLatin1Char('\n')); const QStringList lines = QString::fromLocal8Bit(response.consoleStreamOutput).split(QLatin1Char('\n'));
const QString prefix = QLatin1String(" Object file: "); const QString prefix = QLatin1String(" Object file: ");
const QString needle = prefix + moduleName; const QString needle = prefix + moduleName;
@@ -3209,7 +3171,7 @@ void GdbEngine::handleStackSelectThread(const DebuggerResponse &)
{ {
QTC_CHECK(state() == InferiorUnrunnable || state() == InferiorStopOk); QTC_CHECK(state() == InferiorUnrunnable || state() == InferiorStopOk);
showStatusMessage(tr("Retrieving data for stack view..."), 3000); showStatusMessage(tr("Retrieving data for stack view..."), 3000);
reloadStack(true); // Will reload registers. reloadStack(); // Will reload registers.
updateLocals(); updateLocals();
} }
@@ -3217,8 +3179,8 @@ void GdbEngine::reloadFullStack()
{ {
PENDING_DEBUG("RELOAD FULL STACK"); PENDING_DEBUG("RELOAD FULL STACK");
resetLocation(); resetLocation();
postCommand(stackCommand(-1), Discardable, CB(handleStackListFrames), postCommand(stackCommand(-1), Discardable,
QVariant::fromValue<StackCookie>(StackCookie(true, true))); [this](const DebuggerResponse &r) { handleStackListFrames(r, true); });
} }
void GdbEngine::loadAdditionalQmlStack() void GdbEngine::loadAdditionalQmlStack()
@@ -3270,7 +3232,7 @@ void GdbEngine::handleQmlStackFrameArguments(const DebuggerResponse &response)
QByteArray command = "-data-evaluate-expression \"qt_v4StackTrace((QV4::ExecutionContext *)0x"; QByteArray command = "-data-evaluate-expression \"qt_v4StackTrace((QV4::ExecutionContext *)0x";
command += QByteArray::number(contextAddress, 16); command += QByteArray::number(contextAddress, 16);
command += ")\""; command += ")\"";
postCommand(command, CB(handleQmlStackTrace)); postCommand(command, NoFlags, CB(handleQmlStackTrace));
} }
void GdbEngine::handleQmlStackTrace(const DebuggerResponse &response) void GdbEngine::handleQmlStackTrace(const DebuggerResponse &response)
@@ -3323,12 +3285,12 @@ QByteArray GdbEngine::stackCommand(int depth)
return cmd; return cmd;
} }
void GdbEngine::reloadStack(bool forceGotoLocation) void GdbEngine::reloadStack()
{ {
PENDING_DEBUG("RELOAD STACK"); PENDING_DEBUG("RELOAD STACK");
int depth = action(MaximalStackDepth)->value().toInt(); int depth = action(MaximalStackDepth)->value().toInt();
postCommand(stackCommand(depth), Discardable, CB(handleStackListFrames), postCommand(stackCommand(depth), Discardable,
QVariant::fromValue<StackCookie>(StackCookie(false, forceGotoLocation))); [this](const DebuggerResponse &r) { handleStackListFrames(r, false); });
} }
StackFrame GdbEngine::parseStackFrame(const GdbMi &frameMi, int level) StackFrame GdbEngine::parseStackFrame(const GdbMi &frameMi, int level)
@@ -3360,7 +3322,7 @@ StackFrame GdbEngine::parseStackFrame(const GdbMi &frameMi, int level)
return frame; return frame;
} }
void GdbEngine::handleStackListFrames(const DebuggerResponse &response) void GdbEngine::handleStackListFrames(const DebuggerResponse &response, bool isFull)
{ {
if (response.resultClass != ResultDone) { if (response.resultClass != ResultDone) {
// That always happens on symbian gdb with // That always happens on symbian gdb with
@@ -3371,7 +3333,6 @@ void GdbEngine::handleStackListFrames(const DebuggerResponse &response)
return; return;
} }
StackCookie cookie = response.cookie.value<StackCookie>();
QList<StackFrame> stackFrames; QList<StackFrame> stackFrames;
GdbMi stack = response.data["stack"]; // C++ GdbMi stack = response.data["stack"]; // C++
@@ -3396,8 +3357,7 @@ void GdbEngine::handleStackListFrames(const DebuggerResponse &response)
targetFrame = i; targetFrame = i;
} }
bool canExpand = !cookie.isFull bool canExpand = !isFull && (n >= action(MaximalStackDepth)->value().toInt());
&& (n >= action(MaximalStackDepth)->value().toInt());
action(ExpandStack)->setEnabled(canExpand); action(ExpandStack)->setEnabled(canExpand);
stackHandler()->setFrames(stackFrames, canExpand); stackHandler()->setFrames(stackFrames, canExpand);
@@ -3470,7 +3430,7 @@ void GdbEngine::handleThreadInfo(const DebuggerResponse &response)
action(MaximalStackDepth)->value().toByteArray(), action(MaximalStackDepth)->value().toByteArray(),
Discardable, CB(handleThreadNames)); Discardable, CB(handleThreadNames));
} }
reloadStack(false); // Will trigger register reload. reloadStack(); // Will trigger register reload.
} else { } else {
// Fall back for older versions: Try to get at least a list // Fall back for older versions: Try to get at least a list
// of running threads. // of running threads.
@@ -3489,7 +3449,7 @@ void GdbEngine::handleThreadListIds(const DebuggerResponse &response)
thread.id = ThreadId(items.at(index).toInt()); thread.id = ThreadId(items.at(index).toInt());
handler->updateThread(thread); handler->updateThread(thread);
} }
reloadStack(false); // Will trigger register reload. reloadStack(); // Will trigger register reload.
} }
void GdbEngine::handleThreadNames(const DebuggerResponse &response) void GdbEngine::handleThreadNames(const DebuggerResponse &response)
@@ -3524,20 +3484,20 @@ void GdbEngine::createSnapshot()
fileName = tf.fileName(); fileName = tf.fileName();
tf.close(); tf.close();
// This must not be quoted, it doesn't work otherwise. // This must not be quoted, it doesn't work otherwise.
postCommand("gcore " + fileName.toLocal8Bit(), postCommand("gcore " + fileName.toLocal8Bit(), NeedsStop|ConsoleCommand,
NeedsStop|ConsoleCommand, CB(handleMakeSnapshot), fileName); [this, fileName](const DebuggerResponse &r) { handleMakeSnapshot(r, fileName); });
} else { } else {
AsynchronousMessageBox::critical(tr("Snapshot Creation Error"), AsynchronousMessageBox::critical(tr("Snapshot Creation Error"),
tr("Cannot create snapshot file.")); tr("Cannot create snapshot file."));
} }
} }
void GdbEngine::handleMakeSnapshot(const DebuggerResponse &response) void GdbEngine::handleMakeSnapshot(const DebuggerResponse &response, const QString &coreFile)
{ {
if (response.resultClass == ResultDone) { if (response.resultClass == ResultDone) {
DebuggerStartParameters sp = startParameters(); DebuggerStartParameters sp = startParameters();
sp.startMode = AttachCore; sp.startMode = AttachCore;
sp.coreFile = response.cookie.toString(); sp.coreFile = coreFile;
//snapshot.setDate(QDateTime::currentDateTime()); //snapshot.setDate(QDateTime::currentDateTime());
StackFrames frames = stackHandler()->frames(); StackFrames frames = stackHandler()->frames();
QString function = _("<unknown>"); QString function = _("<unknown>");
@@ -3572,7 +3532,7 @@ void GdbEngine::reloadRegisters()
if (true) { if (true) {
if (!m_registerNamesListed) { if (!m_registerNamesListed) {
postCommand("-data-list-register-names", CB(handleRegisterListNames)); postCommand("-data-list-register-names", NoFlags, CB(handleRegisterListNames));
m_registerNamesListed = true; m_registerNamesListed = true;
} }
// Can cause i386-linux-nat.c:571: internal-error: Got request // Can cause i386-linux-nat.c:571: internal-error: Got request
@@ -3580,7 +3540,7 @@ void GdbEngine::reloadRegisters()
postCommand("-data-list-register-values r", postCommand("-data-list-register-values r",
Discardable, CB(handleRegisterListValues)); Discardable, CB(handleRegisterListValues));
} else { } else {
postCommand("maintenance print cooked-registers", CB(handleMaintPrintRegisters)); postCommand("maintenance print cooked-registers", NoFlags, CB(handleMaintPrintRegisters));
} }
} }
@@ -3906,7 +3866,7 @@ void GdbEngine::changeMemory(MemoryAgent *agent, QObject *token,
ac.token = token; ac.token = token;
ac.base = addr; ac.base = addr;
ac.length = data.size(); ac.length = data.size();
postCommand(cmd, NeedsStop, CB(handleChangeMemory), QVariant::fromValue(ac)); postCommand(cmd, NeedsStop, CB(handleChangeMemory));
} }
void GdbEngine::handleChangeMemory(const DebuggerResponse &response) void GdbEngine::handleChangeMemory(const DebuggerResponse &response)
@@ -3930,17 +3890,16 @@ void GdbEngine::fetchMemory(MemoryAgent *agent, QObject *token, quint64 addr,
void GdbEngine::fetchMemoryHelper(const MemoryAgentCookie &ac) void GdbEngine::fetchMemoryHelper(const MemoryAgentCookie &ac)
{ {
postCommand("-data-read-memory 0x" + QByteArray::number(ac.base + ac.offset, 16) + " x 1 1 " postCommand("-data-read-memory 0x" + QByteArray::number(ac.base + ac.offset, 16) + " x 1 1 "
+ QByteArray::number(ac.length), + QByteArray::number(ac.length), NeedsStop,
NeedsStop, CB(handleFetchMemory), QVariant::fromValue(ac)); [this, ac](const DebuggerResponse &r) { handleFetchMemory(r, ac); });
} }
void GdbEngine::handleFetchMemory(const DebuggerResponse &response) void GdbEngine::handleFetchMemory(const DebuggerResponse &response, MemoryAgentCookie ac)
{ {
// ^done,addr="0x08910c88",nr-bytes="16",total-bytes="16", // ^done,addr="0x08910c88",nr-bytes="16",total-bytes="16",
// next-row="0x08910c98",prev-row="0x08910c78",next-page="0x08910c98", // next-row="0x08910c98",prev-row="0x08910c78",next-page="0x08910c98",
// prev-page="0x08910c78",memory=[{addr="0x08910c88", // prev-page="0x08910c78",memory=[{addr="0x08910c88",
// data=["1","0","0","0","5","0","0","0","0","0","0","0","0","0","0","0"]}] // data=["1","0","0","0","5","0","0","0","0","0","0","0","0","0","0","0"]}]
MemoryAgentCookie ac = response.cookie.value<MemoryAgentCookie>();
--*ac.pendingRequests; --*ac.pendingRequests;
showMessage(QString::fromLatin1("PENDING: %1").arg(*ac.pendingRequests)); showMessage(QString::fromLatin1("PENDING: %1").arg(*ac.pendingRequests));
QTC_ASSERT(ac.agent, return); QTC_ASSERT(ac.agent, return);
@@ -4020,25 +3979,34 @@ static inline QByteArray disassemblerCommand(const Location &location, bool mixe
return command; return command;
} }
void GdbEngine::fetchDisassemblerByCliPointMixed(const DisassemblerAgentCookie &ac0) void GdbEngine::fetchDisassemblerByCliPointMixed(const DisassemblerAgentCookie &ac)
{ {
DisassemblerAgentCookie ac = ac0;
QTC_ASSERT(ac.agent, return); QTC_ASSERT(ac.agent, return);
postCommand(disassemblerCommand(ac.agent->location(), true), Discardable|ConsoleCommand, postCommand(disassemblerCommand(ac.agent->location(), true), Discardable|ConsoleCommand,
CB(handleFetchDisassemblerByCliPointMixed), [this, ac](const DebuggerResponse &response) {
QVariant::fromValue(ac)); if (response.resultClass == ResultDone)
if (handleCliDisassemblerResult(response.consoleStreamOutput, ac.agent))
return;
// 'point, plain' can take far too long.
// Skip this feature and immediately fall back to the 'range' version:
fetchDisassemblerByCliRangeMixed(ac);
});
} }
void GdbEngine::fetchDisassemblerByCliRangeMixed(const DisassemblerAgentCookie &ac0) void GdbEngine::fetchDisassemblerByCliRangeMixed(const DisassemblerAgentCookie &ac)
{ {
DisassemblerAgentCookie ac = ac0;
QTC_ASSERT(ac.agent, return); QTC_ASSERT(ac.agent, return);
const quint64 address = ac.agent->address(); const quint64 address = ac.agent->address();
QByteArray start = QByteArray::number(address - 20, 16); QByteArray start = QByteArray::number(address - 20, 16);
QByteArray end = QByteArray::number(address + 100, 16); QByteArray end = QByteArray::number(address + 100, 16);
QByteArray cmd = "disassemble /rm 0x" + start + ",0x" + end; QByteArray cmd = "disassemble /rm 0x" + start + ",0x" + end;
postCommand(cmd, Discardable|ConsoleCommand, postCommand(cmd, Discardable|ConsoleCommand,
CB(handleFetchDisassemblerByCliRangeMixed), QVariant::fromValue(ac)); [this, ac](const DebuggerResponse &response) {
if (response.resultClass == ResultDone)
if (handleCliDisassemblerResult(response.consoleStreamOutput, ac.agent))
return;
fetchDisassemblerByCliRangePlain(ac);
});
} }
@@ -4051,7 +4019,18 @@ void GdbEngine::fetchDisassemblerByCliRangePlain(const DisassemblerAgentCookie &
QByteArray end = QByteArray::number(address + 100, 16); QByteArray end = QByteArray::number(address + 100, 16);
QByteArray cmd = "disassemble /r 0x" + start + ",0x" + end; QByteArray cmd = "disassemble /r 0x" + start + ",0x" + end;
postCommand(cmd, Discardable, postCommand(cmd, Discardable,
CB(handleFetchDisassemblerByCliRangePlain), QVariant::fromValue(ac)); [this, ac](const DebuggerResponse &response) {
if (response.resultClass == ResultDone)
if (handleCliDisassemblerResult(response.consoleStreamOutput, ac.agent))
return;
// Finally, give up.
//76^error,msg="No function contains program counter for selected..."
//76^error,msg="No function contains specified address."
//>568^error,msg="Line number 0 out of range;
QByteArray msg = response.data["msg"].data();
showStatusMessage(tr("Disassembler failed: %1")
.arg(QString::fromLocal8Bit(msg)), 5000);
});
} }
struct LineData struct LineData
@@ -4064,6 +4043,7 @@ struct LineData
bool GdbEngine::handleCliDisassemblerResult(const QByteArray &output, DisassemblerAgent *agent) bool GdbEngine::handleCliDisassemblerResult(const QByteArray &output, DisassemblerAgent *agent)
{ {
QTC_ASSERT(agent, return true);
// First line is something like // First line is something like
// "Dump of assembler code from 0xb7ff598f to 0xb7ff5a07:" // "Dump of assembler code from 0xb7ff598f to 0xb7ff5a07:"
DisassemblerLines dlines; DisassemblerLines dlines;
@@ -4107,50 +4087,6 @@ bool GdbEngine::handleCliDisassemblerResult(const QByteArray &output, Disassembl
return false; return false;
} }
void GdbEngine::handleFetchDisassemblerByCliPointMixed(const DebuggerResponse &response)
{
DisassemblerAgentCookie ac = response.cookie.value<DisassemblerAgentCookie>();
QTC_ASSERT(ac.agent, return);
if (response.resultClass == ResultDone)
if (handleCliDisassemblerResult(response.consoleStreamOutput, ac.agent))
return;
// 'point, plain' can take far too long.
// Skip this feature and immediately fall back to the 'range' version:
fetchDisassemblerByCliRangeMixed(ac);
}
void GdbEngine::handleFetchDisassemblerByCliRangeMixed(const DebuggerResponse &response)
{
DisassemblerAgentCookie ac = response.cookie.value<DisassemblerAgentCookie>();
QTC_ASSERT(ac.agent, return);
if (response.resultClass == ResultDone)
if (handleCliDisassemblerResult(response.consoleStreamOutput, ac.agent))
return;
fetchDisassemblerByCliRangePlain(ac);
}
void GdbEngine::handleFetchDisassemblerByCliRangePlain(const DebuggerResponse &response)
{
DisassemblerAgentCookie ac = response.cookie.value<DisassemblerAgentCookie>();
QTC_ASSERT(ac.agent, return);
if (response.resultClass == ResultDone)
if (handleCliDisassemblerResult(response.consoleStreamOutput, ac.agent))
return;
// Finally, give up.
//76^error,msg="No function contains program counter for selected..."
//76^error,msg="No function contains specified address."
//>568^error,msg="Line number 0 out of range;
QByteArray msg = response.data["msg"].data();
showStatusMessage(tr("Disassembler failed: %1")
.arg(QString::fromLocal8Bit(msg)), 5000);
}
// Binary/configuration check logic. // Binary/configuration check logic.
static QString gdbBinary(const DebuggerStartParameters &sp) static QString gdbBinary(const DebuggerStartParameters &sp)
@@ -4219,9 +4155,9 @@ void GdbEngine::startGdb(const QStringList &args)
} }
showMessage(_("GDB STARTED, INITIALIZING IT")); showMessage(_("GDB STARTED, INITIALIZING IT"));
postCommand("show version", CB(handleShowVersion)); postCommand("show version", NoFlags, CB(handleShowVersion));
//postCommand("-list-features", CB(handleListFeatures)); //postCommand("-list-features", CB(handleListFeatures));
postCommand("show debug-file-directory", CB(handleDebugInfoLocation)); postCommand("show debug-file-directory", NoFlags, CB(handleDebugInfoLocation));
//postCommand("-enable-timings"); //postCommand("-enable-timings");
//postCommand("set print static-members off"); // Seemingly doesn't work. //postCommand("set print static-members off"); // Seemingly doesn't work.
@@ -4562,10 +4498,10 @@ void GdbEngine::finishInferiorSetup()
postCommand("-break-insert -f '" + qtNamespace() + "QMessageLogger::warning'"); postCommand("-break-insert -f '" + qtNamespace() + "QMessageLogger::warning'");
} }
if (boolSetting(BreakOnFatal)) { if (boolSetting(BreakOnFatal)) {
postCommand("-break-insert -f '" + qtNamespace() + "qFatal'", postCommand("-break-insert -f '" + qtNamespace() + "qFatal'", NoFlags,
CB(handleBreakOnQFatal), QVariant(false)); [this](const DebuggerResponse &r) { handleBreakOnQFatal(r, false); });
postCommand("-break-insert -f '" + qtNamespace() + "QMessageLogger::fatal'", postCommand("-break-insert -f '" + qtNamespace() + "QMessageLogger::fatal'", NoFlags,
CB(handleBreakOnQFatal), QVariant(true)); [this](const DebuggerResponse &r) { handleBreakOnQFatal(r, true); });
} else { } else {
notifyInferiorSetupOk(); notifyInferiorSetupOk();
} }
@@ -4589,7 +4525,7 @@ void GdbEngine::handleDebugInfoLocation(const DebuggerResponse &response)
} }
} }
void GdbEngine::handleBreakOnQFatal(const DebuggerResponse &response) void GdbEngine::handleBreakOnQFatal(const DebuggerResponse &response, bool continueSetup)
{ {
if (response.resultClass == ResultDone) { if (response.resultClass == ResultDone) {
GdbMi bkpt = response.data["bkpt"]; GdbMi bkpt = response.data["bkpt"];
@@ -4602,7 +4538,7 @@ void GdbEngine::handleBreakOnQFatal(const DebuggerResponse &response)
} }
// Continue setup. // Continue setup.
if (response.cookie.toBool()) if (continueSetup)
notifyInferiorSetupOk(); notifyInferiorSetupOk();
} }
@@ -4901,13 +4837,13 @@ void GdbEngine::updateLocalsPython(const UpdateParameters &params)
postCommand("bb options:" + options + " vars:" + params.varList + ' ' postCommand("bb options:" + options + " vars:" + params.varList + ' '
+ resultVar + expanded + " watchers:" + watchers.toHex() + cutOff + context, + resultVar + expanded + " watchers:" + watchers.toHex() + cutOff + context,
Discardable, CB(handleStackFramePython), QVariant(params.tryPartial)); Discardable,
[this, params](const DebuggerResponse &r) { handleStackFramePython(r, params.tryPartial); });
} }
void GdbEngine::handleStackFramePython(const DebuggerResponse &response) void GdbEngine::handleStackFramePython(const DebuggerResponse &response, bool partial)
{ {
if (response.resultClass == ResultDone) { if (response.resultClass == ResultDone) {
const bool partial = response.cookie.toBool();
QByteArray out = response.consoleStreamOutput; QByteArray out = response.consoleStreamOutput;
while (out.endsWith(' ') || out.endsWith('\n')) while (out.endsWith(' ') || out.endsWith('\n'))
out.chop(1); out.chop(1);
@@ -4995,10 +4931,7 @@ QString GdbEngine::msgPtraceError(DebuggerStartMode sm)
"For more details, see /etc/sysctl.d/10-ptrace.conf\n"); "For more details, see /etc/sysctl.d/10-ptrace.conf\n");
} }
} // namespace Internal } // namespace Internal
} // namespace Debugger } // namespace Debugger
Q_DECLARE_METATYPE(Debugger::Internal::MemoryAgentCookie)
Q_DECLARE_METATYPE(Debugger::Internal::DisassemblerAgentCookie)
Q_DECLARE_METATYPE(Debugger::Internal::GdbMi) Q_DECLARE_METATYPE(Debugger::Internal::GdbMi)

View File

@@ -185,7 +185,6 @@ private: ////////// Gdb Command Management //////////
int flags; int flags;
GdbCommandCallback callback; GdbCommandCallback callback;
QByteArray command; QByteArray command;
QVariant cookie;
QTime postTime; QTime postTime;
}; };
@@ -197,14 +196,9 @@ private: ////////// Gdb Command Management //////////
protected: protected:
void runCommand(const DebuggerCommand &command); void runCommand(const DebuggerCommand &command);
void postCommand(const QByteArray &command, void postCommand(const QByteArray &command,
GdbCommandFlags flags, GdbCommandFlags flags = NoFlags,
GdbCommandCallback callback = 0, GdbCommandCallback callback = GdbCommandCallback());
const QVariant &cookie = QVariant());
void postCommand(const QByteArray &command,
GdbCommandCallback callback = 0,
const QVariant &cookie = QVariant());
private: private:
void postCommandHelper(const GdbCommand &cmd);
void flushQueuedCommands(); void flushQueuedCommands();
Q_SLOT void commandTimeout(); Q_SLOT void commandTimeout();
void setTokenBarrier(); void setTokenBarrier();
@@ -238,9 +232,7 @@ protected:
Q_SLOT void handleResponse(const QByteArray &buff); Q_SLOT void handleResponse(const QByteArray &buff);
void handleStopResponse(const GdbMi &data); void handleStopResponse(const GdbMi &data);
void handleResultRecord(DebuggerResponse *response); void handleResultRecord(DebuggerResponse *response);
void handleStop1(const DebuggerResponse &response);
void handleStop1(const GdbMi &data); void handleStop1(const GdbMi &data);
void handleStop2(const DebuggerResponse &response);
void handleStop2(const GdbMi &data); void handleStop2(const GdbMi &data);
Q_SLOT void handleStop2(); Q_SLOT void handleStop2();
StackFrame parseStackFrame(const GdbMi &mi, int level); StackFrame parseStackFrame(const GdbMi &mi, int level);
@@ -304,18 +296,17 @@ private: ////////// View & Data Stuff //////////
// Breakpoint specific stuff // Breakpoint specific stuff
// //
void handleBreakModifications(const GdbMi &bkpts); void handleBreakModifications(const GdbMi &bkpts);
void handleBreakIgnore(const DebuggerResponse &response); void handleBreakIgnore(const DebuggerResponse &response, Breakpoint bp);
void handleBreakDisable(const DebuggerResponse &response); void handleBreakDisable(const DebuggerResponse &response, Breakpoint bp);
void handleBreakEnable(const DebuggerResponse &response); void handleBreakEnable(const DebuggerResponse &response, Breakpoint bp);
void handleBreakInsert1(const DebuggerResponse &response); void handleBreakInsert1(const DebuggerResponse &response, Breakpoint bp);
void handleBreakInsert2(const DebuggerResponse &response); void handleBreakInsert2(const DebuggerResponse &response, Breakpoint bp);
void handleBreakDelete(const DebuggerResponse &response); void handleBreakDelete(const DebuggerResponse &response, Breakpoint bp);
void handleTraceInsert2(const DebuggerResponse &response); void handleBreakCondition(const DebuggerResponse &response, Breakpoint bp);
void handleBreakCondition(const DebuggerResponse &response); void handleBreakThreadSpec(const DebuggerResponse &response, Breakpoint bp);
void handleBreakThreadSpec(const DebuggerResponse &response); void handleBreakLineNumber(const DebuggerResponse &response, Breakpoint bp);
void handleBreakLineNumber(const DebuggerResponse &response); void handleWatchInsert(const DebuggerResponse &response, Breakpoint bp);
void handleWatchInsert(const DebuggerResponse &response); void handleCatchInsert(const DebuggerResponse &response, Breakpoint bp);
void handleCatchInsert(const DebuggerResponse &response);
void handleBkpt(const GdbMi &bkpt, Breakpoint bp); void handleBkpt(const GdbMi &bkpt, Breakpoint bp);
void updateResponse(BreakpointResponse &response, const GdbMi &bkpt); void updateResponse(BreakpointResponse &response, const GdbMi &bkpt);
QByteArray breakpointLocation(const BreakpointParameters &data); // For gdb/MI. QByteArray breakpointLocation(const BreakpointParameters &data); // For gdb/MI.
@@ -336,14 +327,13 @@ private: ////////// View & Data Stuff //////////
void reloadModulesInternal(); void reloadModulesInternal();
void handleModulesList(const DebuggerResponse &response); void handleModulesList(const DebuggerResponse &response);
void handleShowModuleSymbols(const DebuggerResponse &response); void handleShowModuleSections(const DebuggerResponse &response, const QString &moduleName);
void handleShowModuleSections(const DebuggerResponse &response);
// //
// Snapshot specific stuff // Snapshot specific stuff
// //
virtual void createSnapshot(); virtual void createSnapshot();
void handleMakeSnapshot(const DebuggerResponse &response); void handleMakeSnapshot(const DebuggerResponse &response, const QString &coreFile);
// //
// Register specific stuff // Register specific stuff
@@ -363,12 +353,9 @@ private: ////////// View & Data Stuff //////////
void fetchDisassemblerByCliPointMixed(const DisassemblerAgentCookie &ac); void fetchDisassemblerByCliPointMixed(const DisassemblerAgentCookie &ac);
void fetchDisassemblerByCliRangeMixed(const DisassemblerAgentCookie &ac); void fetchDisassemblerByCliRangeMixed(const DisassemblerAgentCookie &ac);
void fetchDisassemblerByCliRangePlain(const DisassemblerAgentCookie &ac); void fetchDisassemblerByCliRangePlain(const DisassemblerAgentCookie &ac);
void handleFetchDisassemblerByCliPointMixed(const DebuggerResponse &response);
void handleFetchDisassemblerByCliRangeMixed(const DebuggerResponse &response);
void handleFetchDisassemblerByCliRangePlain(const DebuggerResponse &response);
bool handleCliDisassemblerResult(const QByteArray &response, DisassemblerAgent *agent); bool handleCliDisassemblerResult(const QByteArray &response, DisassemblerAgent *agent);
void handleBreakOnQFatal(const DebuggerResponse &response); void handleBreakOnQFatal(const DebuggerResponse &response, bool continueSetup);
// //
// Source file specific stuff // Source file specific stuff
@@ -392,13 +379,13 @@ private: ////////// View & Data Stuff //////////
// //
protected: protected:
void updateAll(); void updateAll();
void handleStackListFrames(const DebuggerResponse &response); void handleStackListFrames(const DebuggerResponse &response, bool isFull);
void handleStackSelectThread(const DebuggerResponse &response); void handleStackSelectThread(const DebuggerResponse &response);
void handleThreadListIds(const DebuggerResponse &response); void handleThreadListIds(const DebuggerResponse &response);
void handleThreadInfo(const DebuggerResponse &response); void handleThreadInfo(const DebuggerResponse &response);
void handleThreadNames(const DebuggerResponse &response); void handleThreadNames(const DebuggerResponse &response);
QByteArray stackCommand(int depth); QByteArray stackCommand(int depth);
Q_SLOT void reloadStack(bool forceGotoLocation); Q_SLOT void reloadStack();
Q_SLOT virtual void reloadFullStack(); Q_SLOT virtual void reloadFullStack();
virtual void loadAdditionalQmlStack(); virtual void loadAdditionalQmlStack();
void handleQmlStackFrameArguments(const DebuggerResponse &response); void handleQmlStackFrameArguments(const DebuggerResponse &response);
@@ -421,7 +408,7 @@ protected:
void handleChangeMemory(const DebuggerResponse &response); void handleChangeMemory(const DebuggerResponse &response);
virtual void changeMemory(MemoryAgent *agent, QObject *token, virtual void changeMemory(MemoryAgent *agent, QObject *token,
quint64 addr, const QByteArray &data); quint64 addr, const QByteArray &data);
void handleFetchMemory(const DebuggerResponse &response); void handleFetchMemory(const DebuggerResponse &response, MemoryAgentCookie ac);
virtual void watchPoint(const QPoint &); virtual void watchPoint(const QPoint &);
void handleWatchPoint(const DebuggerResponse &response); void handleWatchPoint(const DebuggerResponse &response);
@@ -442,7 +429,7 @@ protected:
void updateLocals(); void updateLocals();
void updateLocalsPython(const UpdateParameters &parameters); void updateLocalsPython(const UpdateParameters &parameters);
void handleStackFramePython(const DebuggerResponse &response); void handleStackFramePython(const DebuggerResponse &response, bool partial);
void setLocals(const QList<GdbMi> &locals); void setLocals(const QList<GdbMi> &locals);

View File

@@ -45,7 +45,7 @@
namespace Debugger { namespace Debugger {
namespace Internal { namespace Internal {
#define CB(callback) [this](const DebuggerResponse &r) { callback(r); }, STRINGIFY(callback) #define CB(callback) [this](const DebuggerResponse &r) { callback(r); }
GdbPlainEngine::GdbPlainEngine(const DebuggerStartParameters &startParameters) GdbPlainEngine::GdbPlainEngine(const DebuggerStartParameters &startParameters)
: GdbEngine(startParameters) : GdbEngine(startParameters)
@@ -63,7 +63,7 @@ void GdbPlainEngine::setupInferior()
postCommand("-exec-arguments " + toLocalEncoding(args)); postCommand("-exec-arguments " + toLocalEncoding(args));
} }
postCommand("-file-exec-and-symbols \"" + execFilePath() + '"', postCommand("-file-exec-and-symbols \"" + execFilePath() + '"',
CB(handleFileExecAndSymbols)); NoFlags, CB(handleFileExecAndSymbols));
} }
void GdbPlainEngine::handleFileExecAndSymbols(const DebuggerResponse &response) void GdbPlainEngine::handleFileExecAndSymbols(const DebuggerResponse &response)

View File

@@ -204,7 +204,7 @@ void GdbRemoteServerEngine::setupInferior()
// mi_execute_async_cli_command: Assertion `is_running (inferior_ptid)' // mi_execute_async_cli_command: Assertion `is_running (inferior_ptid)'
// failed.\nA problem internal to GDB has been detected,[...] // failed.\nA problem internal to GDB has been detected,[...]
if (boolSetting(TargetAsync)) if (boolSetting(TargetAsync))
postCommand("set target-async on", CB(handleSetTargetAsync)); postCommand("set target-async on", NoFlags, CB(handleSetTargetAsync));
if (executableFileName.isEmpty()) { if (executableFileName.isEmpty()) {
showMessage(tr("No symbol file given."), StatusBar); showMessage(tr("No symbol file given."), StatusBar);
@@ -214,7 +214,7 @@ void GdbRemoteServerEngine::setupInferior()
if (!executableFileName.isEmpty()) { if (!executableFileName.isEmpty()) {
postCommand("-file-exec-and-symbols \"" + executableFileName.toLocal8Bit() + '"', postCommand("-file-exec-and-symbols \"" + executableFileName.toLocal8Bit() + '"',
CB(handleFileExecAndSymbols)); NoFlags, CB(handleFileExecAndSymbols));
} }
} }
@@ -264,11 +264,11 @@ void GdbRemoteServerEngine::callTargetRemote()
} }
if (m_isQnxGdb) if (m_isQnxGdb)
postCommand("target qnx " + channel, CB(handleTargetQnx)); postCommand("target qnx " + channel, NoFlags, CB(handleTargetQnx));
else if (startParameters().multiProcess) else if (startParameters().multiProcess)
postCommand("target extended-remote " + channel, CB(handleTargetExtendedRemote)); postCommand("target extended-remote " + channel, NoFlags, CB(handleTargetExtendedRemote));
else else
postCommand("target remote " + channel, CB(handleTargetRemote), 10); postCommand("target remote " + channel, NoFlags, CB(handleTargetRemote));
} }
void GdbRemoteServerEngine::handleTargetRemote(const DebuggerResponse &response) void GdbRemoteServerEngine::handleTargetRemote(const DebuggerResponse &response)
@@ -306,10 +306,10 @@ void GdbRemoteServerEngine::handleTargetExtendedRemote(const DebuggerResponse &r
if (startParameters().attachPID > 0) { // attach to pid if valid if (startParameters().attachPID > 0) { // attach to pid if valid
// gdb server will stop the remote application itself. // gdb server will stop the remote application itself.
postCommand("attach " + QByteArray::number(startParameters().attachPID), postCommand("attach " + QByteArray::number(startParameters().attachPID),
CB(handleTargetExtendedAttach)); NoFlags, CB(handleTargetExtendedAttach));
} else { } else {
postCommand("-gdb-set remote exec-file " + startParameters().remoteExecutable.toLatin1(), postCommand("-gdb-set remote exec-file " + startParameters().remoteExecutable.toLatin1(),
CB(handleTargetExtendedAttach)); NoFlags, CB(handleTargetExtendedAttach));
} }
} else { } else {
QString msg = msgConnectRemoteServerFailed( QString msg = msgConnectRemoteServerFailed(
@@ -343,9 +343,9 @@ void GdbRemoteServerEngine::handleTargetQnx(const DebuggerResponse &response)
const qint64 pid = isMasterEngine() ? startParameters().attachPID : masterEngine()->startParameters().attachPID; const qint64 pid = isMasterEngine() ? startParameters().attachPID : masterEngine()->startParameters().attachPID;
const QString remoteExecutable = isMasterEngine() ? startParameters().remoteExecutable : masterEngine()->startParameters().remoteExecutable; const QString remoteExecutable = isMasterEngine() ? startParameters().remoteExecutable : masterEngine()->startParameters().remoteExecutable;
if (pid > -1) if (pid > -1)
postCommand("attach " + QByteArray::number(pid), CB(handleAttach)); postCommand("attach " + QByteArray::number(pid), NoFlags, CB(handleAttach));
else if (!remoteExecutable.isEmpty()) else if (!remoteExecutable.isEmpty())
postCommand("set nto-executable " + remoteExecutable.toLatin1(), CB(handleSetNtoExecutable)); postCommand("set nto-executable " + remoteExecutable.toLatin1(), NoFlags, CB(handleSetNtoExecutable));
else else
handleInferiorPrepared(); handleInferiorPrepared();
} else { } else {

View File

@@ -46,8 +46,6 @@ using namespace Utils;
namespace Debugger { namespace Debugger {
namespace Internal { namespace Internal {
#define CB(callback) [this](const DebuggerResponse &r) { callback(r); }
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
// //
// TermGdbAdapter // TermGdbAdapter
@@ -136,8 +134,8 @@ void GdbTermEngine::runEngine()
{ {
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state()); QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
const qint64 attachedPID = m_stubProc.applicationPID(); const qint64 attachedPID = m_stubProc.applicationPID();
postCommand("attach " + QByteArray::number(attachedPID), postCommand("attach " + QByteArray::number(attachedPID), NoFlags,
CB(handleStubAttached)); [this](const DebuggerResponse &r) { handleStubAttached(r); });
} }
void GdbTermEngine::handleStubAttached(const DebuggerResponse &response) void GdbTermEngine::handleStubAttached(const DebuggerResponse &response)

View File

@@ -48,21 +48,6 @@ enum StackColumns
StackColumnCount = StackAddressColumn, StackColumnCount = StackAddressColumn,
}; };
////////////////////////////////////////////////////////////////////////
//
// StackCookie
//
////////////////////////////////////////////////////////////////////////
struct StackCookie
{
StackCookie() : isFull(true), gotoLocation(false) {}
StackCookie(bool full, bool jump) : isFull(full), gotoLocation(jump) {}
bool isFull;
bool gotoLocation;
};
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// //
// StackModel // StackModel
@@ -120,7 +105,4 @@ private:
} // namespace Internal } // namespace Internal
} // namespace Debugger } // namespace Debugger
Q_DECLARE_METATYPE(Debugger::Internal::StackCookie)
#endif // DEBUGGER_STACKHANDLER_H #endif // DEBUGGER_STACKHANDLER_H