fix shutdowns triggered while inferior is not stopped

Reviewed-by: hjk
This commit is contained in:
Oswald Buddenhagen
2009-11-02 16:59:57 +01:00
parent e2d468312c
commit a4f2396323
4 changed files with 58 additions and 9 deletions

View File

@@ -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: