Debugger: Merge GdbEngine's {run,post,flush}Command

Since we don't keep a local queue anymore, the distinction is
no more needed. Also, this is close to the LLDB side now.

Also move remaining uses of DebuggerCommand::flags to
GdbEngine, since that's the only user.

Change-Id: I61ae0f4e5294e306ab0b202e80f27fb3e3f7a7d7
Reviewed-by: Christian Stenger <christian.stenger@theqtcompany.com>
Reviewed-by: Niels Weber <niels.weber@theqtcompany.com>
This commit is contained in:
hjk
2015-09-11 11:28:55 +02:00
parent 25bb8411a4
commit 150af7af4c
8 changed files with 428 additions and 489 deletions

View File

@@ -51,17 +51,10 @@ class DebuggerCommand
public: public:
typedef std::function<void(const DebuggerResponse &)> Callback; typedef std::function<void(const DebuggerResponse &)> Callback;
DebuggerCommand() : flags(0) {} DebuggerCommand() {}
DebuggerCommand(const char *f, int flags = 0, Callback cb = Callback()) DebuggerCommand(const char *f) : function(f) {}
: function(f), callback(cb), flags(flags) DebuggerCommand(const QByteArray &f) : function(f) {}
{} DebuggerCommand(const char *f, const QJsonValue &a) : function(f), args(a) {}
DebuggerCommand(const char *f, const QJsonValue &a, int flags = 0, Callback cb = Callback())
: function(f), args(a), callback(cb), flags(flags)
{}
DebuggerCommand(const char *f, Callback cb)
: function(f), callback(cb), flags(0)
{}
DebuggerCommand(const QByteArray &f) : function(f), flags(0) {}
void arg(const char *value); void arg(const char *value);
void arg(const char *name, int value); void arg(const char *name, int value);
@@ -81,6 +74,9 @@ public:
Callback callback; Callback callback;
uint postTime; // msecsSinceStartOfDay uint postTime; // msecsSinceStartOfDay
int flags; int flags;
private:
void argHelper(const char *name, const QByteArray &value);
}; };
/* /*

View File

@@ -75,8 +75,9 @@ 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;
postCommand("attach " + QByteArray::number(pid), NoFlags, DebuggerCommand cmd("attach " + QByteArray::number(pid));
[this](const DebuggerResponse &r) { handleAttach(r); }); cmd.callback = [this](const DebuggerResponse &r) { handleAttach(r); };
runCommand(cmd);
showStatusMessage(tr("Attached to process %1.").arg(inferiorPid())); showStatusMessage(tr("Attached to process %1.").arg(inferiorPid()));
} }

View File

@@ -212,8 +212,9 @@ 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 + '"', NoFlags, DebuggerCommand cmd("-file-exec-and-symbols \"" + path + '"');
CB(handleFileExecAndSymbols)); cmd.callback = CB(handleFileExecAndSymbols);
runCommand(cmd);
} }
void GdbCoreEngine::handleFileExecAndSymbols(const DebuggerResponse &response) void GdbCoreEngine::handleFileExecAndSymbols(const DebuggerResponse &response)
@@ -236,7 +237,9 @@ void GdbCoreEngine::handleFileExecAndSymbols(const DebuggerResponse &response)
void GdbCoreEngine::runEngine() void GdbCoreEngine::runEngine()
{ {
CHECK_STATE(EngineRunRequested); CHECK_STATE(EngineRunRequested);
postCommand("target core " + coreFileName().toLocal8Bit(), NoFlags, CB(handleTargetCore)); DebuggerCommand cmd("target core " + coreFileName().toLocal8Bit());
cmd.callback = CB(handleTargetCore);
runCommand(cmd);
} }
void GdbCoreEngine::handleTargetCore(const DebuggerResponse &response) void GdbCoreEngine::handleTargetCore(const DebuggerResponse &response)
@@ -249,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();
postCommand("p 5", NoFlags, CB(handleRoundTrip)); runCommand("p 5", CB(handleRoundTrip));
return; return;
} }
showStatusMessage(tr("Attach to core \"%1\" failed:").arg(runParameters().coreFile) showStatusMessage(tr("Attach to core \"%1\" failed:").arg(runParameters().coreFile)

File diff suppressed because it is too large Load Diff

View File

@@ -155,8 +155,6 @@ private: ////////// Gdb Command Management //////////
NeedsStop = 1, NeedsStop = 1,
// No need to wait for the reply before continuing inferior. // No need to wait for the reply before continuing inferior.
Discardable = 2, Discardable = 2,
// We can live without receiving an answer.
NonCriticalResponse = 8,
// Callback expects ResultRunning instead of ResultDone. // Callback expects ResultRunning instead of ResultDone.
RunRequest = 16, RunRequest = 16,
// Callback expects ResultExit instead of ResultDone. // Callback expects ResultExit instead of ResultDone.
@@ -168,20 +166,18 @@ private: ////////// Gdb Command Management //////////
// This is a command that needs to be wrapped into -interpreter-exec console // This is a command that needs to be wrapped into -interpreter-exec console
ConsoleCommand = 512, ConsoleCommand = 512,
// This is the UpdateLocals commannd during which we ignore notifications // This is the UpdateLocals commannd during which we ignore notifications
InUpdateLocals = 1024 InUpdateLocals = 1024,
// This is a command using the python interface
PythonCommand = 2048
}; };
Q_DECLARE_FLAGS(GdbCommandFlags, GdbCommandFlag) Q_DECLARE_FLAGS(GdbCommandFlags, GdbCommandFlag)
// Type and cookie are sender-internal data, opaque for the "event
// queue". resultNeeded == true increments m_pendingResults on
// send and decrements on receipt, effectively preventing
// watch model updates before everything is finished.
void flushCommand(const DebuggerCommand &cmd);
protected: protected:
void runCommand(const DebuggerCommand &command); void runCommand(const DebuggerCommand &command, int flags = NoFlags);
void postCommand(const QByteArray &command, void runCommand(const QByteArray &command,
int flags = NoFlags, const DebuggerCommand::Callback &callback,
DebuggerCommand::Callback callback = DebuggerCommand::Callback()); int flags = NoFlags);
private: private:
Q_SLOT void commandTimeout(); Q_SLOT void commandTimeout();
void setTokenBarrier(); void setTokenBarrier();
@@ -190,6 +186,7 @@ private:
void scheduleTestResponse(int testCase, const QByteArray &response); void scheduleTestResponse(int testCase, const QByteArray &response);
QHash<int, DebuggerCommand> m_commandForToken; QHash<int, DebuggerCommand> m_commandForToken;
QHash<int, int> m_flagsForToken;
int commandTimeoutTime() const; int commandTimeoutTime() const;
QTimer m_commandTimer; QTimer m_commandTimer;
@@ -395,12 +392,10 @@ protected:
void showToolTip(); void showToolTip();
void handleVarAssign(const DebuggerResponse &response); void handleVarAssign(const DebuggerResponse &response);
void handleDetach(const DebuggerResponse &response);
void handleThreadGroupCreated(const GdbMi &result); void handleThreadGroupCreated(const GdbMi &result);
void handleThreadGroupExited(const GdbMi &result); void handleThreadGroupExited(const GdbMi &result);
Q_SLOT void createFullBacktrace(); Q_SLOT void createFullBacktrace();
void handleCreateFullBacktrace(const DebuggerResponse &response);
void doUpdateLocals(const UpdateParameters &parameters) override; void doUpdateLocals(const UpdateParameters &parameters) override;
void handleStackFrame(const DebuggerResponse &response); void handleStackFrame(const DebuggerResponse &response);

View File

@@ -60,10 +60,10 @@ void GdbPlainEngine::setupInferior()
setEnvironmentVariables(); setEnvironmentVariables();
if (!runParameters().processArgs.isEmpty()) { if (!runParameters().processArgs.isEmpty()) {
QString args = runParameters().processArgs; QString args = runParameters().processArgs;
postCommand("-exec-arguments " + toLocalEncoding(args)); runCommand("-exec-arguments " + toLocalEncoding(args));
} }
postCommand("-file-exec-and-symbols \"" + execFilePath() + '"', runCommand("-file-exec-and-symbols \"" + execFilePath() + '"',
NoFlags, CB(handleFileExecAndSymbols)); CB(handleFileExecAndSymbols));
} }
void GdbPlainEngine::handleFileExecAndSymbols(const DebuggerResponse &response) void GdbPlainEngine::handleFileExecAndSymbols(const DebuggerResponse &response)
@@ -84,11 +84,10 @@ void GdbPlainEngine::handleFileExecAndSymbols(const DebuggerResponse &response)
void GdbPlainEngine::runEngine() void GdbPlainEngine::runEngine()
{ {
if (runParameters().useContinueInsteadOfRun) if (runParameters().useContinueInsteadOfRun)
postCommand("-exec-continue", GdbEngine::RunRequest, CB(handleExecuteContinue)); runCommand("-exec-continue", CB(handleExecuteContinue), RunRequest);
else else
postCommand("-exec-run", GdbEngine::RunRequest, CB(handleExecRun)); runCommand("-exec-run", CB(handleExecRun), RunRequest);
} }
void GdbPlainEngine::handleExecRun(const DebuggerResponse &response) void GdbPlainEngine::handleExecRun(const DebuggerResponse &response)
{ {
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state()); QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
@@ -99,7 +98,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))
postCommand("target record"); runCommand("target record");
} else { } else {
QString msg = fromLocalEncoding(response.data["msg"].data()); QString msg = fromLocalEncoding(response.data["msg"].data());
//QTC_CHECK(status() == InferiorRunOk); //QTC_CHECK(status() == InferiorRunOk);

View File

@@ -183,10 +183,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())
postCommand("set solib-search-path " + solibSearchPath.toLocal8Bit()); runCommand("set solib-search-path " + solibSearchPath.toLocal8Bit());
if (!args.isEmpty()) if (!args.isEmpty())
postCommand("-exec-arguments " + args.toLocal8Bit()); runCommand("-exec-arguments " + args.toLocal8Bit());
setEnvironmentVariables(); setEnvironmentVariables();
@@ -210,7 +210,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", NoFlags, CB(handleSetTargetAsync)); runCommand("set target-async on", CB(handleSetTargetAsync));
if (executableFileName.isEmpty()) { if (executableFileName.isEmpty()) {
showMessage(tr("No symbol file given."), StatusBar); showMessage(tr("No symbol file given."), StatusBar);
@@ -219,8 +219,8 @@ void GdbRemoteServerEngine::setupInferior()
} }
if (!executableFileName.isEmpty()) { if (!executableFileName.isEmpty()) {
postCommand("-file-exec-and-symbols \"" + executableFileName.toLocal8Bit() + '"', runCommand("-file-exec-and-symbols \"" + executableFileName.toLocal8Bit() + '"',
NoFlags, CB(handleFileExecAndSymbols)); CB(handleFileExecAndSymbols));
} }
} }
@@ -270,11 +270,11 @@ void GdbRemoteServerEngine::callTargetRemote()
} }
if (m_isQnxGdb) if (m_isQnxGdb)
postCommand("target qnx " + channel, NoFlags, CB(handleTargetQnx)); runCommand("target qnx " + channel, CB(handleTargetQnx));
else if (runParameters().multiProcess) else if (runParameters().multiProcess)
postCommand("target extended-remote " + channel, NoFlags, CB(handleTargetExtendedRemote)); runCommand("target extended-remote " + channel, CB(handleTargetExtendedRemote));
else else
postCommand("target remote " + channel, NoFlags, CB(handleTargetRemote)); runCommand("target remote " + channel, CB(handleTargetRemote));
} }
void GdbRemoteServerEngine::handleTargetRemote(const DebuggerResponse &response) void GdbRemoteServerEngine::handleTargetRemote(const DebuggerResponse &response)
@@ -287,7 +287,7 @@ void GdbRemoteServerEngine::handleTargetRemote(const DebuggerResponse &response)
QString postAttachCommands = stringSetting(GdbPostAttachCommands); QString postAttachCommands = stringSetting(GdbPostAttachCommands);
if (!postAttachCommands.isEmpty()) { if (!postAttachCommands.isEmpty()) {
foreach (const QString &cmd, postAttachCommands.split(QLatin1Char('\n'))) foreach (const QString &cmd, postAttachCommands.split(QLatin1Char('\n')))
postCommand(cmd.toLatin1()); runCommand(cmd.toLatin1());
} }
handleInferiorPrepared(); handleInferiorPrepared();
} else { } else {
@@ -307,15 +307,15 @@ void GdbRemoteServerEngine::handleTargetExtendedRemote(const DebuggerResponse &r
QString postAttachCommands = stringSetting(GdbPostAttachCommands); QString postAttachCommands = stringSetting(GdbPostAttachCommands);
if (!postAttachCommands.isEmpty()) { if (!postAttachCommands.isEmpty()) {
foreach (const QString &cmd, postAttachCommands.split(QLatin1Char('\n'))) foreach (const QString &cmd, postAttachCommands.split(QLatin1Char('\n')))
postCommand(cmd.toLatin1()); runCommand(cmd.toLatin1());
} }
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.
postCommand("attach " + QByteArray::number(runParameters().attachPID), runCommand("attach " + QByteArray::number(runParameters().attachPID),
NoFlags, CB(handleTargetExtendedAttach)); CB(handleTargetExtendedAttach));
} else { } else {
postCommand("-gdb-set remote exec-file " + runParameters().remoteExecutable.toLatin1(), runCommand("-gdb-set remote exec-file " + runParameters().remoteExecutable.toLatin1(),
NoFlags, CB(handleTargetExtendedAttach)); CB(handleTargetExtendedAttach));
} }
} else { } else {
QString msg = msgConnectRemoteServerFailed( QString msg = msgConnectRemoteServerFailed(
@@ -349,9 +349,9 @@ void GdbRemoteServerEngine::handleTargetQnx(const DebuggerResponse &response)
const qint64 pid = isMasterEngine() ? runParameters().attachPID : masterEngine()->runParameters().attachPID; const qint64 pid = isMasterEngine() ? runParameters().attachPID : masterEngine()->runParameters().attachPID;
const QString remoteExecutable = isMasterEngine() ? runParameters().remoteExecutable : masterEngine()->runParameters().remoteExecutable; const QString remoteExecutable = isMasterEngine() ? runParameters().remoteExecutable : masterEngine()->runParameters().remoteExecutable;
if (pid > -1) if (pid > -1)
postCommand("attach " + QByteArray::number(pid), NoFlags, CB(handleAttach)); runCommand("attach " + QByteArray::number(pid), CB(handleAttach));
else if (!remoteExecutable.isEmpty()) else if (!remoteExecutable.isEmpty())
postCommand("set nto-executable " + remoteExecutable.toLatin1(), NoFlags, CB(handleSetNtoExecutable)); runCommand("set nto-executable " + remoteExecutable.toLatin1(), CB(handleSetNtoExecutable));
else else
handleInferiorPrepared(); handleInferiorPrepared();
} else { } else {
@@ -409,7 +409,7 @@ void GdbRemoteServerEngine::runEngine()
const QString remoteExecutable = runParameters().remoteExecutable; const QString remoteExecutable = runParameters().remoteExecutable;
if (!remoteExecutable.isEmpty()) { if (!remoteExecutable.isEmpty()) {
postCommand("-exec-run", GdbEngine::RunRequest, CB(handleExecRun)); runCommand("-exec-run", CB(handleExecRun), RunRequest);
} else { } else {
notifyEngineRunAndInferiorStopOk(); notifyEngineRunAndInferiorStopOk();
continueInferiorInternal(); continueInferiorInternal();
@@ -434,7 +434,7 @@ void GdbRemoteServerEngine::interruptInferior2()
{ {
QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state()); QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state());
if (boolSetting(TargetAsync)) { if (boolSetting(TargetAsync)) {
postCommand("-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

@@ -134,8 +134,9 @@ 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), NoFlags, DebuggerCommand cmd("attach " + QByteArray::number(attachedPID));
[this](const DebuggerResponse &r) { handleStubAttached(r); }); cmd.callback = [this](const DebuggerResponse &r) { handleStubAttached(r); };
runCommand(cmd);
} }
void GdbTermEngine::handleStubAttached(const DebuggerResponse &response) void GdbTermEngine::handleStubAttached(const DebuggerResponse &response)