debugger: cleaner debugger aborting

Make the second "Abort Debugger" kill the gdb process directly
instead of relying on further communication.

Also fix some "unexpected" (but harmless) state transitions.

Change-Id: I0938ec76420fbd77ec4b7348819dd7f63763547f
Reviewed-by: hjk <qthjk@ovi.com>
This commit is contained in:
hjk
2011-10-31 17:36:08 +01:00
committed by hjk
parent 384a8ed1cf
commit 755f5fc327
6 changed files with 43 additions and 14 deletions

View File

@@ -60,7 +60,7 @@ const char INTERRUPT[] = "Debugger.Interrupt";
const char CONTINUE[] = "Debugger.Continue"; const char CONTINUE[] = "Debugger.Continue";
const char STOP[] = "Debugger.Stop"; const char STOP[] = "Debugger.Stop";
const char HIDDEN_STOP[] = "Debugger.HiddenStop"; const char HIDDEN_STOP[] = "Debugger.HiddenStop";
const char RESET[] = "Debugger.Reset"; const char ABORT[] = "Debugger.Abort";
const char STEP[] = "Debugger.StepLine"; const char STEP[] = "Debugger.StepLine";
const char STEPOUT[] = "Debugger.StepOut"; const char STEPOUT[] = "Debugger.StepOut";
const char NEXT[] = "Debugger.NextLine"; const char NEXT[] = "Debugger.NextLine";

View File

@@ -1209,7 +1209,7 @@ bool DebuggerEngine::isReverseDebugging() const
// Called by DebuggerRunControl. // Called by DebuggerRunControl.
void DebuggerEngine::quitDebugger() void DebuggerEngine::quitDebugger()
{ {
showMessage("QUIT DEBUGGER REQUESTED"); showMessage(_("QUIT DEBUGGER REQUESTED IN STATE %1").arg(state()));
d->m_targetState = DebuggerFinished; d->m_targetState = DebuggerFinished;
switch (state()) { switch (state()) {
case InferiorStopOk: case InferiorStopOk:
@@ -1225,6 +1225,9 @@ void DebuggerEngine::quitDebugger()
case EngineRunFailed: case EngineRunFailed:
case DebuggerFinished: case DebuggerFinished:
break; break;
case InferiorSetupRequested:
notifyInferiorSetupFailed();
break;
default: default:
// FIXME: We should disable the actions connected to that. // FIXME: We should disable the actions connected to that.
notifyInferiorIll(); notifyInferiorIll();
@@ -1232,6 +1235,12 @@ void DebuggerEngine::quitDebugger()
} }
} }
void DebuggerEngine::abortDebugger()
{
// Overridden in e.g. GdbEngine.
quitDebugger();
}
void DebuggerEngine::requestInterruptInferior() void DebuggerEngine::requestInterruptInferior()
{ {
d->doInterruptInferior(); d->doInterruptInferior();

View File

@@ -267,6 +267,7 @@ public:
virtual void resetLocation(); virtual void resetLocation();
virtual void gotoLocation(const Internal::Location &location); virtual void gotoLocation(const Internal::Location &location);
virtual void quitDebugger(); // called by DebuggerRunControl virtual void quitDebugger(); // called by DebuggerRunControl
virtual void abortDebugger(); // called by DebuggerPlugin
virtual void updateViews(); virtual void updateViews();
bool isSlaveEngine() const; bool isSlaveEngine() const;

View File

@@ -809,10 +809,10 @@ public slots:
currentEngine()->requestInterruptInferior(); currentEngine()->requestInterruptInferior();
} }
void handleExecReset() void handleAbort()
{ {
currentEngine()->resetLocation(); currentEngine()->resetLocation();
currentEngine()->notifyEngineIll(); // FIXME: Check. currentEngine()->abortDebugger();
} }
void handleExecStep() void handleExecStep()
@@ -1040,7 +1040,7 @@ public:
QAction *m_exitAction; // On application output button if "Stop" is possible QAction *m_exitAction; // On application output button if "Stop" is possible
QAction *m_interruptAction; // On the fat debug button if "Pause" is possible QAction *m_interruptAction; // On the fat debug button if "Pause" is possible
QAction *m_undisturbableAction; // On the fat debug button if nothing can be done QAction *m_undisturbableAction; // On the fat debug button if nothing can be done
QAction *m_resetAction; QAction *m_abortAction;
QAction *m_stepAction; QAction *m_stepAction;
QAction *m_stepOutAction; QAction *m_stepOutAction;
QAction *m_runToLineAction; // In the debug menu QAction *m_runToLineAction; // In the debug menu
@@ -2070,7 +2070,7 @@ void DebuggerPluginPrivate::setInitialState()
action(OperateByInstruction)->setEnabled(false); action(OperateByInstruction)->setEnabled(false);
m_exitAction->setEnabled(false); m_exitAction->setEnabled(false);
m_resetAction->setEnabled(false); m_abortAction->setEnabled(false);
m_interruptAction->setEnabled(false); m_interruptAction->setEnabled(false);
m_continueAction->setEnabled(false); m_continueAction->setEnabled(false);
@@ -2201,7 +2201,7 @@ void DebuggerPluginPrivate::updateState(DebuggerEngine *engine)
&& (stopped || isCore); && (stopped || isCore);
action(OperateByInstruction)->setEnabled(canOperateByInstruction); action(OperateByInstruction)->setEnabled(canOperateByInstruction);
m_resetAction->setEnabled(state != DebuggerNotReady m_abortAction->setEnabled(state != DebuggerNotReady
&& state != DebuggerFinished); && state != DebuggerFinished);
m_stepAction->setEnabled(stopped || state == DebuggerNotReady); m_stepAction->setEnabled(stopped || state == DebuggerNotReady);
@@ -2792,10 +2792,10 @@ void DebuggerPluginPrivate::extensionsInitialized()
act->setIcon(m_interruptIcon); act->setIcon(m_interruptIcon);
act->setEnabled(false); act->setEnabled(false);
act = m_resetAction = new QAction(tr("Abort Debugging"), this); act = m_abortAction = new QAction(tr("Abort Debugging"), this);
act->setToolTip(tr("Aborts debugging and " act->setToolTip(tr("Aborts debugging and "
"resets the debugger to the initial state.")); "resets the debugger to the initial state."));
connect(act, SIGNAL(triggered()), SLOT(handleExecReset())); connect(act, SIGNAL(triggered()), SLOT(handleAbort()));
act = m_nextAction = new QAction(tr("Step Over"), this); act = m_nextAction = new QAction(tr("Step Over"), this);
act->setIcon(QIcon(__(":/debugger/images/debugger_stepover_small.png"))); act->setIcon(QIcon(__(":/debugger/images/debugger_stepover_small.png")));
@@ -3063,8 +3063,8 @@ void DebuggerPluginPrivate::extensionsInitialized()
Constants::HIDDEN_STOP, globalcontext); Constants::HIDDEN_STOP, globalcontext);
cmd->setDefaultKeySequence(QKeySequence(Constants::STOP_KEY)); cmd->setDefaultKeySequence(QKeySequence(Constants::STOP_KEY));
cmd = am->registerAction(m_resetAction, cmd = am->registerAction(m_abortAction,
Constants::RESET, globalcontext); Constants::ABORT, globalcontext);
//cmd->setDefaultKeySequence(QKeySequence(Constants::RESET_KEY)); //cmd->setDefaultKeySequence(QKeySequence(Constants::RESET_KEY));
cmd->setDefaultText(tr("Reset Debugger")); cmd->setDefaultText(tr("Reset Debugger"));
debugMenu->addAction(cmd, CC::G_DEFAULT_ONE); debugMenu->addAction(cmd, CC::G_DEFAULT_ONE);

