summaryrefslogtreecommitdiff
path: root/src/plugins/debugger
diff options
context:
space:
mode:
authorOswald Buddenhagen <oswald.buddenhagen@nokia.com>2009-11-02 16:59:57 +0100
committerOswald Buddenhagen <oswald.buddenhagen@nokia.com>2009-11-02 17:13:47 +0100
commita4f23963237cc9f8abd6cbc8c405949044f36b3f (patch)
tree31cdf1bcefcbcf6a3e01b83c6b75648db05a536f /src/plugins/debugger
parente2d468312cf12f7d74633d7aea3553563e135bb3 (diff)
downloadqt-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.h2
-rw-r--r--src/plugins/debugger/debuggermanager.cpp10
-rw-r--r--src/plugins/debugger/gdb/gdbengine.cpp49
-rw-r--r--src/plugins/debugger/gdb/gdbengine.h6
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);