Debugger: Move command flags to debugger command

Also, remove the need to mark GDB Python commands, detect the
need to use MI on the presence of non-Pythonic letters in
the command (space and hyphen).

Plan is to reuse even more almost shared code between engines.

Change-Id: I4e00debb07f2482637930675a28f464666b59553
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
hjk
2016-12-13 13:37:05 +01:00
parent c2eada278e
commit a61b6dfc57
11 changed files with 138 additions and 128 deletions

View File

@@ -196,6 +196,21 @@ public:
const DebuggerRunParameters &runParameters() const; const DebuggerRunParameters &runParameters() const;
DebuggerRunParameters &runParameters(); DebuggerRunParameters &runParameters();
enum {
// Remove need to qualify each use.
NeedsTemporaryStop = DebuggerCommand::NeedsTemporaryStop,
NeedsFullStop = DebuggerCommand::NeedsFullStop,
Discardable = DebuggerCommand::Discardable,
ConsoleCommand = DebuggerCommand::ConsoleCommand,
NeedsFlush = DebuggerCommand::NeedsFlush,
ExitRequest = DebuggerCommand::ExitRequest,
RunRequest = DebuggerCommand::RunRequest,
LosesChild = DebuggerCommand::LosesChild,
RebuildBreakpointModel = DebuggerCommand::RebuildBreakpointModel,
InUpdateLocals = DebuggerCommand::InUpdateLocals,
Silent = DebuggerCommand::Silent
};
virtual bool canHandleToolTip(const DebuggerToolTipContext &) const; virtual bool canHandleToolTip(const DebuggerToolTipContext &) const;
virtual void expandItem(const QString &iname); // Called when item in tree gets expanded. virtual void expandItem(const QString &iname); // Called when item in tree gets expanded.
virtual void updateItem(const QString &iname); // Called for fresh watch items. virtual void updateItem(const QString &iname); // Called for fresh watch items.

View File

@@ -50,6 +50,7 @@ public:
DebuggerCommand(const QString &f, const QJsonValue &a) : function(f), args(a) {} DebuggerCommand(const QString &f, const QJsonValue &a) : function(f), args(a) {}
DebuggerCommand(const QString &f, int fl) : function(f), flags(fl) {} DebuggerCommand(const QString &f, int fl) : function(f), flags(fl) {}
DebuggerCommand(const QString &f, int fl, const Callback &cb) : function(f), callback(cb), flags(fl) {} DebuggerCommand(const QString &f, int fl, const Callback &cb) : function(f), callback(cb), flags(fl) {}
DebuggerCommand(const QString &f, const Callback &cb) : function(f), callback(cb) {}
void arg(const char *value); void arg(const char *value);
void arg(const char *name, bool value); void arg(const char *name, bool value);
@@ -65,6 +66,34 @@ public:
QString argsToPython() const; QString argsToPython() const;
QString argsToString() const; QString argsToString() const;
enum CommandFlag {
NoFlags = 0,
// The command needs a stopped inferior.
NeedsTemporaryStop = 1,
// No need to wait for the reply before continuing inferior.
Discardable = 2,
// Needs a dummy extra command to force GDB output flushing.
NeedsFlush = 4,
// The command needs a stopped inferior and will stay stopped afterward.
NeedsFullStop = 8,
// Callback expects ResultRunning instead of ResultDone.
RunRequest = 16,
// Callback expects ResultExit instead of ResultDone.
ExitRequest = 32,
// Auto-set inferior shutdown related states.
LosesChild = 64,
// Trigger breakpoint model rebuild when no such commands are pending anymore.
RebuildBreakpointModel = 128,
// This is a command that needs to be wrapped into -interpreter-exec console
ConsoleCommand = 512,
// This is the UpdateLocals commannd during which we ignore notifications
InUpdateLocals = 1024,
// Do not echo to log.
Silent = 4096
};
Q_DECLARE_FLAGS(CommandFlags, CommandFlag)
QString function; QString function;
QJsonValue args; QJsonValue args;
Callback callback; Callback callback;
@@ -270,3 +299,5 @@ const char DisplayArrayData[] = "arraydata:separate";
} // namespace Internal } // namespace Internal
} // namespace Debugger } // namespace Debugger
Q_DECLARE_OPERATORS_FOR_FLAGS(Debugger::Internal::DebuggerCommand::CommandFlags)

View File

@@ -61,7 +61,7 @@ void GdbAttachEngine::runEngine()
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state()); QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
const qint64 pid = runParameters().attachPID; const qint64 pid = runParameters().attachPID;
showStatusMessage(tr("Attaching to process %1.").arg(pid)); showStatusMessage(tr("Attaching to process %1.").arg(pid));
runCommand({"attach " + QString::number(pid), NoFlags, runCommand({"attach " + QString::number(pid),
[this](const DebuggerResponse &r) { handleAttach(r); }}); [this](const DebuggerResponse &r) { handleAttach(r); }});
// In some cases we get only output like // In some cases we get only output like
// "Could not attach to process. If your uid matches the uid of the target\n" // "Could not attach to process. If your uid matches the uid of the target\n"
@@ -69,7 +69,7 @@ void GdbAttachEngine::runEngine()
// " again as the root user. For more details, see /etc/sysctl.d/10-ptrace.conf\n" // " again as the root user. For more details, see /etc/sysctl.d/10-ptrace.conf\n"
// " ptrace: Operation not permitted.\n" // " ptrace: Operation not permitted.\n"
// but no(!) ^ response. Use a second command to force *some* output // but no(!) ^ response. Use a second command to force *some* output
runCommand({"print 24", NoFlags}); runCommand({"print 24"});
} }
void GdbAttachEngine::handleAttach(const DebuggerResponse &response) void GdbAttachEngine::handleAttach(const DebuggerResponse &response)

View File

@@ -208,7 +208,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);
QString path = fi.absoluteFilePath(); QString path = fi.absoluteFilePath();
runCommand({"-file-exec-and-symbols \"" + path + '"', NoFlags, runCommand({"-file-exec-and-symbols \"" + path + '"',
CB(handleFileExecAndSymbols)}); CB(handleFileExecAndSymbols)});
} }
@@ -232,8 +232,7 @@ void GdbCoreEngine::handleFileExecAndSymbols(const DebuggerResponse &response)
void GdbCoreEngine::runEngine() void GdbCoreEngine::runEngine()
{ {
CHECK_STATE(EngineRunRequested); CHECK_STATE(EngineRunRequested);
runCommand({"target core " + coreFileName(), NoFlags, runCommand({"target core " + coreFileName(), CB(handleTargetCore)});
CB(handleTargetCore)});
} }
void GdbCoreEngine::handleTargetCore(const DebuggerResponse &response) void GdbCoreEngine::handleTargetCore(const DebuggerResponse &response)
@@ -253,7 +252,7 @@ void GdbCoreEngine::handleTargetCore(const DebuggerResponse &response)
// symbols yet. Load them in order of importance. // symbols yet. Load them in order of importance.
reloadStack(); reloadStack();
reloadModulesInternal(); reloadModulesInternal();
runCommand({"p 5", NoFlags, CB(handleRoundTrip)}); runCommand({"p 5", CB(handleRoundTrip)});
} }
void GdbCoreEngine::handleRoundTrip(const DebuggerResponse &response) void GdbCoreEngine::handleRoundTrip(const DebuggerResponse &response)

View File

