diff options
author | Oswald Buddenhagen <oswald.buddenhagen@nokia.com> | 2009-11-02 16:59:57 +0100 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@nokia.com> | 2009-11-02 17:13:47 +0100 |
commit | a4f23963237cc9f8abd6cbc8c405949044f36b3f (patch) | |
tree | 31cdf1bcefcbcf6a3e01b83c6b75648db05a536f /src/plugins/debugger | |
parent | e2d468312cf12f7d74633d7aea3553563e135bb3 (diff) | |
download | qt-creator-a4f23963237cc9f8abd6cbc8c405949044f36b3f.tar.gz |
fix shutdowns triggered while inferior is not stopped
Reviewed-by: hjk
Diffstat (limited to 'src/plugins/debugger')
-rw-r--r-- | src/plugins/debugger/debuggerconstants.h | 2 | ||||
-rw-r--r-- | src/plugins/debugger/debuggermanager.cpp | 10 | ||||
-rw-r--r-- | src/plugins/debugger/gdb/gdbengine.cpp | 49 | ||||
-rw-r--r-- | src/plugins/debugger/gdb/gdbengine.h | 6 |
4 files changed, 58 insertions, 9 deletions
diff --git a/src/plugins/debugger/debuggerconstants.h b/src/plugins/debugger/debuggerconstants.h index d3bc9d20f4..53874f23cc 100644 --- a/src/plugins/debugger/debuggerconstants.h +++ b/src/plugins/debugger/debuggerconstants.h @@ -75,9 +75,11 @@ enum DebuggerState InferiorStartFailed, InferiorRunningRequested, // Debuggee requested to run + InferiorRunningRequested_Kill, // Debuggee requested to run, but want to kill it InferiorRunning, // Debuggee running InferiorStopping, // Debuggee running, stop requested + InferiorStopping_Kill, // Debuggee running, stop requested, want to kill it InferiorStopped, // Debuggee stopped InferiorStopFailed, // Debuggee not stopped, will kill debugger diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp index 04330ea217..0192429b07 100644 --- a/src/plugins/debugger/debuggermanager.cpp +++ b/src/plugins/debugger/debuggermanager.cpp @@ -192,9 +192,11 @@ const char *DebuggerManager::stateName(int s) SN(InferiorStarting) SN(InferiorStartFailed) SN(InferiorRunningRequested) + SN(InferiorRunningRequested_Kill) SN(InferiorRunning) SN(InferiorUnrunnable) SN(InferiorStopping) + SN(InferiorStopping_Kill) SN(InferiorStopped) SN(InferiorStopFailed) SN(InferiorShuttingDown) @@ -1578,11 +1580,17 @@ static bool isAllowedTransition(int from, int to) return to == EngineShuttingDown; case InferiorRunningRequested: + return to == InferiorRunning || to == InferiorStopped + || to == InferiorRunningRequested_Kill; + case InferiorRunningRequested_Kill: return to == InferiorRunning || to == InferiorStopped; case InferiorRunning: return to == InferiorStopping; case InferiorStopping: + return to == InferiorStopped || to == InferiorStopFailed + || to == InferiorStopping_Kill; + case InferiorStopping_Kill: return to == InferiorStopped || to == InferiorStopFailed; case InferiorStopped: return to == InferiorRunningRequested || to == InferiorShuttingDown; @@ -1705,6 +1713,8 @@ bool DebuggerManager::debuggerActionsEnabled() const case AdapterStarted: case AdapterStartFailed: case InferiorStartFailed: + case InferiorRunningRequested_Kill: + case InferiorStopping_Kill: case InferiorStopFailed: case InferiorShuttingDown: case InferiorShutDown: diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index d36686d385..aa7abd0108 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -115,8 +115,10 @@ static bool stateAcceptsGdbCommands(DebuggerState state) case InferiorStarting: case InferiorStartFailed: case InferiorRunningRequested: + case InferiorRunningRequested_Kill: case InferiorRunning: case InferiorStopping: + case InferiorStopping_Kill: case InferiorStopped: case InferiorShuttingDown: case InferiorShutDown: @@ -649,6 +651,16 @@ void GdbEngine::interruptInferior() m_gdbAdapter->interruptInferior(); } +void GdbEngine::interruptInferiorTemporarily() +{ + interruptInferior(); + foreach (const GdbCommand &cmd, m_commandsToRunOnTemporaryBreak) + if (cmd.flags & LosesChild) { + setState(InferiorStopping_Kill); + break; + } +} + void GdbEngine::maybeHandleInferiorPidChanged(const QString &pid0) { const qint64 pid = pid0.toLongLong(); @@ -731,12 +743,20 @@ void GdbEngine::postCommandHelper(const GdbCommand &cmd) debugMessage(_("QUEUING COMMAND ") + cmd.command); m_commandsToRunOnTemporaryBreak.append(cmd); if (state() == InferiorStopping) { + if (cmd.flags & LosesChild) + setState(InferiorStopping_Kill); debugMessage(_("CHILD ALREADY BEING INTERRUPTED")); + } else if (state() == InferiorStopping_Kill) { + debugMessage(_("CHILD ALREADY BEING INTERRUPTED (KILL PENDING)")); } else if (state() == InferiorRunningRequested) { + if (cmd.flags & LosesChild) + setState(InferiorRunningRequested_Kill); debugMessage(_("RUNNING REQUESTED; POSTPONING INTERRUPT")); + } else if (state() == InferiorRunningRequested_Kill) { + debugMessage(_("RUNNING REQUESTED; POSTPONING INTERRUPT (KILL PENDING)")); } else if (state() == InferiorRunning) { showStatusMessage(tr("Stopping temporarily."), 1000); - interruptInferior(); + interruptInferiorTemporarily(); } else { qDebug() << "ATTEMPTING TO QUEUE COMMAND IN INAPPROPRIATE STATE" << state(); } @@ -775,6 +795,9 @@ void GdbEngine::flushCommand(const GdbCommand &cmd0) gdbInputAvailable(LogInput, cmd.command); m_gdbAdapter->write(cmd.command.toLatin1() + "\r\n"); + + if (cmd.flags & LosesChild) + setState(InferiorShuttingDown); } void GdbEngine::handleResultRecord(GdbResponse *response) @@ -888,7 +911,7 @@ void GdbEngine::handleResultRecord(GdbResponse *response) // This is done after the command callbacks so the running-requesting commands // can assert on the right state. if (state() == InferiorRunning && !m_commandsToRunOnTemporaryBreak.isEmpty()) - interruptInferior(); + interruptInferiorTemporarily(); // Continue only if there are no commands wire anymore, so this will // be fully synchroneous. @@ -1075,11 +1098,16 @@ void GdbEngine::handleStopResponse(const GdbMi &data) } if (!m_commandsToRunOnTemporaryBreak.isEmpty()) { - QTC_ASSERT(state() == InferiorStopping, qDebug() << state()) + QTC_ASSERT(state() == InferiorStopping || state() == InferiorStopping_Kill, + qDebug() << state()) setState(InferiorStopped); flushQueuedCommands(); - QTC_ASSERT(m_commandsDoneCallback == 0, /**/); - m_commandsDoneCallback = &GdbEngine::autoContinueInferior; + if (state() == InferiorStopped) { + QTC_ASSERT(m_commandsDoneCallback == 0, /**/); + m_commandsDoneCallback = &GdbEngine::autoContinueInferior; + } else { + QTC_ASSERT(state() == InferiorShuttingDown, qDebug() << state()) + } return; } @@ -1320,6 +1348,12 @@ void GdbEngine::handleExecContinue(const GdbResponse &response) // The "running" state is picked up in handleResponse() QTC_ASSERT(state() == InferiorRunning, /**/); } else { + if (state() == InferiorRunningRequested_Kill) { + setState(InferiorStopped); + m_commandsToRunOnTemporaryBreak.clear(); + shutdown(); + return; + } QTC_ASSERT(state() == InferiorRunningRequested, /**/); setState(InferiorStopped); QByteArray msg = response.data.findChild("msg").data(); @@ -1369,6 +1403,8 @@ void GdbEngine::shutdown() case EngineStarting: // We can't get here, really case InferiorShuttingDown: // Will auto-trigger further shutdown steps case EngineShuttingDown: // Do not disturb! :) + case InferiorRunningRequested_Kill: + case InferiorStopping_Kill: break; case AdapterStarting: // GDB is up, adapter is "doing something" setState(AdapterStartFailed); @@ -1388,8 +1424,7 @@ void GdbEngine::shutdown() case InferiorStopped: // FIXME set some timeout? postCommand(_(m_gdbAdapter->inferiorShutdownCommand()), - NeedsStop, CB(handleInferiorShutdown)); - setState(InferiorShuttingDown); // Do it after posting the command! + NeedsStop | LosesChild, CB(handleInferiorShutdown)); break; case AdapterStarted: // We can't get here, really case InferiorStartFailed: diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index 665e77688d..ab39b4101c 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -176,8 +176,9 @@ private: ////////// Gdb Command Management ////////// RebuildModel = 4, // Trigger model rebuild when no such commands are pending any more WatchUpdate = Discardable | RebuildModel, EmbedToken = 8, // Expand %1 in the command to the command token - RunRequest = 16, // Callback expect GdbResultRunning instead of GdbResultDone - ExitRequest = 32 // Callback expect GdbResultExit instead of GdbResultDone + RunRequest = 16, // Callback expects GdbResultRunning instead of GdbResultDone + ExitRequest = 32, // Callback expects GdbResultExit instead of GdbResultDone + LosesChild = 64 // Auto-set inferior shutdown related states }; Q_DECLARE_FLAGS(GdbCommandFlags, GdbCommandFlag) private: @@ -283,6 +284,7 @@ private: ////////// Inferior Management ////////// void autoContinueInferior(); virtual void continueInferior(); virtual void interruptInferior(); + void interruptInferiorTemporarily(); virtual void runToLineExec(const QString &fileName, int lineNumber); virtual void runToFunctionExec(const QString &functionName); |