View File

@@ -261,8 +261,11 @@ QString GdbEngine::errorMessage(QProcess::ProcessError error)
"permissions to invoke the program.\n%2") "permissions to invoke the program.\n%2")
.arg(m_gdb, gdbProc()->errorString()); .arg(m_gdb, gdbProc()->errorString());
case QProcess::Crashed: case QProcess::Crashed:
if (targetState() == DebuggerFinished)
return tr("The gdb process crashed some time after starting " return tr("The gdb process crashed some time after starting "
"successfully."); "successfully.");
else
return tr("The gdb process was ended forcefully");
case QProcess::Timedout: case QProcess::Timedout:
return tr("The last waitFor...() function timed out. " return tr("The last waitFor...() function timed out. "
"The state of QProcess is unchanged, and you can try calling " "The state of QProcess is unchanged, and you can try calling "
@@ -4730,6 +4733,21 @@ void GdbEngine::handleGdbFinished(int code, QProcess::ExitStatus type)
} }
} }
void GdbEngine::abortDebugger()
{
if (targetState() == DebuggerFinished) {
// We already tried. Try harder.
showMessage(_("ABORTING DEBUGGER. SECOND TIME."));
QTC_ASSERT(m_gdbAdapter, return);
QTC_ASSERT(m_gdbAdapter->gdbProc(), return);
m_gdbAdapter->gdbProc()->kill();
} else {
// Be friendly the first time. This will change targetState().
showMessage(_("ABORTING DEBUGGER. FIRST TIME."));
quitDebugger();
}
}
void GdbEngine::handleAdapterStartFailed(const QString &msg, void GdbEngine::handleAdapterStartFailed(const QString &msg,
const QString &settingsIdHint) const QString &settingsIdHint)
{ {

View File

@@ -242,6 +242,7 @@ private: ////////// General Interface //////////
virtual void shutdownEngine(); virtual void shutdownEngine();
virtual void shutdownInferior(); virtual void shutdownInferior();
virtual void notifyInferiorSetupFailed(); virtual void notifyInferiorSetupFailed();
virtual void abortDebugger();
virtual bool acceptsDebuggerCommands() const; virtual bool acceptsDebuggerCommands() const;
virtual void executeDebuggerCommand(const QString &command); virtual void executeDebuggerCommand(const QString &command);