@@ -840,7 +840,7 @@ void GdbEngine::interruptInferior()
return; return;
if (usesExecInterrupt()) { if (usesExecInterrupt()) {
runCommand({"-exec-interrupt", NoFlags}); runCommand({"-exec-interrupt"});
} else { } else {
showStatusMessage(tr("Stop requested..."), 5000); showStatusMessage(tr("Stop requested..."), 5000);
showMessage("TRYING TO INTERRUPT INFERIOR"); showMessage("TRYING TO INTERRUPT INFERIOR");
@@ -935,7 +935,10 @@ void GdbEngine::runCommand(const DebuggerCommand &command)
if (!(cmd.flags & Discardable)) if (!(cmd.flags & Discardable))
++m_nonDiscardableCount; ++m_nonDiscardableCount;
if (cmd.flags & PythonCommand) { bool isPythonCommand = true;
if (cmd.function.contains('-') || cmd.function.contains(' '))
isPythonCommand = false;
if (isPythonCommand) {
cmd.arg("token", token); cmd.arg("token", token);
cmd.function = "python theDumper." + cmd.function + "(" + cmd.argsToPython() + ")"; cmd.function = "python theDumper." + cmd.function + "(" + cmd.argsToPython() + ")";
} }
@@ -1209,7 +1212,7 @@ void GdbEngine::executeDebuggerCommand(const QString &command, DebuggerLanguages
if (!(languages & CppLanguage)) if (!(languages & CppLanguage))
return; return;
QTC_CHECK(acceptsDebuggerCommands()); QTC_CHECK(acceptsDebuggerCommands());
runCommand({command, NoFlags}); runCommand({command});
} }
// This is triggered when switching snapshots. // This is triggered when switching snapshots.
@@ -1222,7 +1225,7 @@ void GdbEngine::updateAll()
cmd.callback = [this](const DebuggerResponse &r) { handleStackListFrames(r, false); }; cmd.callback = [this](const DebuggerResponse &r) { handleStackListFrames(r, false); };
runCommand(cmd); runCommand(cmd);
stackHandler()->setCurrentIndex(0); stackHandler()->setCurrentIndex(0);
runCommand({"-thread-info", NoFlags, CB(handleThreadInfo)}); runCommand({"-thread-info", CB(handleThreadInfo)});
reloadRegisters(); reloadRegisters();
updateLocals(); updateLocals();
} }
@@ -1373,7 +1376,7 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
bool gotoHandleStop1 = true; bool gotoHandleStop1 = true;
if (!m_fullStartDone) { if (!m_fullStartDone) {
m_fullStartDone = true; m_fullStartDone = true;
runCommand({"sharedlibrary .*", NoFlags, runCommand({"sharedlibrary .*",
[this, data](const DebuggerResponse &) { handleStop1(data); }}); [this, data](const DebuggerResponse &) { handleStop1(data); }});
gotoHandleStop1 = false; gotoHandleStop1 = false;
} }
@@ -1529,9 +1532,9 @@ void GdbEngine::handleStop1(const GdbMi &data)
if (!m_systemDumpersLoaded) { if (!m_systemDumpersLoaded) {
m_systemDumpersLoaded = true; m_systemDumpersLoaded = true;
if (m_gdbVersion >= 70400 && boolSetting(LoadGdbDumpers)) if (m_gdbVersion >= 70400 && boolSetting(LoadGdbDumpers))
runCommand({"importPlainDumpers on", NoFlags}); runCommand({"importPlainDumpers on"});
else else
runCommand({"importPlainDumpers off", NoFlags}); runCommand({"importPlainDumpers off"});
} }
handleStop2(data); handleStop2(data);
@@ -1840,7 +1843,7 @@ void GdbEngine::shutdownInferior()
{ {
CHECK_STATE(InferiorShutdownRequested); CHECK_STATE(InferiorShutdownRequested);
DebuggerCommand cmd; DebuggerCommand cmd;
cmd.function = QLatin1String(runParameters().closeMode == DetachAtClose ? "detach" : "kill"); cmd.function = QLatin1String(runParameters().closeMode == DetachAtClose ? "detach " : "kill ");
cmd.callback = CB(handleInferiorShutdown); cmd.callback = CB(handleInferiorShutdown);
cmd.flags = NeedsTemporaryStop|LosesChild; cmd.flags = NeedsTemporaryStop|LosesChild;
runCommand(cmd); runCommand(cmd);
@@ -1885,8 +1888,8 @@ void GdbEngine::notifyAdapterShutdownOk()
switch (m_gdbProc.state()) { switch (m_gdbProc.state()) {
case QProcess::Running: { case QProcess::Running: {
if (runParameters().closeMode == KillAndExitMonitorAtClose) if (runParameters().closeMode == KillAndExitMonitorAtClose)
runCommand({"monitor exit", NoFlags}); runCommand({"monitor exit"});
runCommand({"exitGdb", ExitRequest|PythonCommand, CB(handleGdbExit)}); runCommand({"exitGdb", ExitRequest, CB(handleGdbExit)});
break; break;
} }
case QProcess::NotRunning: case QProcess::NotRunning:
@@ -2009,11 +2012,12 @@ void GdbEngine::continueInferiorInternal()
showStatusMessage(tr("Running requested..."), 5000); showStatusMessage(tr("Running requested..."), 5000);
CHECK_STATE(InferiorRunRequested); CHECK_STATE(InferiorRunRequested);
if (isNativeMixedActiveFrame()) { if (isNativeMixedActiveFrame()) {
DebuggerCommand cmd("executeContinue", RunRequest|PythonCommand); DebuggerCommand cmd("executeContinue", RunRequest);
cmd.callback = CB(handleExecuteContinue); cmd.callback = CB(handleExecuteContinue);
runCommand(cmd); runCommand(cmd);
} else { } else {
DebuggerCommand cmd("-exec-continue", RunRequest|NeedsFlush); DebuggerCommand cmd("-exec-continue");
cmd.flags = RunRequest | NeedsFlush;
cmd.callback = CB(handleExecuteContinue); cmd.callback = CB(handleExecuteContinue);
runCommand(cmd); runCommand(cmd);
} }
@@ -2033,7 +2037,7 @@ void GdbEngine::executeStep()
notifyInferiorRunRequested(); notifyInferiorRunRequested();
showStatusMessage(tr("Step requested..."), 5000); showStatusMessage(tr("Step requested..."), 5000);
if (isNativeMixedActiveFrame()) { if (isNativeMixedActiveFrame()) {
DebuggerCommand cmd("executeStep", RunRequest|PythonCommand); DebuggerCommand cmd("executeStep", RunRequest);
cmd.callback = CB(handleExecuteStep); cmd.callback = CB(handleExecuteStep);
runCommand(cmd); runCommand(cmd);
} else { } else {
@@ -2102,7 +2106,7 @@ void GdbEngine::executeStepOut()
notifyInferiorRunRequested(); notifyInferiorRunRequested();
showStatusMessage(tr("Finish function requested..."), 5000); showStatusMessage(tr("Finish function requested..."), 5000);
if (isNativeMixedActiveFrame()) { if (isNativeMixedActiveFrame()) {
runCommand({"executeStepOut", RunRequest|PythonCommand}); runCommand({"executeStepOut", RunRequest});
} else { } else {
// -exec-finish in 'main' results (correctly) in // -exec-finish in 'main' results (correctly) in
// 40^error,msg="\"finish\" not meaningful in the outermost frame." // 40^error,msg="\"finish\" not meaningful in the outermost frame."
@@ -2119,8 +2123,7 @@ void GdbEngine::executeNext()
notifyInferiorRunRequested(); notifyInferiorRunRequested();
showStatusMessage(tr("Step next requested..."), 5000); showStatusMessage(tr("Step next requested..."), 5000);
if (isNativeMixedActiveFrame()) { if (isNativeMixedActiveFrame()) {
DebuggerCommand cmd("executeNext", RunRequest|PythonCommand); runCommand({"executeNext", RunRequest});
runCommand(cmd);
} else { } else {
DebuggerCommand cmd; DebuggerCommand cmd;
cmd.flags = RunRequest; cmd.flags = RunRequest;
@@ -2191,7 +2194,7 @@ void GdbEngine::executeRunToLine(const ContextData &data)
loc = addressSpec(data.address); loc = addressSpec(data.address);
else else
loc = '"' + breakLocation(data.fileName) + '"' + ':' + QString::number(data.lineNumber); loc = '"' + breakLocation(data.fileName) + '"' + ':' + QString::number(data.lineNumber);
runCommand({"tbreak " + loc, NoFlags}); runCommand({"tbreak " + loc});
runCommand({"continue", RunRequest, CB(handleExecuteRunToLine)}); runCommand({"continue", RunRequest, CB(handleExecuteRunToLine)});
#else #else
@@ -2206,7 +2209,7 @@ void GdbEngine::executeRunToFunction(const QString &functionName)
{ {
CHECK_STATE(InferiorStopOk); CHECK_STATE(InferiorStopOk);
setTokenBarrier(); setTokenBarrier();
runCommand({"-break-insert -t " + functionName, NoFlags}); runCommand({"-break-insert -t " + functionName});
showStatusMessage(tr("Run to function %1 requested...").arg(functionName), 5000); showStatusMessage(tr("Run to function %1 requested...").arg(functionName), 5000);
continueInferiorInternal(); continueInferiorInternal();
} }
@@ -2219,10 +2222,10 @@ void GdbEngine::executeJumpToLine(const ContextData &data)
loc = addressSpec(data.address); loc = addressSpec(data.address);
else else
loc = '"' + breakLocation(data.fileName) + '"' + ':' + QString::number(data.lineNumber); loc = '"' + breakLocation(data.fileName) + '"' + ':' + QString::number(data.lineNumber);
runCommand({"tbreak " + loc, NoFlags}); runCommand({"tbreak " + loc});
notifyInferiorRunRequested(); notifyInferiorRunRequested();
runCommand({"jump" + loc, RunRequest, CB(handleExecuteJumpToLine)}); runCommand({"jump " + loc, RunRequest, CB(handleExecuteJumpToLine)});
// will produce something like // will produce something like
// &"jump \"/home/apoenitz/dev/work/test1/test1.cpp\":242" // &"jump \"/home/apoenitz/dev/work/test1/test1.cpp\":242"
// ~"Continuing at 0x4058f3." // ~"Continuing at 0x4058f3."
@@ -2558,8 +2561,8 @@ void GdbEngine::handleBreakInsert1(const DebuggerResponse &response, Breakpoint
// This delete was deferred. Act now. // This delete was deferred. Act now.
const GdbMi mainbkpt = response.data["bkpt"]; const GdbMi mainbkpt = response.data["bkpt"];
bp.notifyBreakpointRemoveProceeding(); bp.notifyBreakpointRemoveProceeding();
DebuggerCommand cmd("-break-delete " + mainbkpt["number"].data(), DebuggerCommand cmd("-break-delete " + mainbkpt["number"].data());
NeedsTemporaryStop | RebuildBreakpointModel); cmd.flags = NeedsTemporaryStop | RebuildBreakpointModel;
runCommand(cmd); runCommand(cmd);
bp.notifyBreakpointRemoveOk(); bp.notifyBreakpointRemoveOk();
return; return;
@@ -2730,7 +2733,7 @@ void GdbEngine::insertBreakpoint(Breakpoint bp)
const BreakpointParameters &data = bp.parameters(); const BreakpointParameters &data = bp.parameters();
if (!data.isCppBreakpoint()) { if (!data.isCppBreakpoint()) {
DebuggerCommand cmd("insertInterpreterBreakpoint", PythonCommand | NeedsTemporaryStop); DebuggerCommand cmd("insertInterpreterBreakpoint", NeedsTemporaryStop);
bp.addToCommand(&cmd); bp.addToCommand(&cmd);
cmd.callback = [this, bp](const DebuggerResponse &r) { handleInsertInterpreterBreakpoint(r, bp); }; cmd.callback = [this, bp](const DebuggerResponse &r) { handleInsertInterpreterBreakpoint(r, bp); };
runCommand(cmd); runCommand(cmd);
@@ -2849,7 +2852,7 @@ void GdbEngine::removeBreakpoint(Breakpoint bp)
const BreakpointParameters &data = bp.parameters(); const BreakpointParameters &data = bp.parameters();
if (!data.isCppBreakpoint()) { if (!data.isCppBreakpoint()) {
DebuggerCommand cmd("removeInterpreterBreakpoint", PythonCommand); DebuggerCommand cmd("removeInterpreterBreakpoint");
bp.addToCommand(&cmd); bp.addToCommand(&cmd);
runCommand(cmd); runCommand(cmd);
bp.notifyBreakpointRemoveOk(); bp.notifyBreakpointRemoveOk();
@@ -2893,7 +2896,7 @@ static QString dotEscape(QString str)
void GdbEngine::loadSymbols(const QString &modulePath) 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)
runCommand({"sharedlibrary " + dotEscape(modulePath), NoFlags}); runCommand({"sharedlibrary " + dotEscape(modulePath)});
reloadModulesInternal(); reloadModulesInternal();
reloadStack(); reloadStack();
updateLocals(); updateLocals();
@@ -2901,7 +2904,7 @@ void GdbEngine::loadSymbols(const QString &modulePath)
void GdbEngine::loadAllSymbols() void GdbEngine::loadAllSymbols()
{ {
runCommand({"sharedlibrary .*", NoFlags}); runCommand({"sharedlibrary .*"});
reloadModulesInternal(); reloadModulesInternal();
reloadStack(); reloadStack();
updateLocals(); updateLocals();
@@ -2917,7 +2920,7 @@ void GdbEngine::loadSymbolsForStack()
foreach (const Module &module, modules) { foreach (const Module &module, modules) {
if (module.startAddress <= frame.address if (module.startAddress <= frame.address
&& frame.address < module.endAddress) { && frame.address < module.endAddress) {
runCommand({"sharedlibrary " + dotEscape(module.modulePath), NoFlags}); runCommand({"sharedlibrary " + dotEscape(module.modulePath)});
needUpdate = true; needUpdate = true;
} }
} }
@@ -3199,7 +3202,7 @@ void GdbEngine::reloadFullStack()
resetLocation(); resetLocation();
DebuggerCommand cmd = stackCommand(-1); DebuggerCommand cmd = stackCommand(-1);
cmd.callback = [this](const DebuggerResponse &r) { handleStackListFrames(r, true); }; cmd.callback = [this](const DebuggerResponse &r) { handleStackListFrames(r, true); };
cmd.flags = Discardable | PythonCommand; cmd.flags = Discardable;
runCommand(cmd); runCommand(cmd);
} }
@@ -3208,7 +3211,7 @@ void GdbEngine::loadAdditionalQmlStack()
DebuggerCommand cmd = stackCommand(-1); DebuggerCommand cmd = stackCommand(-1);
cmd.arg("extraqml", "1"); cmd.arg("extraqml", "1");
cmd.callback = [this](const DebuggerResponse &r) { handleStackListFrames(r, true); }; cmd.callback = [this](const DebuggerResponse &r) { handleStackListFrames(r, true); };
cmd.flags = Discardable | PythonCommand; cmd.flags = Discardable;
runCommand(cmd); runCommand(cmd);
} }
@@ -3225,7 +3228,7 @@ void GdbEngine::reloadStack()
PENDING_DEBUG("RELOAD STACK"); PENDING_DEBUG("RELOAD STACK");
DebuggerCommand cmd = stackCommand(action(MaximalStackDepth)->value().toInt()); DebuggerCommand cmd = stackCommand(action(MaximalStackDepth)->value().toInt());
cmd.callback = [this](const DebuggerResponse &r) { handleStackListFrames(r, false); }; cmd.callback = [this](const DebuggerResponse &r) { handleStackListFrames(r, false); };
cmd.flags = Discardable | PythonCommand; cmd.flags = Discardable;
runCommand(cmd); runCommand(cmd);
} }
@@ -3400,7 +3403,7 @@ void GdbEngine::reloadRegisters()
if (!m_registerNamesListed) { if (!m_registerNamesListed) {
// The MI version does not give register size. // The MI version does not give register size.
// runCommand("-data-list-register-names", CB(handleRegisterListNames)); // runCommand("-data-list-register-names", CB(handleRegisterListNames));
runCommand({"maintenance print raw-registers", NoFlags, runCommand({"maintenance print raw-registers",
CB(handleRegisterListing)}); CB(handleRegisterListing)});
m_registerNamesListed = true; m_registerNamesListed = true;
} }
@@ -3409,7 +3412,7 @@ void GdbEngine::reloadRegisters()
runCommand({"-data-list-register-values r", Discardable, runCommand({"-data-list-register-values r", Discardable,
CB(handleRegisterListValues)}); CB(handleRegisterListValues)});
} else { } else {
runCommand({"maintenance print cooked-registers", NoFlags, runCommand({"maintenance print cooked-registers",
CB(handleMaintPrintRegisters)}); CB(handleMaintPrintRegisters)});
} }
} }
@@ -3475,7 +3478,7 @@ void GdbEngine::setRegisterValue(const QString &name, const QString &value)
QString fullName = name; QString fullName = name;
if (name.startsWith("xmm")) if (name.startsWith("xmm"))
fullName += ".uint128"; fullName += ".uint128";
runCommand({"set $" + fullName + "=" + value, NoFlags}); runCommand({"set $" + fullName + "=" + value});
reloadRegisters(); reloadRegisters();
} }
@@ -3602,7 +3605,7 @@ void GdbEngine::handleVarAssign(const DebuggerResponse &)
void GdbEngine::assignValueInDebugger(WatchItem *item, void GdbEngine::assignValueInDebugger(WatchItem *item,
const QString &expression, const QVariant &value) const QString &expression, const QVariant &value)
{ {
DebuggerCommand cmd("assignValue", PythonCommand); DebuggerCommand cmd("assignValue");
cmd.arg("type", toHex(item->type)); cmd.arg("type", toHex(item->type));
cmd.arg("expr", toHex(expression)); cmd.arg("expr", toHex(expression));
cmd.arg("value", toHex(value.toString())); cmd.arg("value", toHex(value.toString()));
@@ -3613,7 +3616,7 @@ void GdbEngine::assignValueInDebugger(WatchItem *item,
void GdbEngine::watchPoint(const QPoint &pnt) void GdbEngine::watchPoint(const QPoint &pnt)
{ {
DebuggerCommand cmd("watchPoint", PythonCommand|NeedsFullStop); DebuggerCommand cmd("watchPoint", NeedsFullStop);
cmd.arg("x", pnt.x()); cmd.arg("x", pnt.x());
cmd.arg("y", pnt.y()); cmd.arg("y", pnt.y());
cmd.callback = CB(handleWatchPoint); cmd.callback = CB(handleWatchPoint);
@@ -3938,9 +3941,9 @@ void GdbEngine::startGdb(const QStringList &args)
} }
showMessage("GDB STARTED, INITIALIZING IT"); showMessage("GDB STARTED, INITIALIZING IT");
runCommand({"show version", NoFlags, CB(handleShowVersion)}); runCommand({"show version", CB(handleShowVersion)});
//runCommand("-list-features", CB(handleListFeatures)); //runCommand("-list-features", CB(handleListFeatures));
runCommand({"show debug-file-directory", NoFlags, CB(handleDebugInfoLocation)}); runCommand({"show debug-file-directory", CB(handleDebugInfoLocation)});
//runCommand("-enable-timings"); //runCommand("-enable-timings");
//rurun print static-members off"); // Seemingly doesn't work. //rurun print static-members off"); // Seemingly doesn't work.
@@ -4013,22 +4016,22 @@ void GdbEngine::startGdb(const QStringList &args)
for (auto it = completeSourcePathMap.constBegin(), cend = completeSourcePathMap.constEnd(); for (auto it = completeSourcePathMap.constBegin(), cend = completeSourcePathMap.constEnd();
it != cend; it != cend;
++it) { ++it) {
runCommand({"set substitute-path " + it.key() + " " + it.value(), NoFlags}); runCommand({"set substitute-path " + it.key() + " " + it.value()});
} }
// Spaces just will not work. // Spaces just will not work.
foreach (const QString &src, rp.debugSourceLocation) { foreach (const QString &src, rp.debugSourceLocation) {
if (QDir(src).exists()) if (QDir(src).exists())
runCommand({"directory " + src, NoFlags}); runCommand({"directory " + src});
else else
showMessage("# directory does not exist: " + src, LogInput); showMessage("# directory does not exist: " + src, LogInput);
} }
if (!rp.sysRoot.isEmpty()) { if (!rp.sysRoot.isEmpty()) {
runCommand({"set sysroot " + rp.sysRoot, NoFlags}); runCommand({"set sysroot " + rp.sysRoot});
// sysroot is not enough to correctly locate the sources, so explicitly // sysroot is not enough to correctly locate the sources, so explicitly
// relocate the most likely place for the debug source // relocate the most likely place for the debug source
runCommand({"set substitute-path /usr/src " + rp.sysRoot + "/usr/src", NoFlags}); runCommand({"set substitute-path /usr/src " + rp.sysRoot + "/usr/src"});
} }
//QByteArray ba = QFileInfo(sp.dumperLibrary).path().toLocal8Bit(); //QByteArray ba = QFileInfo(sp.dumperLibrary).path().toLocal8Bit();
@@ -4053,27 +4056,27 @@ void GdbEngine::startGdb(const QStringList &args)
const QString dumperSourcePath = ICore::resourcePath() + "/debugger/"; const QString dumperSourcePath = ICore::resourcePath() + "/debugger/";
if (terminal()->isUsable()) if (terminal()->isUsable())
runCommand({"set inferior-tty " + QString::fromUtf8(terminal()->slaveDevice()), NoFlags}); runCommand({"set inferior-tty " + QString::fromUtf8(terminal()->slaveDevice())});
const QFileInfo gdbBinaryFile(rp.debugger.executable); const QFileInfo gdbBinaryFile(rp.debugger.executable);
const QString uninstalledData = gdbBinaryFile.absolutePath() + "/data-directory/python"; const QString uninstalledData = gdbBinaryFile.absolutePath() + "/data-directory/python";
runCommand({"python sys.path.insert(1, '" + dumperSourcePath + "')", NoFlags}); runCommand({"python sys.path.insert(1, '" + dumperSourcePath + "')"});
runCommand({"python sys.path.append('" + uninstalledData + "')", NoFlags}); runCommand({"python sys.path.append('" + uninstalledData + "')"});
runCommand({"python from gdbbridge import *", NoFlags}); runCommand({"python from gdbbridge import *"});
const QString path = stringSetting(ExtraDumperFile); const QString path = stringSetting(ExtraDumperFile);
if (!path.isEmpty() && QFileInfo(path).isReadable()) { if (!path.isEmpty() && QFileInfo(path).isReadable()) {
DebuggerCommand cmd("addDumperModule", PythonCommand); DebuggerCommand cmd("addDumperModule");
cmd.arg("path", path); cmd.arg("path", path);
runCommand(cmd); runCommand(cmd);
} }
const QString commands = stringSetting(ExtraDumperCommands); const QString commands = stringSetting(ExtraDumperCommands);
if (!commands.isEmpty()) if (!commands.isEmpty())
runCommand({commands, NoFlags}); runCommand({commands});
runCommand({"loadDumpers", PythonCommand, CB(handlePythonSetup)}); runCommand({"loadDumpers", CB(handlePythonSetup)});
} }
void GdbEngine::handleGdbStartFailed() void GdbEngine::handleGdbStartFailed()
@@ -4085,7 +4088,7 @@ void GdbEngine::loadInitScript()
const QString script = runParameters().overrideStartScript; const QString script = runParameters().overrideStartScript;
if (!script.isEmpty()) { if (!script.isEmpty()) {
if (QFileInfo(script).isReadable()) { if (QFileInfo(script).isReadable()) {
runCommand({"source " + script, NoFlags}); runCommand({"source " + script});
} else { } else {
AsynchronousMessageBox::warning( AsynchronousMessageBox::warning(
tr("Cannot find debugger initialization script"), tr("Cannot find debugger initialization script"),
@@ -4097,7 +4100,7 @@ void GdbEngine::loadInitScript()
} else { } else {
const QString commands = expand(stringSetting(GdbStartupCommands)); const QString commands = expand(stringSetting(GdbStartupCommands));
if (!commands.isEmpty()) if (!commands.isEmpty())
runCommand({commands, NoFlags}); runCommand({commands});
} }
} }
@@ -4107,16 +4110,16 @@ void GdbEngine::setEnvironmentVariables()
Environment runEnv = runParameters().inferior.environment; Environment runEnv = runParameters().inferior.environment;
foreach (const EnvironmentItem &item, sysEnv.diff(runEnv)) { foreach (const EnvironmentItem &item, sysEnv.diff(runEnv)) {
if (item.unset) if (item.unset)
runCommand({"unset environment " + item.name, NoFlags}); runCommand({"unset environment " + item.name});
else else
runCommand({"-gdb-set environment " + item.name + '=' runCommand({"-gdb-set environment " + item.name + '='
+ item.value, NoFlags}); + item.value});
} }
} }
void GdbEngine::reloadDebuggingHelpers() void GdbEngine::reloadDebuggingHelpers()
{ {
runCommand({"reloadDumpers", PythonCommand}); runCommand({"reloadDumpers"});
reloadLocals(); reloadLocals();
} }
@@ -4220,15 +4223,15 @@ void GdbEngine::handleInferiorPrepared()
if (!rp.commandsAfterConnect.isEmpty()) { if (!rp.commandsAfterConnect.isEmpty()) {
const QString commands = expand(rp.commandsAfterConnect); const QString commands = expand(rp.commandsAfterConnect);
foreach (const QString &command, commands.split('\n')) for (const QString &command : commands.split('\n'))
runCommand({command, NoFlags}); runCommand({command});
} }
//runCommand("set follow-exec-mode new"); //runCommand("set follow-exec-mode new");
if (rp.breakOnMain) { if (rp.breakOnMain) {
QString cmd = "tbreak "; QString cmd = "tbreak ";
cmd += QLatin1String(rp.toolChainAbi.os() == Abi::WindowsOS ? "qMain" : "main"); cmd += QLatin1String(rp.toolChainAbi.os() == Abi::WindowsOS ? "qMain" : "main");
runCommand({cmd, NoFlags}); runCommand({cmd});
} }
// Initial attempt to set breakpoints. // Initial attempt to set breakpoints.
@@ -4255,7 +4258,7 @@ void GdbEngine::finishInferiorSetup()
const bool onWarning = boolSetting(BreakOnWarning); const bool onWarning = boolSetting(BreakOnWarning);
const bool onFatal = boolSetting(BreakOnFatal); const bool onFatal = boolSetting(BreakOnFatal);
if (onAbort || onWarning || onFatal) { if (onAbort || onWarning || onFatal) {
DebuggerCommand cmd("createSpecialBreakpoints", PythonCommand); DebuggerCommand cmd("createSpecialBreakpoints");
cmd.arg("breakonabort", onAbort); cmd.arg("breakonabort", onAbort);
cmd.arg("breakonwarning", onWarning); cmd.arg("breakonwarning", onWarning);
cmd.arg("breakonfatal", onFatal); cmd.arg("breakonfatal", onFatal);
@@ -4279,7 +4282,7 @@ void GdbEngine::handleDebugInfoLocation(const DebuggerResponse &response)
QString cmd = "set debug-file-directory " + debugInfoLocation; QString cmd = "set debug-file-directory " + debugInfoLocation;
if (!curDebugInfoLocations.isEmpty()) if (!curDebugInfoLocations.isEmpty())
cmd += HostOsInfo::pathListSeparator() + curDebugInfoLocations; cmd += HostOsInfo::pathListSeparator() + curDebugInfoLocations;
runCommand({cmd, NoFlags}); runCommand({cmd});
} }
} }
} }
@@ -4491,7 +4494,7 @@ void GdbEngine::doUpdateLocals(const UpdateParameters &params)
watchHandler()->notifyUpdateStarted(params); watchHandler()->notifyUpdateStarted(params);
DebuggerCommand cmd("fetchVariables", Discardable|InUpdateLocals|PythonCommand); DebuggerCommand cmd("fetchVariables", Discardable|InUpdateLocals);
watchHandler()->appendFormatRequests(&cmd); watchHandler()->appendFormatRequests(&cmd);
watchHandler()->appendWatchersAndTooltipRequests(&cmd); watchHandler()->appendWatchersAndTooltipRequests(&cmd);

View File

@@ -147,35 +147,7 @@ private:
// known function return value. // known function return value.
QString m_resultVarName; QString m_resultVarName;
private: ////////// Gdb Command Management ////////// protected: ////////// Gdb Command Management //////////
public: // Otherwise the Qt flag macros are unhappy.
enum GdbCommandFlag {
NoFlags = 0,
// The command needs a stopped inferior.
NeedsTemporaryStop = 1,
// No need to wait for the reply before continuing inferior.
Discardable = 2,
// Needs a dummy extra command to force GDB output flushing.
NeedsFlush = 4,
// The command needs a stopped inferior and will stay stopped afterward.
NeedsFullStop = 8,
// Callback expects ResultRunning instead of ResultDone.
RunRequest = 16,
// Callback expects ResultExit instead of ResultDone.
ExitRequest = 32,
// Auto-set inferior shutdown related states.
LosesChild = 64,
// Trigger breakpoint model rebuild when no such commands are pending anymore.
RebuildBreakpointModel = 128,
// This is a command that needs to be wrapped into -interpreter-exec console
ConsoleCommand = 512,
// This is the UpdateLocals commannd during which we ignore notifications
InUpdateLocals = 1024,
// This is a command using the python interface
PythonCommand = 2048
};
Q_DECLARE_FLAGS(GdbCommandFlags, GdbCommandFlag)
void runCommand(const DebuggerCommand &command) override; void runCommand(const DebuggerCommand &command) override;
@@ -469,5 +441,3 @@ protected:
} // namespace Internal } // namespace Internal
} // namespace Debugger } // namespace Debugger
Q_DECLARE_OPERATORS_FOR_FLAGS(Debugger::Internal::GdbEngine::GdbCommandFlags)

View File

@@ -54,14 +54,14 @@ void GdbPlainEngine::setupInferior()
setEnvironmentVariables(); setEnvironmentVariables();
const DebuggerRunParameters &rp = runParameters(); const DebuggerRunParameters &rp = runParameters();
if (!rp.inferior.workingDirectory.isEmpty()) if (!rp.inferior.workingDirectory.isEmpty())
runCommand({"cd " + rp.inferior.workingDirectory, NoFlags}); runCommand({"cd " + rp.inferior.workingDirectory});
if (!rp.inferior.commandLineArguments.isEmpty()) { if (!rp.inferior.commandLineArguments.isEmpty()) {
QString args = rp.inferior.commandLineArguments; QString args = rp.inferior.commandLineArguments;
runCommand({"-exec-arguments " + args, NoFlags}); runCommand({"-exec-arguments " + args});
} }
QString executable = QFileInfo(runParameters().inferior.executable).absoluteFilePath(); QString executable = QFileInfo(runParameters().inferior.executable).absoluteFilePath();
runCommand({"-file-exec-and-symbols \"" + executable + '"', NoFlags, runCommand({"-file-exec-and-symbols \"" + executable + '"',
CB(handleFileExecAndSymbols)}); CB(handleFileExecAndSymbols)});
} }
@@ -82,9 +82,9 @@ void GdbPlainEngine::handleFileExecAndSymbols(const DebuggerResponse &response)
void GdbPlainEngine::runEngine() void GdbPlainEngine::runEngine()
{ {
if (runParameters().useContinueInsteadOfRun) if (runParameters().useContinueInsteadOfRun)
runCommand({"-exec-continue", RunRequest, CB(handleExecuteContinue)}); runCommand({"-exec-continue", DebuggerCommand::RunRequest, CB(handleExecuteContinue)});
else else
runCommand({"-exec-run", RunRequest, CB(handleExecRun)}); runCommand({"-exec-run", DebuggerCommand::RunRequest, CB(handleExecRun)});
} }
void GdbPlainEngine::handleExecRun(const DebuggerResponse &response) void GdbPlainEngine::handleExecRun(const DebuggerResponse &response)
@@ -97,7 +97,7 @@ void GdbPlainEngine::handleExecRun(const DebuggerResponse &response)
showMessage(msgInferiorSetupOk(), StatusBar); showMessage(msgInferiorSetupOk(), StatusBar);
// FIXME: That's the wrong place for it. // FIXME: That's the wrong place for it.
if (boolSetting(EnableReverseDebugging)) if (boolSetting(EnableReverseDebugging))
runCommand({"target record", NoFlags}); runCommand({"target record"});
} else { } else {
QString msg = response.data["msg"].data(); QString msg = response.data["msg"].data();
//QTC_CHECK(status() == InferiorRunOk); //QTC_CHECK(status() == InferiorRunOk);

View File

@@ -177,10 +177,10 @@ void GdbRemoteServerEngine::setupInferior()
// postCommand("set architecture " + remoteArch); // postCommand("set architecture " + remoteArch);
const QString solibSearchPath = rp.solibSearchPath.join(HostOsInfo::pathListSeparator()); const QString solibSearchPath = rp.solibSearchPath.join(HostOsInfo::pathListSeparator());
if (!solibSearchPath.isEmpty()) if (!solibSearchPath.isEmpty())
runCommand({"set solib-search-path " + solibSearchPath, NoFlags}); runCommand({"set solib-search-path " + solibSearchPath});
if (!args.isEmpty()) if (!args.isEmpty())
runCommand({"-exec-arguments " + args, NoFlags}); runCommand({"-exec-arguments " + args});
setEnvironmentVariables(); setEnvironmentVariables();
@@ -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 (usesTargetAsync()) if (usesTargetAsync())
runCommand({"set target-async on", NoFlags, CB(handleSetTargetAsync)}); runCommand({"set target-async on", CB(handleSetTargetAsync)});
if (symbolFile.isEmpty()) { if (symbolFile.isEmpty()) {
showMessage(tr("No symbol file given."), StatusBar); showMessage(tr("No symbol file given."), StatusBar);
@@ -214,7 +214,7 @@ void GdbRemoteServerEngine::setupInferior()
if (!symbolFile.isEmpty()) { if (!symbolFile.isEmpty()) {
runCommand({"-file-exec-and-symbols \"" + symbolFile + '"', runCommand({"-file-exec-and-symbols \"" + symbolFile + '"',
NoFlags, CB(handleFileExecAndSymbols)}); CB(handleFileExecAndSymbols)});
} }
} }
@@ -261,11 +261,11 @@ void GdbRemoteServerEngine::callTargetRemote()
} }
if (m_isQnxGdb) if (m_isQnxGdb)
runCommand({"target qnx " + channel, NoFlags, CB(handleTargetQnx)}); runCommand({"target qnx " + channel, CB(handleTargetQnx)});
else if (runParameters().useExtendedRemote) else if (runParameters().useExtendedRemote)
runCommand({"target extended-remote " + channel, NoFlags, CB(handleTargetExtendedRemote)}); runCommand({"target extended-remote " + channel, CB(handleTargetExtendedRemote)});
else else
runCommand({"target remote " + channel, NoFlags, CB(handleTargetRemote)}); runCommand({"target remote " + channel, CB(handleTargetRemote)});
} }
void GdbRemoteServerEngine::handleTargetRemote(const DebuggerResponse &response) void GdbRemoteServerEngine::handleTargetRemote(const DebuggerResponse &response)
@@ -277,7 +277,7 @@ void GdbRemoteServerEngine::handleTargetRemote(const DebuggerResponse &response)
showMessage(msgAttachedToStoppedInferior(), StatusBar); showMessage(msgAttachedToStoppedInferior(), StatusBar);
QString commands = expand(stringSetting(GdbPostAttachCommands)); QString commands = expand(stringSetting(GdbPostAttachCommands));
if (!commands.isEmpty()) if (!commands.isEmpty())
runCommand({commands, NoFlags}); runCommand({commands});
handleInferiorPrepared(); handleInferiorPrepared();
} else { } else {
// 16^error,msg="hd:5555: Connection timed out." // 16^error,msg="hd:5555: Connection timed out."
@@ -293,14 +293,14 @@ void GdbRemoteServerEngine::handleTargetExtendedRemote(const DebuggerResponse &r
showMessage(msgAttachedToStoppedInferior(), StatusBar); showMessage(msgAttachedToStoppedInferior(), StatusBar);
QString commands = expand(stringSetting(GdbPostAttachCommands)); QString commands = expand(stringSetting(GdbPostAttachCommands));
if (!commands.isEmpty()) if (!commands.isEmpty())
runCommand({commands, NoFlags}); runCommand({commands});
if (runParameters().attachPID > 0) { // attach to pid if valid if (runParameters().attachPID > 0) { // attach to pid if valid
// gdb server will stop the remote application itself. // gdb server will stop the remote application itself.
runCommand({"attach " + QString::number(runParameters().attachPID), runCommand({"attach " + QString::number(runParameters().attachPID),
NoFlags, CB(handleTargetExtendedAttach)}); CB(handleTargetExtendedAttach)});
} else if (!runParameters().inferior.executable.isEmpty()) { } else if (!runParameters().inferior.executable.isEmpty()) {
runCommand({"-gdb-set remote exec-file " + runParameters().inferior.executable, runCommand({"-gdb-set remote exec-file " + runParameters().inferior.executable,
NoFlags, CB(handleTargetExtendedAttach)}); CB(handleTargetExtendedAttach)});
} else { } else {
const QString title = tr("No Remote Executable or Process ID Specified"); const QString title = tr("No Remote Executable or Process ID Specified");
const QString msg = tr( const QString msg = tr(
@@ -350,9 +350,9 @@ void GdbRemoteServerEngine::handleTargetQnx(const DebuggerResponse &response)
const qint64 pid = rp.attachPID; const qint64 pid = rp.attachPID;
const QString remoteExecutable = rp.inferior.executable; const QString remoteExecutable = rp.inferior.executable;
if (pid > -1) if (pid > -1)
runCommand({"attach " + QString::number(pid), NoFlags, CB(handleAttach)}); runCommand({"attach " + QString::number(pid), CB(handleAttach)});
else if (!remoteExecutable.isEmpty()) else if (!remoteExecutable.isEmpty())
runCommand({"set nto-executable " + remoteExecutable, NoFlags, CB(handleSetNtoExecutable)}); runCommand({"set nto-executable " + remoteExecutable, CB(handleSetNtoExecutable)});
else else
handleInferiorPrepared(); handleInferiorPrepared();
} else { } else {
@@ -408,7 +408,7 @@ void GdbRemoteServerEngine::runEngine()
notifyEngineRunAndInferiorStopOk(); notifyEngineRunAndInferiorStopOk();
continueInferiorInternal(); continueInferiorInternal();
} else { } else {
runCommand({"-exec-run", RunRequest, CB(handleExecRun)}); runCommand({"-exec-run", DebuggerCommand::RunRequest, CB(handleExecRun)});
} }
} }
@@ -429,7 +429,7 @@ void GdbRemoteServerEngine::interruptInferior2()
{ {
QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state()); QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state());
if (usesTargetAsync()) { if (usesTargetAsync()) {
runCommand({"-exec-interrupt", NoFlags, CB(handleInterruptInferior)}); runCommand({"-exec-interrupt", CB(handleInterruptInferior)});
} else if (m_isQnxGdb && HostOsInfo::isWindowsHost()) { } else if (m_isQnxGdb && HostOsInfo::isWindowsHost()) {
m_gdbProc.interrupt(); m_gdbProc.interrupt();
} else { } else {

View File

@@ -128,7 +128,7 @@ 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();
runCommand({"attach " + QString::number(attachedPID), NoFlags, runCommand({"attach " + QString::number(attachedPID),
[this](const DebuggerResponse &r) { handleStubAttached(r); }}); [this](const DebuggerResponse &r) { handleStubAttached(r); }});
} }

View File

@@ -414,7 +414,7 @@ void LldbEngine::setupInferior()
} }
}; };
cmd2.flags = LldbEngine::Silent; cmd2.flags = Silent;
runCommand(cmd2); runCommand(cmd2);
} }

View File

@@ -61,14 +61,6 @@ public:
explicit LldbEngine(const DebuggerRunParameters &runParameters); explicit LldbEngine(const DebuggerRunParameters &runParameters);
~LldbEngine() override; ~LldbEngine() override;
enum LldbCommandFlag {
NoFlags = 0,
// Do not echo to log.
Silent = 1,
// The command needs a stopped inferior and will stay stopped afterward.
NeedsFullStop = 8,
};
signals: signals:
void outputReady(const QString &data); void outputReady(const QString &data);