Commit cdf7dbea authored by hjk's avatar hjk
Browse files

debugger: start refactoring of state transitions

This updates the state diagram in debuggerplugin.cpp and
renames AdapterStart{Fail}ed to EngineStart{Fail}ed.
parent 8d7ee24a
...@@ -386,7 +386,7 @@ void CdbDebugEngine::startDebugger() ...@@ -386,7 +386,7 @@ void CdbDebugEngine::startDebugger()
m_d->checkVersion(); m_d->checkVersion();
if (m_d->m_hDebuggeeProcess) { if (m_d->m_hDebuggeeProcess) {
warning(QLatin1String("Internal error: Attempt to start debugger while another process is being debugged.")); warning(QLatin1String("Internal error: Attempt to start debugger while another process is being debugged."));
setState(AdapterStartFailed, Q_FUNC_INFO, __LINE__); setState(EngineStartFailed, Q_FUNC_INFO, __LINE__);
setState(DebuggerNotReady, Q_FUNC_INFO, __LINE__); setState(DebuggerNotReady, Q_FUNC_INFO, __LINE__);
emit startFailed(); emit startFailed();
return; return;
...@@ -395,7 +395,7 @@ void CdbDebugEngine::startDebugger() ...@@ -395,7 +395,7 @@ void CdbDebugEngine::startDebugger()
case AttachCore: case AttachCore:
case AttachToRemote: case AttachToRemote:
warning(QLatin1String("Internal error: Mode not supported.")); warning(QLatin1String("Internal error: Mode not supported."));
setState(AdapterStartFailed, Q_FUNC_INFO, __LINE__); setState(EngineStartFailed, Q_FUNC_INFO, __LINE__);
setState(DebuggerNotReady, Q_FUNC_INFO, __LINE__); setState(DebuggerNotReady, Q_FUNC_INFO, __LINE__);
emit startFailed(); emit startFailed();
break; break;
...@@ -405,7 +405,7 @@ void CdbDebugEngine::startDebugger() ...@@ -405,7 +405,7 @@ void CdbDebugEngine::startDebugger()
m_d->m_mode = sp.startMode; m_d->m_mode = sp.startMode;
m_d->clearDisplay(); m_d->clearDisplay();
m_d->m_inferiorStartupComplete = false; m_d->m_inferiorStartupComplete = false;
setState(AdapterStarted, Q_FUNC_INFO, __LINE__); setState(EngineStarted, Q_FUNC_INFO, __LINE__);
// Options // Options
QString errorMessage; QString errorMessage;
if (!m_d->setBreakOnThrow(theDebuggerBoolSetting(BreakOnThrow), &errorMessage)) if (!m_d->setBreakOnThrow(theDebuggerBoolSetting(BreakOnThrow), &errorMessage))
......
...@@ -82,8 +82,8 @@ enum DebuggerState ...@@ -82,8 +82,8 @@ enum DebuggerState
EngineStarting, // Engine starts EngineStarting, // Engine starts
AdapterStarting, AdapterStarting,
AdapterStarted, EngineStarted,
AdapterStartFailed, EngineStartFailed,
InferiorUnrunnable, // Used in the core dump adapter InferiorUnrunnable, // Used in the core dump adapter
InferiorStarting, InferiorStarting,
// InferiorStarted, // Use InferiorRunningRequested or InferiorStopped // InferiorStarted, // Use InferiorRunningRequested or InferiorStopped
......
...@@ -145,8 +145,8 @@ const char *DebuggerEngine::stateName(int s) ...@@ -145,8 +145,8 @@ const char *DebuggerEngine::stateName(int s)
SN(DebuggerNotReady) SN(DebuggerNotReady)
SN(EngineStarting) SN(EngineStarting)
SN(AdapterStarting) SN(AdapterStarting)
SN(AdapterStarted) SN(EngineStarted)
SN(AdapterStartFailed) SN(EngineStartFailed)
SN(InferiorStarting) SN(InferiorStarting)
SN(InferiorStartFailed) SN(InferiorStartFailed)
SN(InferiorRunningRequested) SN(InferiorRunningRequested)
...@@ -912,10 +912,10 @@ static bool isAllowedTransition(int from, int to) ...@@ -912,10 +912,10 @@ static bool isAllowedTransition(int from, int to)
return to == AdapterStarting || to == DebuggerNotReady; return to == AdapterStarting || to == DebuggerNotReady;
case AdapterStarting: case AdapterStarting:
return to == AdapterStarted || to == AdapterStartFailed; return to == EngineStarted || to == EngineStartFailed;
case AdapterStarted: case EngineStarted:
return to == InferiorStarting || to == EngineShuttingDown; return to == InferiorStarting || to == EngineShuttingDown;
case AdapterStartFailed: case EngineStartFailed:
return to == DebuggerNotReady; return to == DebuggerNotReady;
case InferiorStarting: case InferiorStarting:
...@@ -997,8 +997,8 @@ bool DebuggerEngine::debuggerActionsEnabled(DebuggerState state) ...@@ -997,8 +997,8 @@ bool DebuggerEngine::debuggerActionsEnabled(DebuggerState state)
case DebuggerNotReady: case DebuggerNotReady:
case EngineStarting: case EngineStarting:
case AdapterStarting: case AdapterStarting:
case AdapterStarted: case EngineStarted:
case AdapterStartFailed: case EngineStartFailed:
case InferiorStartFailed: case InferiorStartFailed:
case InferiorRunningRequested_Kill: case InferiorRunningRequested_Kill:
case InferiorStopping_Kill: case InferiorStopping_Kill:
......
...@@ -157,45 +157,92 @@ ...@@ -157,45 +157,92 @@
#endif #endif
// Note: the Debugger process itself and any helper processes like // Note: the Debugger process itself and any helper processes like
// gdbserver, the trk client etc are referred to as 'Adapter', // gdbserver, the trk client etc are referred to as 'Engine',
// whereas the debugged process is referred to as 'Inferior'. // whereas the debugged process is referred to as 'Inferior'.
// //
// 0 == DebuggerNotReady // Transitions marked by '---' are done in the individual engines.
// | // Transitions marked by '+-+' are done in the base DebuggerEngine.
// The GdbEngine->startEngine() function is described in more detail below.
//
// DebuggerNotReady
// +
// +
// EngineStarting // EngineStarting
// | // +
// AdapterStarting --> AdapterStartFailed --> 0 // +
// | // (calls *Engine->startEngine())
// AdapterStarted ------------------------------------. // | |
// | v // | `---> EngineStartFailed
// InferiorStarting ----> InferiorStartFailed -------->| // | +
// | | // | [calls RunControl->startFailed]
// (core) | (attach) (term) (remote) | // | +
// .-----------------<-|->------------------. | // | DebuggerNotReady
// | v | | // v
// InferiorUnrunnable | (plain) | | // EngineStarted
// | | (trk) | | // +
// | | | | // [calls RunControl->StartSuccessful]
// | .--> InferiorRunningRequested | | // +
// | | | | | // (calls *Engine->startInferior())
// | | InferiorRunning | | // | |
// | | | | | // | ` ----> InferiorStartFailed +-+-+-+->.
// | | InferiorStopping | | // | +
// | | | | | // v +
// | '------ InferiorStopped <-----------' | // InferiorStarted +
// +
// (calls *Engine->runInferior()) +
// | +
// (core) | (attach) (term) (remote) (script) +
// .-----------------<-|->------------------. +
// | v | +
// InferiorUnrunnable | (plain) | +
// | | (trk) | +
// | | | +
// | .--> InferiorRunningRequested | +
// | | | | +
// | | InferiorRunning | +
// | | | | +
// | | InferiorStopping | +
// | | | | +
// | '------ InferiorStopped <-----------' +
// | | v // | | v
// | InferiorShuttingDown -> InferiorShutdownFailed ---->| // | InferiorShuttingDown -> InferiorShutdownFailed ---->+
// | | | // | | +
// | InferiorShutDown | // | InferiorShutDown +
// | | | // | | +
// '--------> EngineShuttingDown <--------------------------------' // '--------> EngineShuttingDown <-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+'
// | // |
// 0 // DebuggerNotReady
//
// GdbEngine specific startup. All happens in EngineStarting state
// //
// Allowed actions: // Transitions marked by '---' are done in the individual adapters.
// [R] : Run // Transitions marked by '+-+' are done in the GdbEngine.
// [C] : Continue
// [N] : Step, Next // GdbEngine::startEngine()
// +
// +
// (calls *Adapter->startAdapter())
// | |
// | `---> handleAdapterStartFailed()
// | +
// | EngineStartFailed
// |
// handleAdapterStarted()
// +
// (calls *Adapter->prepareInferior())
// | |
// | `---> handleAdapterStartFailed()
// | +
// | EngineStartFailed
// |
// handleInferiorPrepared()
// +
// EngineStarted
using namespace Core; using namespace Core;
using namespace Debugger; using namespace Debugger;
...@@ -2629,8 +2676,8 @@ bool DebuggerListener::coreAboutToClose() ...@@ -2629,8 +2676,8 @@ bool DebuggerListener::coreAboutToClose()
switch (plugin->state()) { switch (plugin->state()) {
case DebuggerNotReady: case DebuggerNotReady:
return true; return true;
case AdapterStarted: // Most importantly, terminating a running case EngineStarted: // Most importantly, terminating a running
case AdapterStartFailed: // debuggee can cause problems. case EngineStartFailed: // debuggee can cause problems.
case InferiorUnrunnable: case InferiorUnrunnable:
case InferiorStartFailed: case InferiorStartFailed:
case InferiorStopped: case InferiorStopped:
......
...@@ -123,8 +123,8 @@ static bool stateAcceptsGdbCommands(DebuggerState state) ...@@ -123,8 +123,8 @@ static bool stateAcceptsGdbCommands(DebuggerState state)
{ {
switch (state) { switch (state) {
case AdapterStarting: case AdapterStarting:
case AdapterStarted: case EngineStarted:
case AdapterStartFailed: case EngineStartFailed:
case InferiorUnrunnable: case InferiorUnrunnable:
case InferiorStarting: case InferiorStarting:
case InferiorStartFailed: case InferiorStartFailed:
...@@ -768,7 +768,7 @@ void GdbEngine::postCommandHelper(const GdbCommand &cmd) ...@@ -768,7 +768,7 @@ void GdbEngine::postCommandHelper(const GdbCommand &cmd)
} else if ((cmd.flags & NeedsStop) } else if ((cmd.flags & NeedsStop)
|| !m_commandsToRunOnTemporaryBreak.isEmpty()) { || !m_commandsToRunOnTemporaryBreak.isEmpty()) {
if (state() == InferiorStopped || state() == InferiorUnrunnable if (state() == InferiorStopped || state() == InferiorUnrunnable
|| state() == InferiorStarting || state() == AdapterStarted) { || state() == InferiorStarting || state() == EngineStarted) {
// Can be safely sent now. // Can be safely sent now.
flushCommand(cmd); flushCommand(cmd);
} else { } else {
...@@ -1636,10 +1636,10 @@ void GdbEngine::shutdown() ...@@ -1636,10 +1636,10 @@ void GdbEngine::shutdown()
case InferiorStopping_Kill: case InferiorStopping_Kill:
break; break;
case AdapterStarting: // GDB is up, adapter is "doing something" case AdapterStarting: // GDB is up, adapter is "doing something"
setState(AdapterStartFailed); setState(EngineStartFailed);
m_gdbAdapter->shutdown(); m_gdbAdapter->shutdown();
// fall-through // fall-through
case AdapterStartFailed: // Adapter "did something", but it did not help case EngineStartFailed: // Adapter "did something", but it did not help
if (gdbProc()->state() == QProcess::Running) { if (gdbProc()->state() == QProcess::Running) {
m_commandsToRunOnTemporaryBreak.clear(); m_commandsToRunOnTemporaryBreak.clear();
postCommand("-gdb-exit", GdbEngine::ExitRequest, CB(handleGdbExit)); postCommand("-gdb-exit", GdbEngine::ExitRequest, CB(handleGdbExit));
...@@ -1655,7 +1655,7 @@ void GdbEngine::shutdown() ...@@ -1655,7 +1655,7 @@ void GdbEngine::shutdown()
postCommand(m_gdbAdapter->inferiorShutdownCommand(), postCommand(m_gdbAdapter->inferiorShutdownCommand(),
NeedsStop | LosesChild, CB(handleInferiorShutdown)); NeedsStop | LosesChild, CB(handleInferiorShutdown));
break; break;
case AdapterStarted: // We can't get here, really case EngineStarted: // We can't get here, really
case InferiorStartFailed: case InferiorStartFailed:
case InferiorShutDown: case InferiorShutDown:
case InferiorShutdownFailed: // Whatever case InferiorShutdownFailed: // Whatever
...@@ -4207,7 +4207,7 @@ void GdbEngine::handleGdbFinished(int code, QProcess::ExitStatus type) ...@@ -4207,7 +4207,7 @@ void GdbEngine::handleGdbFinished(int code, QProcess::ExitStatus type)
} else if (state() == EngineShuttingDown) { } else if (state() == EngineShuttingDown) {
showMessage(_("GOING TO SHUT DOWN ADAPTER")); showMessage(_("GOING TO SHUT DOWN ADAPTER"));
m_gdbAdapter->shutdown(); m_gdbAdapter->shutdown();
} else if (state() != AdapterStartFailed) { } else if (state() != EngineStartFailed) {
QString msg = tr("The gdb process exited unexpectedly (%1).") QString msg = tr("The gdb process exited unexpectedly (%1).")
.arg((type == QProcess::CrashExit) .arg((type == QProcess::CrashExit)
? tr("crashed") : tr("code %1").arg(code)); ? tr("crashed") : tr("code %1").arg(code));
...@@ -4221,7 +4221,7 @@ void GdbEngine::handleGdbFinished(int code, QProcess::ExitStatus type) ...@@ -4221,7 +4221,7 @@ void GdbEngine::handleGdbFinished(int code, QProcess::ExitStatus type)
void GdbEngine::handleAdapterStartFailed(const QString &msg, const QString &settingsIdHint) void GdbEngine::handleAdapterStartFailed(const QString &msg, const QString &settingsIdHint)
{ {
setState(AdapterStartFailed); setState(EngineStartFailed);
showMessage(_("ADAPTER START FAILED")); showMessage(_("ADAPTER START FAILED"));
if (!msg.isEmpty()) { if (!msg.isEmpty()) {
const QString title = tr("Adapter start failed"); const QString title = tr("Adapter start failed");
...@@ -4237,7 +4237,7 @@ void GdbEngine::handleAdapterStartFailed(const QString &msg, const QString &sett ...@@ -4237,7 +4237,7 @@ void GdbEngine::handleAdapterStartFailed(const QString &msg, const QString &sett
void GdbEngine::handleAdapterStarted() void GdbEngine::handleAdapterStarted()
{ {
setState(AdapterStarted); setState(EngineStarted);
if (m_progress) if (m_progress)
m_progress->setProgressValue(25); m_progress->setProgressValue(25);
showMessage(_("ADAPTER SUCCESSFULLY STARTED")); showMessage(_("ADAPTER SUCCESSFULLY STARTED"));
...@@ -4286,7 +4286,7 @@ void GdbEngine::startInferiorPhase2() ...@@ -4286,7 +4286,7 @@ void GdbEngine::startInferiorPhase2()
void GdbEngine::handleInferiorStartFailed(const QString &msg) void GdbEngine::handleInferiorStartFailed(const QString &msg)
{ {
showStatusMessage(tr("Failed to start application: ") + msg); showStatusMessage(tr("Failed to start application: ") + msg);
if (state() == AdapterStartFailed) { if (state() == EngineStartFailed) {
showMessage(_("INFERIOR START FAILED, BUT ADAPTER DIED ALREADY")); showMessage(_("INFERIOR START FAILED, BUT ADAPTER DIED ALREADY"));
return; // Adapter crashed meanwhile, so this notification is meaningless. return; // Adapter crashed meanwhile, so this notification is meaningless.
} }
...@@ -4305,7 +4305,7 @@ void GdbEngine::handleAdapterCrashed(const QString &msg) ...@@ -4305,7 +4305,7 @@ void GdbEngine::handleAdapterCrashed(const QString &msg)
// Don't bother with state transitions - this can happen in any state and // Don't bother with state transitions - this can happen in any state and
// the end result is always the same, so it makes little sense to find a // the end result is always the same, so it makes little sense to find a
// "path" which does not assert. // "path" which does not assert.
setState(AdapterStartFailed, true); setState(EngineStartFailed, true);
// No point in being friendly here ... // No point in being friendly here ...
gdbProc()->kill(); gdbProc()->kill();
......
...@@ -182,7 +182,7 @@ void PdbEngine::startDebugger() ...@@ -182,7 +182,7 @@ void PdbEngine::startDebugger()
if (!m_pdbProc.waitForStarted()) { if (!m_pdbProc.waitForStarted()) {
const QString msg = tr("Unable to start pdb '%1': %2") const QString msg = tr("Unable to start pdb '%1': %2")
.arg(m_pdb, m_pdbProc.errorString()); .arg(m_pdb, m_pdbProc.errorString());
setState(AdapterStartFailed); setState(EngineStartFailed);
showMessage(_("ADAPTER START FAILED")); showMessage(_("ADAPTER START FAILED"));
if (!msg.isEmpty()) { if (!msg.isEmpty()) {
const QString title = tr("Adapter start failed"); const QString title = tr("Adapter start failed");
...@@ -200,7 +200,7 @@ void PdbEngine::startDebugger() ...@@ -200,7 +200,7 @@ void PdbEngine::startDebugger()
postCommand("execfile('" + dumperSourcePath + "pdumper.py')", postCommand("execfile('" + dumperSourcePath + "pdumper.py')",
CB(handleLoadDumper)); CB(handleLoadDumper));
setState(AdapterStarted); setState(EngineStarted);
setState(InferiorStarting); setState(InferiorStarting);
emit startSuccessful(); emit startSuccessful();
showStatusMessage(tr("Running requested..."), 5000); showStatusMessage(tr("Running requested..."), 5000);
......
...@@ -255,11 +255,11 @@ void QmlEngine::startDebugger() ...@@ -255,11 +255,11 @@ void QmlEngine::startDebugger()
m_proc.start(sp.executable, sp.processArgs); m_proc.start(sp.executable, sp.processArgs);
if (!m_proc.waitForStarted()) { if (!m_proc.waitForStarted()) {
setState(AdapterStartFailed); setState(EngineStartFailed);
startFailed(); startFailed();
return; return;
} }
setState(AdapterStarted); setState(EngineStarted);
startSuccessful(); startSuccessful();
setState(InferiorStarting); setState(InferiorStarting);
......
...@@ -248,7 +248,7 @@ void ScriptEngine::startDebugger() ...@@ -248,7 +248,7 @@ void ScriptEngine::startDebugger()
m_stopOnNextLine = false; m_stopOnNextLine = false;
m_scriptEngine->abortEvaluation(); m_scriptEngine->abortEvaluation();
setState(AdapterStarted); setState(EngineStarted);
setState(InferiorStarting); setState(InferiorStarting);
m_scriptFileName = QFileInfo(startParameters().executable).absoluteFilePath(); m_scriptFileName = QFileInfo(startParameters().executable).absoluteFilePath();
......
...@@ -700,7 +700,7 @@ void QmlInspector::debuggerStateChanged(int newState) ...@@ -700,7 +700,7 @@ void QmlInspector::debuggerStateChanged(int newState)
m_connectionInitialized = false; m_connectionInitialized = false;
break; break;
} }
case Debugger::AdapterStartFailed: case Debugger::EngineStartFailed:
case Debugger::InferiorStartFailed: case Debugger::InferiorStartFailed:
emit statusMessage(QString(tr("Debugging failed: could not start C++ debugger."))); emit statusMessage(QString(tr("Debugging failed: could not start C++ debugger.")));
break; break;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment