Commit cdf7dbea authored by hjk's avatar hjk

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()
m_d->checkVersion();
if (m_d->m_hDebuggeeProcess) {
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__);
emit startFailed();
return;
......@@ -395,7 +395,7 @@ void CdbDebugEngine::startDebugger()
case AttachCore:
case AttachToRemote:
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__);
emit startFailed();
break;
......@@ -405,7 +405,7 @@ void CdbDebugEngine::startDebugger()
m_d->m_mode = sp.startMode;
m_d->clearDisplay();
m_d->m_inferiorStartupComplete = false;
setState(AdapterStarted, Q_FUNC_INFO, __LINE__);
setState(EngineStarted, Q_FUNC_INFO, __LINE__);
// Options
QString errorMessage;
if (!m_d->setBreakOnThrow(theDebuggerBoolSetting(BreakOnThrow), &errorMessage))
......
......@@ -82,8 +82,8 @@ enum DebuggerState
EngineStarting, // Engine starts
AdapterStarting,
AdapterStarted,
AdapterStartFailed,
EngineStarted,
EngineStartFailed,
InferiorUnrunnable, // Used in the core dump adapter
InferiorStarting,
// InferiorStarted, // Use InferiorRunningRequested or InferiorStopped
......
......@@ -145,8 +145,8 @@ const char *DebuggerEngine::stateName(int s)
SN(DebuggerNotReady)
SN(EngineStarting)
SN(AdapterStarting)
SN(AdapterStarted)
SN(AdapterStartFailed)
SN(EngineStarted)
SN(EngineStartFailed)
SN(InferiorStarting)
SN(InferiorStartFailed)
SN(InferiorRunningRequested)
......@@ -912,10 +912,10 @@ static bool isAllowedTransition(int from, int to)
return to == AdapterStarting || to == DebuggerNotReady;
case AdapterStarting:
return to == AdapterStarted || to == AdapterStartFailed;
case AdapterStarted:
return to == EngineStarted || to == EngineStartFailed;
case EngineStarted:
return to == InferiorStarting || to == EngineShuttingDown;
case AdapterStartFailed:
case EngineStartFailed:
return to == DebuggerNotReady;
case InferiorStarting:
......@@ -997,8 +997,8 @@ bool DebuggerEngine::debuggerActionsEnabled(DebuggerState state)
case DebuggerNotReady:
case EngineStarting:
case AdapterStarting:
case AdapterStarted:
case AdapterStartFailed:
case EngineStarted:
case EngineStartFailed:
case InferiorStartFailed:
case InferiorRunningRequested_Kill:
case InferiorStopping_Kill:
......
......@@ -157,45 +157,92 @@
#endif
// 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'.
//
// 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
// |
// AdapterStarting --> AdapterStartFailed --> 0
// |
// AdapterStarted ------------------------------------.
// | v
// InferiorStarting ----> InferiorStartFailed -------->|
// | |
// (core) | (attach) (term) (remote) |
// .-----------------<-|->------------------. |
// | v | |
// InferiorUnrunnable | (plain) | |
// | | (trk) | |
// | | | |
// | .--> InferiorRunningRequested | |
// | | | | |
// | | InferiorRunning | |
// | | | | |
// | | InferiorStopping | |
// | | | | |
// | '------ InferiorStopped <-----------' |
// +
// +
// (calls *Engine->startEngine())
// | |
// | `---> EngineStartFailed
// | +
// | [calls RunControl->startFailed]
// | +
// | DebuggerNotReady
// v
// EngineStarted
// +
// [calls RunControl->StartSuccessful]
// +
// (calls *Engine->startInferior())
// | |
// | ` ----> InferiorStartFailed +-+-+-+->.
// | +
// v +
// InferiorStarted +
// +
// (calls *Engine->runInferior()) +
// | +
// (core) | (attach) (term) (remote) (script) +
// .-----------------<-|->------------------. +
// | v | +
// InferiorUnrunnable | (plain) | +
// | | (trk) | +
// | | | +
// | .--> InferiorRunningRequested | +
// | | | | +
// | | InferiorRunning | +
// | | | | +
// | | InferiorStopping | +
// | | | | +
// | '------ InferiorStopped <-----------' +
// | | v
// | InferiorShuttingDown -> InferiorShutdownFailed ---->|
// | | |
// | InferiorShutDown |
// | | |
// '--------> EngineShuttingDown <--------------------------------'
// | InferiorShuttingDown -> InferiorShutdownFailed ---->+
// | | +
// | InferiorShutDown +
// | | +
// '--------> EngineShuttingDown <-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+'
// |
// 0
// DebuggerNotReady
//
// GdbEngine specific startup. All happens in EngineStarting state
//
// Allowed actions:
// [R] : Run
// [C] : Continue
// [N] : Step, Next
// Transitions marked by '---' are done in the individual adapters.
// Transitions marked by '+-+' are done in the GdbEngine.
// GdbEngine::startEngine()
// +
// +
// (calls *Adapter->startAdapter())
// | |
// | `---> handleAdapterStartFailed()
// | +
// | EngineStartFailed
// |
// handleAdapterStarted()
// +
// (calls *Adapter->prepareInferior())
// | |
// | `---> handleAdapterStartFailed()
// | +
// | EngineStartFailed
// |
// handleInferiorPrepared()
// +
// EngineStarted
using namespace Core;
using namespace Debugger;
......@@ -2629,8 +2676,8 @@ bool DebuggerListener::coreAboutToClose()
switch (plugin->state()) {
case DebuggerNotReady:
return true;
case AdapterStarted: // Most importantly, terminating a running
case AdapterStartFailed: // debuggee can cause problems.
case EngineStarted: // Most importantly, terminating a running
case EngineStartFailed: // debuggee can cause problems.
case InferiorUnrunnable:
case InferiorStartFailed:
case InferiorStopped:
......
......@@ -123,8 +123,8 @@ static bool stateAcceptsGdbCommands(DebuggerState state)
{
switch (state) {
case AdapterStarting:
case AdapterStarted:
case AdapterStartFailed:
case EngineStarted:
case EngineStartFailed:
case InferiorUnrunnable:
case InferiorStarting:
case InferiorStartFailed:
......@@ -768,7 +768,7 @@ void GdbEngine::postCommandHelper(const GdbCommand &cmd)
} else if ((cmd.flags & NeedsStop)
|| !m_commandsToRunOnTemporaryBreak.isEmpty()) {
if (state() == InferiorStopped || state() == InferiorUnrunnable
|| state() == InferiorStarting || state() == AdapterStarted) {
|| state() == InferiorStarting || state() == EngineStarted) {
// Can be safely sent now.
flushCommand(cmd);
} else {
......@@ -1636,10 +1636,10 @@ void GdbEngine::shutdown()
case InferiorStopping_Kill:
break;
case AdapterStarting: // GDB is up, adapter is "doing something"
setState(AdapterStartFailed);
setState(EngineStartFailed);
m_gdbAdapter->shutdown();
// 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) {
m_commandsToRunOnTemporaryBreak.clear();
postCommand("-gdb-exit", GdbEngine::ExitRequest, CB(handleGdbExit));
......@@ -1655,7 +1655,7 @@ void GdbEngine::shutdown()
postCommand(m_gdbAdapter->inferiorShutdownCommand(),
NeedsStop | LosesChild, CB(handleInferiorShutdown));
break;
case AdapterStarted: // We can't get here, really
case EngineStarted: // We can't get here, really
case InferiorStartFailed:
case InferiorShutDown:
case InferiorShutdownFailed: // Whatever
......@@ -4207,7 +4207,7 @@ void GdbEngine::handleGdbFinished(int code, QProcess::ExitStatus type)
} else if (state() == EngineShuttingDown) {
showMessage(_("GOING TO SHUT DOWN ADAPTER"));
m_gdbAdapter->shutdown();
} else if (state() != AdapterStartFailed) {
} else if (state() != EngineStartFailed) {
QString msg = tr("The gdb process exited unexpectedly (%1).")
.arg((type == QProcess::CrashExit)
? tr("crashed") : tr("code %1").arg(code));
......@@ -4221,7 +4221,7 @@ void GdbEngine::handleGdbFinished(int code, QProcess::ExitStatus type)
void GdbEngine::handleAdapterStartFailed(const QString &msg, const QString &settingsIdHint)
{
setState(AdapterStartFailed);
setState(EngineStartFailed);
showMessage(_("ADAPTER START FAILED"));
if (!msg.isEmpty()) {
const QString title = tr("Adapter start failed");
......@@ -4237,7 +4237,7 @@ void GdbEngine::handleAdapterStartFailed(const QString &msg, const QString &sett
void GdbEngine::handleAdapterStarted()
{
setState(AdapterStarted);
setState(EngineStarted);
if (m_progress)
m_progress->setProgressValue(25);
showMessage(_("ADAPTER SUCCESSFULLY STARTED"));
......@@ -4286,7 +4286,7 @@ void GdbEngine::startInferiorPhase2()
void GdbEngine::handleInferiorStartFailed(const QString &msg)
{
showStatusMessage(tr("Failed to start application: ") + msg);
if (state() == AdapterStartFailed) {
if (state() == EngineStartFailed) {
showMessage(_("INFERIOR START FAILED, BUT ADAPTER DIED ALREADY"));
return; // Adapter crashed meanwhile, so this notification is meaningless.
}
......@@ -4305,7 +4305,7 @@ void GdbEngine::handleAdapterCrashed(const QString &msg)
// 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
// "path" which does not assert.
setState(AdapterStartFailed, true);
setState(EngineStartFailed, true);
// No point in being friendly here ...
gdbProc()->kill();
......
......@@ -182,7 +182,7 @@ void PdbEngine::startDebugger()
if (!m_pdbProc.waitForStarted()) {
const QString msg = tr("Unable to start pdb '%1': %2")
.arg(m_pdb, m_pdbProc.errorString());
setState(AdapterStartFailed);
setState(EngineStartFailed);
showMessage(_("ADAPTER START FAILED"));
if (!msg.isEmpty()) {
const QString title = tr("Adapter start failed");
......@@ -200,7 +200,7 @@ void PdbEngine::startDebugger()
postCommand("execfile('" + dumperSourcePath + "pdumper.py')",
CB(handleLoadDumper));
setState(AdapterStarted);
setState(EngineStarted);
setState(InferiorStarting);
emit startSuccessful();
showStatusMessage(tr("Running requested..."), 5000);
......
......@@ -255,11 +255,11 @@ void QmlEngine::startDebugger()
m_proc.start(sp.executable, sp.processArgs);
if (!m_proc.waitForStarted()) {
setState(AdapterStartFailed);
setState(EngineStartFailed);
startFailed();
return;
}
setState(AdapterStarted);
setState(EngineStarted);
startSuccessful();
setState(InferiorStarting);
......
......@@ -248,7 +248,7 @@ void ScriptEngine::startDebugger()
m_stopOnNextLine = false;
m_scriptEngine->abortEvaluation();
setState(AdapterStarted);
setState(EngineStarted);
setState(InferiorStarting);
m_scriptFileName = QFileInfo(startParameters().executable).absoluteFilePath();
......
......@@ -700,7 +700,7 @@ void QmlInspector::debuggerStateChanged(int newState)
m_connectionInitialized = false;
break;
}
case Debugger::AdapterStartFailed:
case Debugger::EngineStartFailed:
case Debugger::InferiorStartFailed:
emit statusMessage(QString(tr("Debugging failed: could not start C++ debugger.")));
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