diff options
Diffstat (limited to 'src')
39 files changed, 1389 insertions, 829 deletions
diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index ca5b5f204d..9f8151b15d 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -232,9 +232,14 @@ void CdbEngine::setState(DebuggerState state, const char *func, int line) DebuggerEngine::setState(state); } -void CdbEngine::shutdown() +void CdbEngine::shutdownInferior() { - exitDebugger(); + notifyInferiorShutdownOk(); +} + +void CdbEngine::shutdownEngine() +{ + m_d->endDebugging(); } QString CdbEngine::editorToolTip(const QString &exp, const QString &function) @@ -376,7 +381,7 @@ void CdbEngine::startupChecks() void CdbEngine::setupEngine() { - QTC_ASSERT(state() == EngineSettingUp, qDebug() << state()); + QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state()); const DebuggerStartParameters &sp = startParameters(); if (debugCDBExecution) qDebug() << "startDebugger"; @@ -426,7 +431,7 @@ void CdbEngine::setupEngine() void CdbEngine::setupInferior() { - QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state()); + QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); notifyInferiorSetupOk(); } @@ -499,7 +504,7 @@ bool CdbEngine::startAttachDebugger(qint64 pid, DebuggerStartMode sm, QString *e void CdbEnginePrivate::processCreatedAttached(ULONG64 processHandle, ULONG64 initialThreadHandle) { - m_engine->setState(InferiorRunningRequested, Q_FUNC_INFO, __LINE__); + m_engine->setState(InferiorRunRequested, Q_FUNC_INFO, __LINE__); setDebuggeeHandles(reinterpret_cast<HANDLE>(processHandle), reinterpret_cast<HANDLE>(initialThreadHandle)); ULONG currentThreadId; if (SUCCEEDED(interfaces().debugSystemObjects->GetThreadIdByHandle(initialThreadHandle, ¤tThreadId))) { @@ -526,7 +531,7 @@ void CdbEnginePrivate::processCreatedAttached(ULONG64 processHandle, ULONG64 ini m_engine->warning(QString::fromLatin1("Handshake failed on event #%1: %2").arg(evtNr).arg(CdbCore::msgComFailed("SetNotifyEventHandle", hr))); } } - m_engine->setState(InferiorRunning, Q_FUNC_INFO, __LINE__); + m_engine->setState(InferiorRunOk, Q_FUNC_INFO, __LINE__); if (debugCDBExecution) qDebug() << "<processCreatedAttached"; } @@ -534,13 +539,13 @@ void CdbEnginePrivate::processCreatedAttached(ULONG64 processHandle, ULONG64 ini void CdbEngine::processTerminated(unsigned long exitCode) { showMessage(tr("The process exited with exit code %1.").arg(exitCode)); - if (state() != InferiorStopping) - setState(InferiorStopping, Q_FUNC_INFO, __LINE__); - setState(InferiorStopped, Q_FUNC_INFO, __LINE__); - setState(InferiorShuttingDown, Q_FUNC_INFO, __LINE__); + if (state() != InferiorStopRequested) + setState(InferiorStopRequested, Q_FUNC_INFO, __LINE__); + setState(InferiorStopOk, Q_FUNC_INFO, __LINE__); + setState(InferiorShutdownRequested, Q_FUNC_INFO, __LINE__); m_d->setDebuggeeHandles(0, 0); m_d->clearForRun(); - setState(InferiorShutDown, Q_FUNC_INFO, __LINE__); + setState(InferiorShutdownOk, Q_FUNC_INFO, __LINE__); // Avoid calls from event handler. QTimer::singleShot(0, this, SLOT(quitDebugger())); } @@ -548,7 +553,7 @@ void CdbEngine::processTerminated(unsigned long exitCode) bool CdbEnginePrivate::endInferior(EndInferiorAction action, QString *errorMessage) { // Process must be stopped in order to terminate - m_engine->setState(InferiorShuttingDown, Q_FUNC_INFO, __LINE__); // pretend it is shutdown + m_engine->setState(InferiorShutdownRequested, Q_FUNC_INFO, __LINE__); // pretend it is shutdown const bool wasRunning = isDebuggeeRunning(); if (wasRunning) { interruptInterferiorProcess(errorMessage); @@ -577,7 +582,7 @@ bool CdbEnginePrivate::endInferior(EndInferiorAction action, QString *errorMessa // Perform cleanup even when failed..no point clinging to the process setDebuggeeHandles(0, 0); killWatchTimer(); - m_engine->setState(success ? InferiorShutDown : InferiorShutdownFailed, Q_FUNC_INFO, __LINE__); + m_engine->setState(success ? InferiorShutdownOk : InferiorShutdownFailed, Q_FUNC_INFO, __LINE__); return success; } @@ -594,7 +599,7 @@ void CdbEnginePrivate::endDebugging(EndDebuggingMode em) return; // Do we need to stop the process? QString errorMessage; - if (oldState != InferiorShutDown && m_hDebuggeeProcess) { + if (oldState != InferiorShutdownOk && m_hDebuggeeProcess) { EndInferiorAction action; switch (em) { case EndDebuggingAuto: @@ -618,7 +623,7 @@ void CdbEnginePrivate::endDebugging(EndDebuggingMode em) errorMessage.clear(); } // Clean up resources (open files, etc.) - m_engine->setState(EngineShuttingDown, Q_FUNC_INFO, __LINE__); + m_engine->setState(EngineShutdownRequested, Q_FUNC_INFO, __LINE__); clearForRun(); const bool endedCleanly = endSession(&errorMessage); m_engine->setState(DebuggerNotReady, Q_FUNC_INFO, __LINE__); @@ -628,11 +633,6 @@ void CdbEnginePrivate::endDebugging(EndDebuggingMode em) } } -void CdbEngine::exitDebugger() -{ - m_d->endDebugging(); -} - void CdbEngine::detachDebugger() { m_d->endDebugging(CdbEnginePrivate::EndDebuggingDetach); @@ -712,15 +712,15 @@ bool CdbEnginePrivate::executeContinueCommand(const QString &command) qDebug() << Q_FUNC_INFO << command; clearForRun(); updateCodeLevel(); // Step by instruction - m_engine->setState(InferiorRunningRequested, Q_FUNC_INFO, __LINE__); + m_engine->setState(InferiorRunRequested, Q_FUNC_INFO, __LINE__); m_engine->showMessage(CdbEngine::tr("Continuing with '%1'...").arg(command)); QString errorMessage; const bool success = executeDebuggerCommand(command, &errorMessage); if (success) { - m_engine->setState(InferiorRunning, Q_FUNC_INFO, __LINE__); + m_engine->setState(InferiorRunOk, Q_FUNC_INFO, __LINE__); startWatchTimer(); } else { - m_engine->setState(InferiorStopped, Q_FUNC_INFO, __LINE__); + m_engine->setState(InferiorStopOk, Q_FUNC_INFO, __LINE__); m_engine->warning(CdbEngine::tr("Unable to continue: %1").arg(errorMessage)); } return success; @@ -772,7 +772,7 @@ bool CdbEngine::step(unsigned long executionStatus) || threadsHandler()->threads().size() == 1; m_d->clearForRun(); // clears thread ids m_d->updateCodeLevel(); // Step by instruction or source line - setState(InferiorRunningRequested, Q_FUNC_INFO, __LINE__); + setState(InferiorRunRequested, Q_FUNC_INFO, __LINE__); bool success = false; if (sameThread && executionStatus != CdbExtendedExecutionStatusStepOut) { // Step event-triggering thread, use fast API const HRESULT hr = m_d->interfaces().debugControl->SetExecutionStatus(executionStatus); @@ -806,9 +806,9 @@ bool CdbEngine::step(unsigned long executionStatus) if (executionStatus == DEBUG_STATUS_STEP_INTO || executionStatus == DEBUG_STATUS_REVERSE_STEP_INTO) m_d->m_breakEventMode = CdbEnginePrivate::BreakEventIgnoreOnce; m_d->startWatchTimer(); - setState(InferiorRunning, Q_FUNC_INFO, __LINE__); + setState(InferiorRunOk, Q_FUNC_INFO, __LINE__); } else { - setState(InferiorStopped, Q_FUNC_INFO, __LINE__); + setState(InferiorStopOk, Q_FUNC_INFO, __LINE__); } if (debugCDBExecution) qDebug() << "<step samethread" << sameThread << "succeeded" << success; @@ -879,7 +879,7 @@ bool CdbEnginePrivate::continueInferior(QString *errorMessage) return true; } // Request continue - m_engine->setState(InferiorRunningRequested, Q_FUNC_INFO, __LINE__); + m_engine->setState(InferiorRunRequested, Q_FUNC_INFO, __LINE__); bool success = false; do { clearForRun(); @@ -895,9 +895,9 @@ bool CdbEnginePrivate::continueInferior(QString *errorMessage) success = true; } while (false); if (success) { - m_engine->setState(InferiorRunning, Q_FUNC_INFO, __LINE__); + m_engine->setState(InferiorRunOk, Q_FUNC_INFO, __LINE__); } else { - m_engine->setState(InferiorStopped, Q_FUNC_INFO, __LINE__); // No RunningRequestFailed? + m_engine->setState(InferiorStopOk, Q_FUNC_INFO, __LINE__); // No RunningRequestFailed? } return true; } @@ -922,7 +922,7 @@ void CdbEnginePrivate::slotModulesLoaded() // spawned by the debug handler and inherits the handles, // the event handling does not work reliably (that is, the crash // event is not delivered). In that case, force a break - if (m_mode == AttachCrashedExternal && m_engine->state() != InferiorStopped) + if (m_mode == AttachCrashedExternal && m_engine->state() != InferiorStopOk) QTimer::singleShot(10, m_engine, SLOT(slotBreakAttachToCrashed())); } @@ -930,7 +930,7 @@ void CdbEngine::slotBreakAttachToCrashed() { // Force a break when attaching to crashed process (if Creator was not spawned // from handler). - if (state() != InferiorStopped) { + if (state() != InferiorStopOk) { showMessage(QLatin1String("Forcing break...")); m_d->m_dumper->disable(); interruptInferior(); @@ -943,7 +943,7 @@ void CdbEngine::interruptInferior() return; QString errorMessage; - setState(InferiorStopping, Q_FUNC_INFO, __LINE__); + setState(InferiorStopRequested, Q_FUNC_INFO, __LINE__); if (!m_d->interruptInterferiorProcess(&errorMessage)) { setState(InferiorStopFailed, Q_FUNC_INFO, __LINE__); warning(msgFunctionFailed(Q_FUNC_INFO, errorMessage)); @@ -1022,7 +1022,7 @@ void CdbEngine::activateFrame(int frameIndex) if (debugCDB) qDebug() << Q_FUNC_INFO << frameIndex; - if (state() != InferiorStopped) { + if (state() != InferiorStopOk) { qWarning("WARNING %s: invoked while debuggee is running\n", Q_FUNC_INFO); return; } @@ -1237,7 +1237,7 @@ void CdbEngine::requestModuleSymbols(const QString &moduleName) void CdbEngine::reloadRegisters() { - if (state() != InferiorStopped) + if (state() != InferiorStopOk) return; const int intBase = 10; if (debugCDB) @@ -1272,7 +1272,7 @@ void CdbEngine::slotConsoleStubMessage(const QString &msg, bool) void CdbEngine::slotConsoleStubTerminated() { - exitDebugger(); + shutdownEngine(); } void CdbEngine::warning(const QString &msg) @@ -1331,9 +1331,9 @@ void CdbEnginePrivate::handleDebugEvent() case BreakEventHandle: { // If this is triggered by breakpoint/crash: Set state to stopping // to avoid warnings as opposed to interrupt inferior - if (m_engine->state() != InferiorStopping) - m_engine->setState(InferiorStopping, Q_FUNC_INFO, __LINE__); - m_engine->setState(InferiorStopped, Q_FUNC_INFO, __LINE__); + if (m_engine->state() != InferiorStopRequested) + m_engine->setState(InferiorStopRequested, Q_FUNC_INFO, __LINE__); + m_engine->setState(InferiorStopOk, Q_FUNC_INFO, __LINE__); // Indicate artifical thread that is created when interrupting as such, // else use stop message with cleaned newlines and blanks. const QString currentThreadState = @@ -1424,7 +1424,7 @@ ULONG CdbEnginePrivate::updateThreadList(const QString ¤tThreadState) ULONG currentThreadId; QString errorMessage; // When interrupting, an artifical thread with a breakpoint is created. - const bool stopped = m_engine->state() == InferiorStopped; + const bool stopped = m_engine->state() == InferiorStopOk; if (!CdbStackTraceContext::getThreads(interfaces(), stopped, &threads, ¤tThreadId, diff --git a/src/plugins/debugger/cdb/cdbengine.h b/src/plugins/debugger/cdb/cdbengine.h index d03c57d638..0b72dfcead 100644 --- a/src/plugins/debugger/cdb/cdbengine.h +++ b/src/plugins/debugger/cdb/cdbengine.h @@ -55,12 +55,12 @@ public: static DebuggerEngine *create(const DebuggerStartParameters &sp, QString *errorMessage); - virtual void shutdown(); virtual void setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos); virtual void setupEngine(); virtual void setupInferior(); virtual void runEngine(); - virtual void exitDebugger(); + virtual void shutdownInferior(); + virtual void shutdownEngine(); virtual void detachDebugger(); virtual void updateWatchData(const WatchData &data); virtual unsigned debuggerCapabilities() const; diff --git a/src/plugins/debugger/debuggerconstants.h b/src/plugins/debugger/debuggerconstants.h index c2ae3c8f98..e0bc2a8950 100644 --- a/src/plugins/debugger/debuggerconstants.h +++ b/src/plugins/debugger/debuggerconstants.h @@ -79,29 +79,34 @@ enum DebuggerState { DebuggerNotReady, // Debugger not started - EngineSettingUp, // Engine starts + EngineSetupRequested, // Engine starts EngineSetupFailed, EngineSetupOk, - InferiorUnrunnable, // Used in the core dump adapter - InferiorSettingUp, + InferiorSetupRequested, InferiorSetupFailed, - InferiorSetupOk, - InferiorRunningRequested, // Debuggee requested to run - InferiorRunningRequested_Kill, // Debuggee requested to run, but want to kill it - InferiorRunning, // Debuggee running + EngineRunRequested, + EngineRunFailed, + InferiorUnrunnable, // Used in the core dump adapter - 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 + InferiorRunRequested, // Debuggee requested to run + InferiorRunOk, // Debuggee running + InferiorRunFailed, // Debuggee running - InferiorShuttingDown, - InferiorShutDown, + InferiorStopRequested, // Debuggee running, stop requested + InferiorStopOk, // Debuggee stopped + InferiorStopFailed, // Debuggee not stopped, will kill debugger + + InferiorShutdownRequested, + InferiorShutdownOk, InferiorShutdownFailed, - EngineShuttingDown + EngineShutdownRequested, + EngineShutdownOk, + EngineShutdownFailed, + + DebuggerFinished }; enum DebuggerStartMode @@ -139,21 +144,21 @@ enum LogChannel { LogInput, // Used for user input LogMiscInput, // Used for misc stuff in the input pane - LogOutput, - LogWarning, - LogError, + LogOutput, + LogWarning, + LogError, LogStatus, // Used for status changed messages LogTime, // Used for time stamp messages - LogDebug, - LogMisc, - AppOutput, - AppError, + LogDebug, + LogMisc, + AppOutput, + AppError, AppStuff, StatusBar // LogStatus and also put to the status bar -}; - -enum ModelRoles -{ +}; + +enum ModelRoles +{ DisplaySourceRole = 32, // Qt::UserRole EngineStateRole, diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index f14d2c9756..37cdd4e78e 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -88,6 +88,13 @@ using namespace Debugger::Internal; using namespace ProjectExplorer; using namespace TextEditor; +//#define DEBUG_STATE 1 +#if DEBUG_STATE +# define SDEBUG(s) qDebug() << s +#else +# define SDEBUG(s) +#endif +# define XSDEBUG(s) qDebug() << s /////////////////////////////////////////////////////////////////////// // @@ -143,24 +150,27 @@ const char *DebuggerEngine::stateName(int s) # define SN(x) case x: return #x; switch (s) { SN(DebuggerNotReady) - SN(EngineSettingUp) + SN(EngineSetupRequested) SN(EngineSetupOk) SN(EngineSetupFailed) - SN(InferiorSettingUp) + SN(EngineRunFailed) + SN(InferiorSetupRequested) SN(InferiorSetupFailed) - SN(InferiorSetupOk) - SN(InferiorRunningRequested) - SN(InferiorRunningRequested_Kill) - SN(InferiorRunning) + SN(EngineRunRequested) + SN(InferiorRunRequested) + SN(InferiorRunOk) + SN(InferiorRunFailed) SN(InferiorUnrunnable) - SN(InferiorStopping) - SN(InferiorStopping_Kill) - SN(InferiorStopped) + SN(InferiorStopRequested) + SN(InferiorStopOk) SN(InferiorStopFailed) - SN(InferiorShuttingDown) - SN(InferiorShutDown) + SN(InferiorShutdownRequested) + SN(InferiorShutdownOk) SN(InferiorShutdownFailed) - SN(EngineShuttingDown) + SN(EngineShutdownRequested) + SN(EngineShutdownOk) + SN(EngineShutdownFailed) + SN(DebuggerFinished) } return "<unknown>"; # undef SN @@ -208,6 +218,7 @@ public: m_runControl(0), m_startParameters(sp), m_state(DebuggerNotReady), + m_lastGoodState(DebuggerNotReady), m_breakHandler(engine), m_commandHandler(engine), m_modulesHandler(engine), @@ -227,16 +238,28 @@ public slots: void doSetupInferior(); void doRunEngine(); - void doShutdown(); + void doShutdownEngine(); + void doShutdownInferior(); void doInterruptInferior(); + void doFinishDebugger(); public: + DebuggerState state() const { return m_state; } + DebuggerEngine *m_engine; // Not owned. DebuggerRunControl *m_runControl; // Not owned. DebuggerStartParameters m_startParameters; + + // The current state. DebuggerState m_state; + // The state we had before something unexpected happend. + DebuggerState m_lastGoodState; + + // The state we are aiming for. + DebuggerState m_targetState; + qint64 m_inferiorPid; BreakHandler m_breakHandler; @@ -277,7 +300,7 @@ void DebuggerEnginePrivate::handleContextMenuRequest(const QVariant ¶meters) { const QList<QVariant> list = parameters.toList(); QTC_ASSERT(list.size() == 3, return); - TextEditor::ITextEditor *editor = + TextEditor::ITextEditor *editor = (TextEditor::ITextEditor *)(list.at(0).value<quint64>()); int lineNumber = list.at(1).toInt(); QMenu *menu = (QMenu *)(list.at(2).value<quint64>()); @@ -413,7 +436,7 @@ void DebuggerEngine::handleCommand(int role, const QVariant &value) break; case RequestExecExitRole: - exitDebugger(); + d->doShutdownInferior(); break; case RequestExecSnapshotRole: @@ -451,7 +474,7 @@ void DebuggerEngine::handleCommand(int role, const QVariant &value) QPoint point = list.at(0).value<QPoint>(); TextEditor::ITextEditor *editor = // Eeks. (TextEditor::ITextEditor *)(list.at(1).value<quint64>()); - int pos = list.at(2).toInt(); + int pos = list.at(2).toInt(); setToolTipExpression(point, editor, pos); break; } @@ -626,7 +649,7 @@ void DebuggerEngine::startDebugger(DebuggerRunControl *runControl) d->m_runControl = runControl; - QTC_ASSERT(state() == DebuggerNotReady, setState(DebuggerNotReady)); + QTC_ASSERT(state() == DebuggerNotReady, qDebug() << state()); d->m_inferiorPid = d->m_startParameters.attachPID > 0 ? d->m_startParameters.attachPID : 0; @@ -641,7 +664,7 @@ void DebuggerEngine::startDebugger(DebuggerRunControl *runControl) theDebuggerAction(OperateByInstruction) ->setEnabled(engineCapabilities & DisassemblerCapability); - setState(EngineSettingUp); + setState(EngineSetupRequested); setupEngine(); } @@ -905,59 +928,74 @@ DebuggerState DebuggerEngine::state() const return d->m_state; } -static bool isAllowedTransition(int from, int to) +DebuggerState DebuggerEngine::lastGoodState() const { - switch (from) { - case -1: - return to == DebuggerNotReady; + return d->m_lastGoodState; +} + +DebuggerState DebuggerEngine::targetState() const +{ + return d->m_targetState; +} +static bool isAllowedTransition(DebuggerState from, DebuggerState to) +{ + switch (from) { case DebuggerNotReady: - return to == EngineSettingUp || to == DebuggerNotReady; + return to == EngineSetupRequested || to == DebuggerNotReady; - case EngineSettingUp: + case EngineSetupRequested: return to == EngineSetupOk || to == EngineSetupFailed; case EngineSetupFailed: return to == DebuggerNotReady; case EngineSetupOk: - return to == InferiorSettingUp || to == EngineShuttingDown; + return to == InferiorSetupRequested || to == EngineShutdownRequested; - case InferiorSettingUp: - return to == InferiorSetupOk || to == InferiorSetupFailed; + case InferiorSetupRequested: + return to == EngineRunRequested || to == InferiorSetupFailed; case InferiorSetupFailed: - return to == EngineShuttingDown; - case InferiorSetupOk: - return to == InferiorRunningRequested || to == InferiorStopped - || to == InferiorUnrunnable; - - 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; + return to == EngineShutdownRequested; + + case EngineRunRequested: + return to == InferiorRunRequested || to == InferiorStopRequested + || to == InferiorUnrunnable || to == EngineRunFailed; + + case EngineRunFailed: + return to == InferiorShutdownRequested; + + case InferiorRunRequested: + return to == InferiorRunOk || to == InferiorRunFailed; + case InferiorRunFailed: + return to == InferiorStopOk; + case InferiorRunOk: + return to == InferiorStopRequested || to == InferiorStopOk; + + case InferiorStopRequested: + return to == InferiorStopOk || to == InferiorStopFailed; + case InferiorStopOk: + return to == InferiorRunRequested || to == InferiorShutdownRequested + || to == InferiorStopOk; case InferiorStopFailed: - return to == EngineShuttingDown; + return to == EngineShutdownRequested; case InferiorUnrunnable: - return to == EngineShuttingDown; - case InferiorShuttingDown: - return to == InferiorShutDown || to == InferiorShutdownFailed; - case InferiorShutDown: - return to == EngineShuttingDown; + return to == InferiorShutdownRequested; + case InferiorShutdownRequested: + return to == InferiorShutdownOk || to == InferiorShutdownFailed; + case InferiorShutdownOk: + return to == EngineShutdownRequested; case InferiorShutdownFailed: - return to == EngineShuttingDown; + return to == EngineShutdownRequested; - case EngineShuttingDown: - return to == DebuggerNotReady; + case EngineShutdownRequested: + return to == EngineShutdownOk; + case EngineShutdownOk: + return to == DebuggerFinished; + case EngineShutdownFailed: + return to == DebuggerFinished; + + case DebuggerFinished: + return false; } qDebug() << "UNKNOWN STATE:" << from; @@ -966,16 +1004,17 @@ static bool isAllowedTransition(int from, int to) void DebuggerEngine::notifyEngineSetupFailed() { - QTC_ASSERT(state() == EngineSettingUp, qDebug() << state()); + SDEBUG(Q_FUNC_INFO); + QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state()); setState(EngineSetupFailed); - d->m_runControl->debuggingFinished(); d->m_runControl->startFailed(); - QTimer::singleShot(0, this, SLOT(doShutdown())); + QTimer::singleShot(0, d, SLOT(doShutdownEngine())); } void DebuggerEngine::notifyEngineSetupOk() { - QTC_ASSERT(state() == EngineSettingUp, qDebug() << state()); + SDEBUG(Q_FUNC_INFO); + QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state()); setState(EngineSetupOk); d->m_runControl->startSuccessful(); QTimer::singleShot(0, d, SLOT(doSetupInferior())); @@ -983,88 +1022,296 @@ void DebuggerEngine::notifyEngineSetupOk() void DebuggerEnginePrivate::doSetupInferior() { - QTC_ASSERT(m_state == EngineSetupOk, qDebug() << m_state); - m_engine->setState(InferiorSettingUp); + SDEBUG(Q_FUNC_INFO); + QTC_ASSERT(state() == EngineSetupOk, qDebug() << state()); + m_engine->setState(InferiorSetupRequested); m_engine->setupInferior(); } +#if 0 // Default implemention, can be overridden. void DebuggerEngine::setupInferior() { QTC_ASSERT(state() == EngineSetupOk, qDebug() << state()); notifyInferiorSetupOk(); } +#endif void DebuggerEngine::notifyInferiorSetupFailed() { - QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state()); + SDEBUG(Q_FUNC_INFO); + QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); setState(InferiorSetupFailed); - QTimer::singleShot(0, d, SLOT(doShutdown())); + QTimer::singleShot(0, d, SLOT(doShutdownEngine())); } void DebuggerEngine::notifyInferiorSetupOk() { - QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state()); - setState(InferiorSetupOk); + SDEBUG(Q_FUNC_INFO); + QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); + setState(EngineRunRequested); QTimer::singleShot(0, d, SLOT(doRunEngine())); } void DebuggerEnginePrivate::doRunEngine() { - QTC_ASSERT(m_state == InferiorSetupOk, qDebug() << m_state); + SDEBUG(Q_FUNC_INFO); + QTC_ASSERT(state() == EngineRunRequested, qDebug() << state()); m_engine->runEngine(); } +#if 0 // Default implemention, can be overridden. void DebuggerEngine::runEngine() { - QTC_ASSERT(state() == InferiorSetupOk, qDebug() << state()); + QTC_ASSERT(state() == EngineRunRequested, qDebug() << state()); +} +#endif + +void DebuggerEngine::notifyInferiorUnrunnable() +{ + SDEBUG(Q_FUNC_INFO); + QTC_ASSERT(state() == EngineRunRequested, qDebug() << state()); + setState(InferiorUnrunnable); +} + +void DebuggerEngine::notifyEngineRunFailed() +{ + SDEBUG(Q_FUNC_INFO); + QTC_ASSERT(state() == EngineRunRequested, qDebug() << state()); + setState(EngineRunFailed); + QTimer::singleShot(0, d, SLOT(doShutdownInferior())); +} + +void DebuggerEngine::notifyEngineRunAndInferiorRunOk() +{ + SDEBUG(Q_FUNC_INFO); + QTC_ASSERT(state() == EngineRunRequested, qDebug() << state()); + setState(InferiorRunRequested); + notifyInferiorRunOk(); +} + +void DebuggerEngine::notifyEngineRunAndInferiorStopOk() +{ + SDEBUG(Q_FUNC_INFO); + QTC_ASSERT(state() == EngineRunRequested, qDebug() << state()); + setState(InferiorStopRequested); + notifyInferiorStopOk(); +} + +void DebuggerEngine::notifyInferiorRunRequested() +{ + SDEBUG(Q_FUNC_INFO); + QTC_ASSERT(state() == InferiorStopOk, qDebug() << state()); + setState(InferiorRunRequested); +} + +void DebuggerEngine::notifyInferiorRunOk() +{ + SDEBUG(Q_FUNC_INFO); + QTC_ASSERT(state() == InferiorRunRequested, qDebug() << state()); + setState(InferiorRunOk); +} + +/* +void DebuggerEngine::notifyInferiorSpontaneousRun() +{ + SDEBUG(Q_FUNC_INFO); + QTC_ASSERT(state() == InferiorStopOk, qDebug() << state()); + setState(InferiorRunRequested); + setState(InferiorRunOk); +} +*/ + +void DebuggerEngine::notifyInferiorRunFailed() +{ + XSDEBUG(Q_FUNC_INFO); + qDebug() << "NOTIFY_INFERIOR_RUN_FAILED"; + QTC_ASSERT(state() == InferiorRunRequested, qDebug() << state()); + setState(InferiorRunFailed); + setState(InferiorStopOk); + if (isDying()) { + QTimer::singleShot(0, d, SLOT(doShutdownInferior())); + } +} + +void DebuggerEngine::notifyInferiorStopOk() +{ + SDEBUG(Q_FUNC_INFO); + if (isDying()) { + showMessage(_("STOPPED WHILE DYING. CONTINUING SHUTDOWN.")); + setState(InferiorStopOk); + QTimer::singleShot(0, d, SLOT(doShutdownInferior())); + } else { + QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state()); + setState(InferiorStopOk); + } } -void DebuggerEngine::notifyInferiorRunning() +void DebuggerEngine::notifyInferiorSpontaneousStop() { - QTC_ASSERT(m_state == InferiorRunningRequested, qDebug() << m_state); - setState(InferiorRunning); + SDEBUG(Q_FUNC_INFO); + QTC_ASSERT(state() == InferiorRunOk, qDebug() << state()); + setState(InferiorStopOk); } -void DebuggerEngine::notifyInferiorStopped() +void DebuggerEngine::notifyInferiorStopFailed() { - QTC_ASSERT(m_state == InferiorRunningStoppint, qDebug() << m_state); - setState(InferiorStopped); + SDEBUG(Q_FUNC_INFO); + QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state()); + setState(InferiorStopFailed); + QTimer::singleShot(0, d, SLOT(doShutdownEngine())); } void DebuggerEnginePrivate::doInterruptInferior() { - QTC_ASSERT(m_state == InferiorRunning, qDebug() << m_state); + SDEBUG(Q_FUNC_INFO); + QTC_ASSERT(state() == InferiorRunOk, qDebug() << state()); + m_engine->setState(InferiorStopRequested); m_engine->interruptInferior(); } -void DebuggerEnginePrivate::doShutdown() +void DebuggerEnginePrivate::doShutdownInferior() +{ + SDEBUG(Q_FUNC_INFO); + qDebug() << "DO_SHUTDOWN_INFERIOR"; + m_engine->resetLocation(); + m_targetState = DebuggerFinished; + m_engine->setState(InferiorShutdownRequested); + m_engine->shutdownInferior(); +} + +void DebuggerEngine::notifyInferiorShutdownOk() +{ + SDEBUG(Q_FUNC_INFO); + QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << state()); + showMessage(_("INFERIOR SUCCESSFULLY SHUT DOWN")); + d->m_lastGoodState = DebuggerNotReady; // A "neutral" value. + setState(InferiorShutdownOk); + QTimer::singleShot(0, d, SLOT(doShutdownEngine())); +} + +void DebuggerEngine::notifyInferiorShutdownFailed() +{ + SDEBUG(Q_FUNC_INFO); + QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << state()); + showMessage(_("INFERIOR SHUTDOWN FAILED")); + setState(InferiorShutdownFailed); + QTimer::singleShot(0, d, SLOT(doShutdownEngine())); +} + +void DebuggerEngine::notifyInferiorIll() +{ + SDEBUG(Q_FUNC_INFO); + // This can be issued in almost any state. The inferior could still be + // alive as some previous notifications might have been bogus. + qDebug() << "SOMETHING IS WRONG WITH THE INFERIOR"; + d->m_targetState = DebuggerFinished; + d->m_lastGoodState = d->m_state; + if (state() == InferiorRunRequested) { + // We asked for running, but did not see a response. + // Assume the inferior is dead. + // FIXME: Use timeout? + setState(InferiorRunFailed); + setState(InferiorStopOk); + } + QTC_ASSERT(state() == InferiorStopOk, qDebug() << state()); + QTimer::singleShot(0, d, SLOT(doShutdownInferior())); +} + +void DebuggerEnginePrivate::doShutdownEngine() +{ + SDEBUG(Q_FUNC_INFO); + QTC_ASSERT(state() == InferiorShutdownOk + || state() == InferiorShutdownFailed, qDebug() << state()); + m_targetState = DebuggerFinished; + m_engine->setState(EngineShutdownRequested); + m_engine->shutdownEngine(); +} + +void DebuggerEngine::notifyEngineShutdownOk() +{ + SDEBUG(Q_FUNC_INFO); + QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state()); + showMessage(_("ENGINE SUCCESSFULLY SHUT DOWN")); + setState(EngineShutdownOk); + QTimer::singleShot(0, d, SLOT(doFinishDebugger())); +} + +void DebuggerEngine::notifyEngineShutdownFailed() { - m_engine->shutdown(); + SDEBUG(Q_FUNC_INFO); + showMessage(_("ENGINE SHUTDOWN FAILED")); + QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state()); + setState(EngineShutdownFailed); + QTimer::singleShot(0, d, SLOT(doFinishDebugger())); +} + +void DebuggerEnginePrivate::doFinishDebugger() +{ + SDEBUG(Q_FUNC_INFO); + QTC_ASSERT(state() == EngineShutdownOk + || state() == EngineShutdownFailed, qDebug() << state()); + m_engine->resetLocation(); + m_engine->setState(DebuggerFinished); + m_runControl->debuggingFinished(); +} + +void DebuggerEngine::notifyEngineIll() +{ + SDEBUG(Q_FUNC_INFO); + qDebug() << "SOMETHING IS WRONG WITH THE ENGINE"; + d->m_targetState = DebuggerFinished; + d->m_lastGoodState = d->m_state; + if (state() == InferiorStopOk) { + QTimer::singleShot(0, d, SLOT(doShutdownInferior())); + } else { + QTimer::singleShot(0, d, SLOT(doShutdownEngine())); + } +} + +void DebuggerEngine::notifyEngineSpontaneousShutdown() +{ + SDEBUG(Q_FUNC_INFO); + qDebug() << "THE ENGINE SUDDENLY DIED"; + setState(EngineShutdownOk, true); + QTimer::singleShot(0, d, SLOT(doFinishDebugger())); +} + +void DebuggerEngine::notifyInferiorExited() +{ + XSDEBUG("NOTIFY_INFERIOR_EXIT"); + resetLocation(); + + // This can be issued in almost any state. We assume, though, + // that at this point of time the inferior is not running anymore, + // even if stop notification were not issued or got lost. + if (state() == InferiorRunOk) { + setState(InferiorStopRequested); + setState(InferiorStopOk); + } + setState(InferiorShutdownRequested); + setState(InferiorShutdownOk); + QTimer::singleShot(0, d, SLOT(doShutdownEngine())); } void DebuggerEngine::setState(DebuggerState state, bool forced) { - //qDebug() << "STATUS CHANGE: FROM " << stateName(d->m_state) - // << " TO " << stateName(state); + SDEBUG(Q_FUNC_INFO); + qDebug() << "STATUS CHANGE: FROM " << stateName(d->m_state) + << " TO " << stateName(state); DebuggerState oldState = d->m_state; d->m_state = state; - QString msg = _("State changed from %1(%2) to %3(%4).") - .arg(stateName(oldState)).arg(oldState).arg(stateName(state)).arg(state); + QString msg = _("State changed%5 from %1(%2) to %3(%4).") + .arg(stateName(oldState)).arg(oldState).arg(stateName(state)).arg(state) + .arg(forced ? " BY FORCE" : ""); if (!forced && !isAllowedTransition(oldState, state)) qDebug() << "UNEXPECTED STATE TRANSITION: " << msg; showMessage(msg, LogDebug); plugin()->updateState(this); - - if (state != oldState) { - if (state == DebuggerNotReady) { - d->m_runControl->debuggingFinished(); - } - } } bool DebuggerEngine::debuggerActionsEnabled() const @@ -1075,26 +1322,29 @@ bool DebuggerEngine::debuggerActionsEnabled() const bool DebuggerEngine::debuggerActionsEnabled(DebuggerState state) { switch (state) { - case InferiorSettingUp: - case InferiorRunningRequested: - case InferiorRunning: + case InferiorSetupRequested: + case InferiorRunOk: case InferiorUnrunnable: - case InferiorStopping: - case InferiorStopped: + case InferiorStopOk: return true; + case InferiorStopRequested: + case InferiorRunRequested: + case InferiorRunFailed: case DebuggerNotReady: - case EngineSettingUp: + case EngineSetupRequested: case EngineSetupOk: case EngineSetupFailed: - case InferiorSetupOk: + case EngineRunRequested: + case EngineRunFailed: case InferiorSetupFailed: - case InferiorRunningRequested_Kill: - case InferiorStopping_Kill: case InferiorStopFailed: - case InferiorShuttingDown: - case InferiorShutDown: + case InferiorShutdownRequested: + case InferiorShutdownOk: case InferiorShutdownFailed: - case EngineShuttingDown: + case EngineShutdownRequested: + case EngineShutdownOk: + case EngineShutdownFailed: + case DebuggerFinished: return false; } return false; @@ -1133,6 +1383,13 @@ bool DebuggerEngine::isReverseDebugging() const return plugin()->isReverseDebugging(); } +// called by DebuggerRunControl +void DebuggerEngine::quitDebugger() +{ + qDebug() << "QUIT_DEBUGGER"; + shutdownInferior(); +} + } // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/debuggerengine.h b/src/plugins/debugger/debuggerengine.h index 05c5e55a83..c90581cac3 100644 --- a/src/plugins/debugger/debuggerengine.h +++ b/src/plugins/debugger/debuggerengine.h @@ -121,7 +121,6 @@ public: DebuggerEngine(const DebuggerStartParameters &sp); virtual ~DebuggerEngine(); - virtual void shutdown() {} virtual void setToolTipExpression(const QPoint & /* mousePos */, TextEditor::ITextEditor * /* editor */, int /* cursorPos */) { } void initializeFromTemplate(DebuggerEngine *other); @@ -164,8 +163,6 @@ public: { Q_UNUSED(expr); Q_UNUSED(value); } protected: - virtual void setupEngine() {} - virtual void exitDebugger() {} virtual void detachDebugger() {} virtual void executeStep() {} virtual void executeStepOut() {} @@ -229,6 +226,9 @@ public: void executeReturnX(); DebuggerState state() const; + DebuggerState lastGoodState() const; + DebuggerState targetState() const; + bool isDying() const { return targetState() == DebuggerFinished; } // Dumper stuff (common to cdb and gdb). bool qtDumperLibraryEnabled() const; @@ -251,24 +251,46 @@ public: void openFile(const QString &fileName, int lineNumber = -1); void gotoLocation(const QString &fileName, int lineNumber, bool setMarker); void gotoLocation(const StackFrame &frame, bool setMarker); - void raiseApplication(); - virtual void quitDebugger() { exitDebugger(); } // called by DebuggerRunControl + Q_SLOT void raiseApplication(); + virtual void quitDebugger(); // called by DebuggerRunControl protected: void notifyEngineSetupOk(); void notifyEngineSetupFailed(); + void notifyEngineRunFailed(); void notifyInferiorSetupOk(); void notifyInferiorSetupFailed(); - void notifyInferiorRunning(); - void notifyInferiorStopped(); + void notifyEngineRunAndInferiorRunOk(); + void notifyEngineRunAndInferiorStopOk(); + void notifyInferiorUnrunnable(); // Called by CoreAdapter. + //void notifyInferiorSpontaneousRun(); + + void notifyInferiorRunRequested(); + void notifyInferiorRunOk(); + void notifyInferiorRunFailed(); + + void notifyInferiorStopOk(); + void notifyInferiorSpontaneousStop(); + void notifyInferiorStopFailed(); + void notifyInferiorExited(); + + void notifyInferiorShutdownOk(); + void notifyInferiorShutdownFailed(); + + void notifyEngineSpontaneousShutdown(); + void notifyEngineShutdownOk(); + void notifyEngineShutdownFailed(); - // Called to initiate shutdown. void notifyInferiorIll(); + void notifyEngineIll(); - virtual void setupInferior(); - virtual void runEngine(); + virtual void setupEngine() = 0; + virtual void setupInferior() = 0; + virtual void runEngine() = 0; + virtual void shutdownInferior() = 0; + virtual void shutdownEngine() = 0; //private: // FIXME. State transitions void setState(DebuggerState state, bool forced = false); diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 3b904aca4b..6050c9b626 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -162,91 +162,148 @@ // // Transitions marked by '---' are done in the individual engines. // Transitions marked by '+-+' are done in the base DebuggerEngine. +// Transitions marked by '*' are done asynchronously. // The GdbEngine->setupEngine() function is described in more detail below. // -// DebuggerNotReady -// + -// + -// EngineSettingUp -// + -// + -// (calls *Engine->setupEngine()) -// | | -// {notify- {notify- -// Engine- Engine- -// StartOk} StartFailed} -// | | -// | `---> EngineSetupFailed -// | + -// | [calls RunControl->startFailed] -// | + -// | DebuggerNotReady -// v -// EngineSetupOk -// + -// [calls RunControl->StartSuccessful] -// + -// (calls *Engine->setupInferior()) -// | | -// {notify- {notify- -// Inferior- Inferior- -// SetupOk} SetupFailed} -// | | -// | ` ----> InferiorSetupFailed +-+-+-+->. -// | + -// v + -// InferiorSetupOk + -// + + -// (calls *Engine->runEngine()) + -// | + -// (core) | (attach) (term) (remote) (script) + -// .-----------------<-|->------------------. + -// | v | + -// InferiorUnrunnable | (plain) | + -// | | (trk) | + -// | | | + -// | .--> InferiorRunningRequested | + -// | | | | + -// | | InferiorRunning | + -// | | | | + -// | | InferiorStopping | + -// | | | | + -// | '------ InferiorStopped <-----------' + -// | | v -// | InferiorShuttingDown -> InferiorShutdownFailed ---->+ -// | | + -// | InferiorShutDown + -// | | + -// '--------> EngineShuttingDown <-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+' -// | -// DebuggerNotReady +// DebuggerNotReady +// + +// EngineSetupRequested +// + +// (calls *Engine->setupEngine()) +// | | +// {notify- {notify- +// Engine- Engine- +// SetupOk} SetupFailed} +// | | +// | `---> EngineSetupFailed +// | + +// | [calls RunControl->startFailed] +// | + +// | DebuggerNotReady +// v +// EngineSetupOk +// + +// [calls RunControl->StartSuccessful] +// + +// InferiorSetupRequested +// + +// (calls *Engine->setupInferior()) +// | | +// | | +// {notify- {notify- +// Inferior- Inferior- +// SetupOk} SetupFailed} +// + + +// + ` +-+-> InferiorSetupFailed +-+-+-+-+-+->. +// + + +// + + +// EngineRunRequested + +// + + +// (calls *Engine->runEngine()) + +// / | | \ + +// / | | \ + +// | (core) | (attach) | | + +// | | | | + +// {notify- {notifyER&- {notifyER&- {notify- + +// Inferior- Inferior- Inferior- RunEngine- + +// Unrunnable} StopOk} RunOk} Failed} + +// + + + + + +// InferiorUnrunnable + InferiorRunOk + + +// + + + +// InferiorStopOk EngineRunFailed + +// + v +// `-+-+-+-+-+-+-+-+-+-+-+>-+ +// + +// .--- #SpontaneousStop@InferiorRunOk# + +// | + +// | + +// | #Interupt@InferiorRunOk# + +// | + + +// | InferiorStopRequested + +// | + + +// | (calls *Engine-> + +// | interruptInferior()) + +// | | | + +// {notify- {notify- {notify- + +// Sponta.Inf. Inferior- Inferior- + +// StopOk} StopOk} StopFailed} + +// + + + + +// + + + + +// InferiorStopOk + + +// + + +// + + +// + + +// #Stop@InferiorUnrunnable# + + +// #Creator Close Event# + + +// + + + +// InferiorShutdownRequested + +// + + +// (calls *Engine->shutdownInferior()) + +// | | + +// {notify- {notify- + +// Inferior- Inferior- + +// ShutdownOk} ShutdownFailed} + +// + + + +// + + + +// #Inferior exited# + + + +// | + + + +// {notifyInferior- + + + +// Exited} + + + +// + + + + +// + + + + +// + + + + +// InferiorShutdownOk InferiorShutdownFailed + +// * * + +// EngineShutdownRequested + +// + + +// (calls *Engine->shutdownEngine()) <+-+-+-+-+-+-+-+-+-+-+-+-+-+' +// | | +// {notify- {notify- +// Inferior- Inferior- +// ShutdownOk} ShutdownFailed} +// + + +// EngineShutdownOk EngineShutdownFailed +// * * +// DebuggerFinished // -// GdbEngine specific startup. All happens in EngineSettingUp state + +//(attach) | (plain) +//(term) | (trk) +//(remote) | +//(script) | +//(pdb) | + +// GdbEngine specific startup. All happens in EngineSetupRequested state // // Transitions marked by '---' are done in the individual adapters. // Transitions marked by '+-+' are done in the GdbEngine. - +// // GdbEngine::setupEngine() // + -// + // (calls *Adapter->startAdapter()) // | | // | `---> handleAdapterStartFailed() // | + -// | EngineSetupFailed +// | {notifyEngineSetupFailed} // | // handleAdapterStarted() // + +// {notifyEngineSetupOk} +// +// +// +// GdbEngine::setupInferior() +// + // (calls *Adapter->prepareInferior()) // | | -// | `---> handleAdapterStartFailed() +// | `---> handlePrepareInferiorFailed() // | + -// | EngineSetupFailed +// | {notifyInferiorSetupFailed} // | -// handleInferiorPrepared() +// handleInferiorPrepared() // + -// EngineSetupOk +// {notifyInferiorSetupOk} @@ -775,6 +832,12 @@ class SessionEngine : public DebuggerEngine public: SessionEngine() : DebuggerEngine(DebuggerStartParameters()) {} + void setupEngine() {} + void setupInferior() {} + void runEngine() {} + void shutdownEngine() {} + void shutdownInferior() {} + bool isSessionEngine() const { return true; } void loadSessionData() @@ -2080,7 +2143,7 @@ void DebuggerPluginPrivate::setInitialState() theDebuggerAction(RecheckDebuggingHelpers)->setEnabled(false); theDebuggerAction(AutoDerefPointers)->setEnabled(true); theDebuggerAction(ExpandStack)->setEnabled(false); - theDebuggerAction(ExecuteCommand)->setEnabled(m_state == InferiorStopped); + theDebuggerAction(ExecuteCommand)->setEnabled(m_state == InferiorStopOk); //emit m_plugin->stateChanged(m_state); } @@ -2099,7 +2162,7 @@ void DebuggerPluginPrivate::updateState(DebuggerEngine *engine) m_state = engine->state(); bool actionsEnabled = DebuggerEngine::debuggerActionsEnabled(m_state); - //if (m_state == InferiorStopped) + //if (m_state == InferiorStopOk) // resetLocation(); //qDebug() << "PLUGIN SET STATE: " << m_state; @@ -2108,20 +2171,20 @@ void DebuggerPluginPrivate::updateState(DebuggerEngine *engine) cleanupViews(); } - const bool startIsContinue = (m_state == InferiorStopped); + const bool startIsContinue = (m_state == InferiorStopOk); ICore *core = ICore::instance(); if (startIsContinue) core->updateAdditionalContexts(Core::Context(), m_gdbRunningContext); else core->updateAdditionalContexts(m_gdbRunningContext, Core::Context()); - const bool started = m_state == InferiorRunning - || m_state == InferiorRunningRequested - || m_state == InferiorStopping - || m_state == InferiorStopped; + const bool started = m_state == InferiorRunOk + || m_state == InferiorRunRequested + || m_state == InferiorStopRequested + || m_state == InferiorStopOk; - const bool starting = m_state == EngineSettingUp; - //const bool running = m_state == InferiorRunning; + const bool starting = m_state == EngineSetupRequested; + //const bool running = m_state == InferiorRunOk; m_startExternalAction->setEnabled(!started && !starting); m_attachExternalAction->setEnabled(!started && !starting); @@ -2132,21 +2195,21 @@ void DebuggerPluginPrivate::updateState(DebuggerEngine *engine) #endif m_startRemoteAction->setEnabled(!started && !starting); - const bool detachable = m_state == InferiorStopped + const bool detachable = m_state == InferiorStopOk && engine->startParameters().startMode != AttachCore; m_detachAction->setEnabled(detachable); - const bool stoppable = m_state == InferiorRunning - || m_state == InferiorRunningRequested - || m_state == InferiorStopping - || m_state == InferiorStopped + const bool stoppable = m_state == InferiorRunOk + || m_state == InferiorRunRequested + || m_state == InferiorStopRequested + || m_state == InferiorStopOk || m_state == InferiorUnrunnable; - const bool running = m_state == InferiorRunning; + const bool running = m_state == InferiorRunOk; // FIXME ABC // if (running) // threadsHandler()->notifyRunning(); - const bool stopped = m_state == InferiorStopped; + const bool stopped = m_state == InferiorStopOk; if (stopped) QApplication::alert(mainWindow(), 3000); @@ -2192,9 +2255,9 @@ void DebuggerPluginPrivate::updateState(DebuggerEngine *engine) && (m_capabilities & AutoDerefPointersCapability); theDebuggerAction(AutoDerefPointers)->setEnabled(canDeref); theDebuggerAction(ExpandStack)->setEnabled(actionsEnabled); - theDebuggerAction(ExecuteCommand)->setEnabled(m_state == InferiorStopped); + theDebuggerAction(ExecuteCommand)->setEnabled(m_state == InferiorStopOk); - const bool notbusy = m_state == InferiorStopped + const bool notbusy = m_state == InferiorStopOk || m_state == DebuggerNotReady || m_state == InferiorUnrunnable; setBusyCursor(!notbusy); @@ -2317,7 +2380,7 @@ void DebuggerPluginPrivate::aboutToSaveSession() void DebuggerPluginPrivate::interruptDebuggingRequest() { - if (state() == InferiorRunning) + if (state() == InferiorRunOk) notifyCurrentEngine(RequestExecInterruptRole); else exitDebugger(); @@ -2690,8 +2753,8 @@ bool DebuggerListener::coreAboutToClose() case EngineSetupFailed: // debuggee can cause problems. case InferiorUnrunnable: case InferiorSetupFailed: - case InferiorStopped: - case InferiorShutDown: + case InferiorStopOk: + case InferiorShutdownOk: cleanTermination = true; break; default: diff --git a/src/plugins/debugger/gdb/abstractgdbadapter.cpp b/src/plugins/debugger/gdb/abstractgdbadapter.cpp index bd59e43d00..b3723f1005 100644 --- a/src/plugins/debugger/gdb/abstractgdbadapter.cpp +++ b/src/plugins/debugger/gdb/abstractgdbadapter.cpp @@ -39,7 +39,7 @@ namespace Debugger { namespace Internal { AbstractGdbAdapter::AbstractGdbAdapter(GdbEngine *engine, QObject *parent) - : QObject(parent), m_engine(engine) + : QObject(parent), m_engine(engine) { } @@ -48,19 +48,20 @@ AbstractGdbAdapter::~AbstractGdbAdapter() disconnect(); } -void AbstractGdbAdapter::shutdown() -{ -} +//void AbstractGdbAdapter::shutdown() +//{ +//} -void AbstractGdbAdapter::runAdapter() -{ - qDebug() << "START INFERIOR PHASE 2"; -} +//void AbstractGdbAdapter::runEngine() +//{ +//} +/* const char *AbstractGdbAdapter::inferiorShutdownCommand() const { return "kill"; } +*/ void AbstractGdbAdapter::write(const QByteArray &data) { @@ -87,7 +88,7 @@ QString AbstractGdbAdapter::msgInferiorSetupOk() return tr("Application started"); } -QString AbstractGdbAdapter::msgInferiorRunning() +QString AbstractGdbAdapter::msgInferiorRunOk() { return tr("Application running"); } diff --git a/src/plugins/debugger/gdb/abstractgdbadapter.h b/src/plugins/debugger/gdb/abstractgdbadapter.h index 235c545a1c..955f1f533a 100644 --- a/src/plugins/debugger/gdb/abstractgdbadapter.h +++ b/src/plugins/debugger/gdb/abstractgdbadapter.h @@ -65,10 +65,11 @@ public: virtual void startAdapter() = 0; virtual void setupInferior() = 0; - virtual void runAdapter(); + virtual void runEngine() = 0; virtual void interruptInferior() = 0; - virtual void shutdown(); - virtual const char *inferiorShutdownCommand() const; + virtual void shutdownInferior() = 0; + virtual void shutdownAdapter() = 0; + //virtual const char *inferiorShutdownCommand() const; virtual AbstractGdbProcess *gdbProc() = 0; virtual DumperHandling dumperHandling() const = 0; @@ -77,7 +78,7 @@ public: static QString msgInferiorStopFailed(const QString &why); static QString msgAttachedToStoppedInferior(); static QString msgInferiorSetupOk(); - static QString msgInferiorRunning(); + static QString msgInferiorRunOk(); static QString msgConnectRemoteServerFailed(const QString &why); // Trk specific stuff diff --git a/src/plugins/debugger/gdb/abstractplaingdbadapter.cpp b/src/plugins/debugger/gdb/abstractplaingdbadapter.cpp index 132473745a..483b12da85 100644 --- a/src/plugins/debugger/gdb/abstractplaingdbadapter.cpp +++ b/src/plugins/debugger/gdb/abstractplaingdbadapter.cpp @@ -49,7 +49,7 @@ AbstractPlainGdbAdapter::AbstractPlainGdbAdapter(GdbEngine *engine, void AbstractPlainGdbAdapter::setupInferior() { - QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state()); + QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); if (!startParameters().processArgs.isEmpty()) { QString args = startParameters().processArgs.join(_(" ")); m_engine->postCommand("-exec-arguments " + toLocalEncoding(args)); @@ -60,7 +60,7 @@ void AbstractPlainGdbAdapter::setupInferior() void AbstractPlainGdbAdapter::handleFileExecAndSymbols(const GdbResponse &response) { - QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state()); + QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); if (response.resultClass == GdbResultDone) { if (infoTargetNecessary()) { // Old gdbs do not announce the PID for programs without pthreads. @@ -76,31 +76,33 @@ void AbstractPlainGdbAdapter::handleFileExecAndSymbols(const GdbResponse &respon // Extend the message a bit in unknown cases. if (!ba.endsWith("File format not recognized")) msg = tr("Starting executable failed:\n") + msg; - m_engine->handleInferiorSetupFailed(msg); + m_engine->notifyInferiorSetupFailed(msg); } } -void AbstractPlainGdbAdapter::runAdapter() +void AbstractPlainGdbAdapter::runEngine() { - setState(InferiorRunningRequested); + QTC_ASSERT(state() == EngineRunRequested, qDebug() << state()); m_engine->postCommand("-exec-run", GdbEngine::RunRequest, CB(handleExecRun)); } void AbstractPlainGdbAdapter::handleExecRun(const GdbResponse &response) { + QTC_ASSERT(state() == EngineRunRequested, qDebug() << state()); if (response.resultClass == GdbResultRunning) { - QTC_ASSERT(state() == InferiorRunning, qDebug() << state()); + m_engine->notifyEngineRunAndInferiorRunOk(); + //showStatusMessage(tr("Running...")); showMessage(_("INFERIOR STARTED")); showMessage(msgInferiorSetupOk(), StatusBar); // FIXME: That's the wrong place for it. if (theDebuggerBoolSetting(EnableReverseDebugging)) m_engine->postCommand("target record"); } else { - QTC_ASSERT(state() == InferiorRunningRequested, qDebug() << state()); QString msg = fromLocalEncoding(response.data.findChild("msg").data()); - //QTC_ASSERT(status() == InferiorRunning, /**/); + //QTC_ASSERT(status() == InferiorRunOk, /**/); //interruptInferior(); - m_engine->handleInferiorSetupFailed(msg); + showMessage(msg); + m_engine->notifyEngineRunFailed(); } } @@ -118,10 +120,10 @@ void AbstractPlainGdbAdapter::handleInfoTarget(const GdbResponse &response) m_engine->postCommand("tbreak *0x" + needle.cap(1).toAscii()); // Do nothing here - inferiorPrepared handles the sequencing. } else { - m_engine->handleInferiorSetupFailed(_("Parsing start address failed")); + m_engine->notifyInferiorSetupFailed(_("Parsing start address failed")); } } else if (response.resultClass == GdbResultError) { - m_engine->handleInferiorSetupFailed(_("Fetching start address failed")); + m_engine->notifyInferiorSetupFailed(_("Fetching start address failed")); } } diff --git a/src/plugins/debugger/gdb/abstractplaingdbadapter.h b/src/plugins/debugger/gdb/abstractplaingdbadapter.h index a0495db6a4..a6b60e0188 100644 --- a/src/plugins/debugger/gdb/abstractplaingdbadapter.h +++ b/src/plugins/debugger/gdb/abstractplaingdbadapter.h @@ -36,13 +36,15 @@ namespace Debugger { namespace Internal { class AbstractPlainGdbAdapter : public AbstractGdbAdapter -{ // Needs tr - context +{ + // Needs tr - context Q_OBJECT + public: AbstractPlainGdbAdapter(GdbEngine *engine, QObject *parent = 0); - virtual void setupInferior(); - virtual void runAdapter(); + void setupInferior(); + void runEngine(); protected: void handleInfoTarget(const GdbResponse &response); diff --git a/src/plugins/debugger/gdb/attachgdbadapter.cpp b/src/plugins/debugger/gdb/attachgdbadapter.cpp index 8aa954ef72..a34f6562a9 100644 --- a/src/plugins/debugger/gdb/attachgdbadapter.cpp +++ b/src/plugins/debugger/gdb/attachgdbadapter.cpp @@ -56,7 +56,7 @@ AttachGdbAdapter::AttachGdbAdapter(GdbEngine *engine, QObject *parent) void AttachGdbAdapter::startAdapter() { - QTC_ASSERT(state() == EngineSettingUp, qDebug() << state()); + QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state()); showMessage(_("TRYING TO START ADAPTER")); if (!m_engine->startGdb()) @@ -67,34 +67,52 @@ void AttachGdbAdapter::startAdapter() void AttachGdbAdapter::setupInferior() { - QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state()); + QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); const qint64 pid = startParameters().attachPID; m_engine->postCommand("attach " + QByteArray::number(pid), CB(handleAttach)); // Task 254674 does not want to remove them //qq->breakHandler()->removeAllBreakpoints(); } +void AttachGdbAdapter::runEngine() +{ + QTC_ASSERT(state() == EngineRunRequested, qDebug() << state()); + m_engine->notifyInferiorStopOk(); +} + void AttachGdbAdapter::handleAttach(const GdbResponse &response) { - QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state()); + QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); if (response.resultClass == GdbResultDone) { - setState(InferiorStopped); showMessage(_("INFERIOR ATTACHED")); showMessage(msgAttachedToStoppedInferior(), StatusBar); m_engine->handleInferiorPrepared(); m_engine->updateAll(); } else { QString msg = QString::fromLocal8Bit(response.data.findChild("msg").data()); - m_engine->handleInferiorSetupFailed(msg); + m_engine->notifyInferiorSetupFailed(msg); } } void AttachGdbAdapter::interruptInferior() { + QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state(); return); const qint64 pid = startParameters().attachPID; QTC_ASSERT(pid > 0, return); - if (!interruptProcess(pid)) + if (!interruptProcess(pid)) { showMessage(_("CANNOT INTERRUPT %1").arg(pid)); + m_engine->notifyInferiorStopFailed(); + } +} + +void AttachGdbAdapter::shutdownInferior() +{ + m_engine->defaultInferiorShutdown("detach"); +} + +void AttachGdbAdapter::shutdownAdapter() +{ + m_engine->notifyAdapterShutdownOk(); } } // namespace Internal diff --git a/src/plugins/debugger/gdb/attachgdbadapter.h b/src/plugins/debugger/gdb/attachgdbadapter.h index 6611865a24..8140c2d7c7 100644 --- a/src/plugins/debugger/gdb/attachgdbadapter.h +++ b/src/plugins/debugger/gdb/attachgdbadapter.h @@ -50,15 +50,17 @@ class AttachGdbAdapter : public AbstractGdbAdapter public: AttachGdbAdapter(GdbEngine *engine, QObject *parent = 0); - virtual DumperHandling dumperHandling() const { return DumperLoadedByGdb; } +private: + DumperHandling dumperHandling() const { return DumperLoadedByGdb; } void startAdapter(); void setupInferior(); + void runEngine(); void interruptInferior(); - const char *inferiorShutdownCommand() const { return "detach"; } - AbstractGdbProcess *gdbProc() { return &m_gdbProc; } + void shutdownInferior(); + void shutdownAdapter(); -private: + AbstractGdbProcess *gdbProc() { return &m_gdbProc; } void handleAttach(const GdbResponse &response); LocalGdbProcess m_gdbProc; diff --git a/src/plugins/debugger/gdb/classicgdbengine.cpp b/src/plugins/debugger/gdb/classicgdbengine.cpp index 786250b7d9..409ab16529 100644 --- a/src/plugins/debugger/gdb/classicgdbengine.cpp +++ b/src/plugins/debugger/gdb/classicgdbengine.cpp @@ -574,7 +574,7 @@ void GdbEngine::updateAllClassic() { PRECONDITION; PENDING_DEBUG("UPDATING ALL\n"); - QTC_ASSERT(state() == InferiorUnrunnable || state() == InferiorStopped, /**/); + QTC_ASSERT(state() == InferiorUnrunnable || state() == InferiorStopOk, /**/); tryLoadDebuggingHelpersClassic(); reloadModulesInternal(); postCommand("-stack-list-frames", WatchUpdate, diff --git a/src/plugins/debugger/gdb/coregdbadapter.cpp b/src/plugins/debugger/gdb/coregdbadapter.cpp index 82f6f83372..b656c59e53 100644 --- a/src/plugins/debugger/gdb/coregdbadapter.cpp +++ b/src/plugins/debugger/gdb/coregdbadapter.cpp @@ -59,7 +59,7 @@ CoreGdbAdapter::CoreGdbAdapter(GdbEngine *engine, QObject *parent) void CoreGdbAdapter::startAdapter() { - QTC_ASSERT(state() == EngineSettingUp, qDebug() << state()); + QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state()); showMessage(_("TRYING TO START ADAPTER")); if (!m_engine->startGdb()) @@ -70,7 +70,7 @@ void CoreGdbAdapter::startAdapter() void CoreGdbAdapter::setupInferior() { - QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state()); + QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); m_executable = startParameters().executable; if (m_executable.isEmpty()) { #ifdef EXE_FROM_CORE @@ -103,7 +103,7 @@ void CoreGdbAdapter::loadExeAndSyms() void CoreGdbAdapter::handleFileExecAndSymbols(const GdbResponse &response) { - QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state()); + QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); if (response.resultClass == GdbResultDone) { showMessage(tr("Symbols found."), StatusBar); } else { @@ -124,7 +124,7 @@ void CoreGdbAdapter::loadCoreFile() void CoreGdbAdapter::handleTargetCore(const GdbResponse &response) { - QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state()); + QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); if (response.resultClass == GdbResultDone) { #ifdef EXE_FROM_CORE if (m_round == 1) { @@ -160,22 +160,32 @@ void CoreGdbAdapter::handleTargetCore(const GdbResponse &response) } else { QString msg = tr("Attach to core \"%1\" failed:\n").arg(startParameters().coreFile) + QString::fromLocal8Bit(response.data.findChild("msg").data()); - m_engine->handleInferiorSetupFailed(msg); + m_engine->notifyInferiorSetupFailed(msg); } } -void CoreGdbAdapter::runAdapter() +void CoreGdbAdapter::runEngine() { - QTC_ASSERT(state() == InferiorSetupOk, qDebug() << state()); - setState(InferiorUnrunnable); + QTC_ASSERT(state() == EngineRunRequested, qDebug() << state()); + m_engine->notifyInferiorUnrunnable(); m_engine->updateAll(); } void CoreGdbAdapter::interruptInferior() { - // A core should never 'run' + // A core never runs, so this cannot be called. QTC_ASSERT(false, /**/); } +void CoreGdbAdapter::shutdownInferior() +{ + m_engine->notifyInferiorShutdownOk(); +} + +void CoreGdbAdapter::shutdownAdapter() +{ + m_engine->notifyAdapterShutdownOk(); +} + } // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/gdb/coregdbadapter.h b/src/plugins/debugger/gdb/coregdbadapter.h index b4147c8630..b1df5e535f 100644 --- a/src/plugins/debugger/gdb/coregdbadapter.h +++ b/src/plugins/debugger/gdb/coregdbadapter.h @@ -59,8 +59,10 @@ private: void startAdapter(); void setupInferior(); - void runAdapter(); + void runEngine(); void interruptInferior(); + void shutdownInferior(); + void shutdownAdapter(); AbstractGdbProcess *gdbProc() { return &m_gdbProc; } diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index ddd6f994bf..38651fcaee 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -122,26 +122,29 @@ QByteArray GdbEngine::tooltipIName(const QString &exp) static bool stateAcceptsGdbCommands(DebuggerState state) { switch (state) { - case EngineSettingUp: + case EngineSetupRequested: case EngineSetupOk: case EngineSetupFailed: case InferiorUnrunnable: - case InferiorSettingUp: + case InferiorSetupRequested: case InferiorSetupFailed: - case InferiorSetupOk: - case InferiorRunningRequested: - case InferiorRunningRequested_Kill: - case InferiorRunning: - case InferiorStopping: - case InferiorStopping_Kill: - case InferiorStopped: - case InferiorShuttingDown: - case InferiorShutDown: + case EngineRunRequested: + case InferiorRunRequested: + case InferiorRunOk: + case InferiorStopRequested: + case InferiorStopOk: + case InferiorShutdownRequested: + case EngineShutdownRequested: + case InferiorShutdownOk: case InferiorShutdownFailed: return true; case DebuggerNotReady: case InferiorStopFailed: - case EngineShuttingDown: + case EngineRunFailed: + case InferiorRunFailed: + case EngineShutdownOk: + case EngineShutdownFailed: + case DebuggerFinished: return false; } return false; @@ -532,13 +535,14 @@ void GdbEngine::handleResponse(const QByteArray &buff) m_progress->setProgressValue(100); m_progress->reportFinished(); } - if (state() == InferiorStopped) { // Result of manual command. - resetLocation(); - setTokenBarrier(); - setState(InferiorRunningRequested); - } - setState(InferiorRunning); - showStatusMessage(tr("Running...")); + // FIXME: Handle this in the individual result handlers. + //if (state() == InferiorStopOk) { // Result of manual command. + // resetLocation(); + // setTokenBarrier(); + // setState(InferiorRunRequested); + //} + //setState(InferiorRunOk); + //showStatusMessage(tr("Running...")); response.resultClass = GdbResultRunning; } else if (resultClass == "connected") { response.resultClass = GdbResultConnected; @@ -635,11 +639,8 @@ void GdbEngine::readGdbStandardOutput() void GdbEngine::interruptInferior() { - QTC_ASSERT(state() == InferiorRunning, qDebug() << state(); return); - - setState(InferiorStopping); + QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state(); return); showStatusMessage(tr("Stop requested..."), 5000); - showMessage(_("TRYING TO INTERRUPT INFERIOR")); m_gdbAdapter->interruptInferior(); } @@ -649,7 +650,8 @@ void GdbEngine::interruptInferiorTemporarily() interruptInferior(); foreach (const GdbCommand &cmd, m_commandsToRunOnTemporaryBreak) { if (cmd.flags & LosesChild) { - setState(InferiorStopping_Kill); + notifyInferiorIll(); + //setState(InferiorStopRequested_Kill); break; } } @@ -736,35 +738,39 @@ void GdbEngine::postCommandHelper(const GdbCommand &cmd) flushCommand(cmd); } else if ((cmd.flags & NeedsStop) || !m_commandsToRunOnTemporaryBreak.isEmpty()) { - if (state() == InferiorStopped || state() == InferiorUnrunnable - || state() == InferiorSettingUp || state() == EngineSetupOk) { + if (state() == InferiorStopOk || state() == InferiorUnrunnable + || state() == InferiorSetupRequested || state() == EngineSetupOk + || state() == InferiorShutdownRequested) { // Can be safely sent now. flushCommand(cmd); } else { // Queue the commands that we cannot send at once. showMessage(_("QUEUING COMMAND " + cmd.command)); m_commandsToRunOnTemporaryBreak.append(cmd); - if (state() == InferiorStopping) { - if (cmd.flags & LosesChild) - setState(InferiorStopping_Kill); + if (state() == InferiorStopRequested) { + if (cmd.flags & LosesChild) { + notifyInferiorIll(); + //setState(InferiorStopRequested_Kill); + } showMessage(_("CHILD ALREADY BEING INTERRUPTED. STILL HOPING.")); // Calling shutdown() here breaks all situations where two // NeedsStop commands are issued in quick succession. - } else if (state() == InferiorStopping_Kill) { - showMessage(_("CHILD ALREADY BEING INTERRUPTED (KILL PENDING)")); - // FIXME - shutdown(); - } else if (state() == InferiorRunningRequested) { - if (cmd.flags & LosesChild) - setState(InferiorRunningRequested_Kill); - showMessage(_("RUNNING REQUESTED; POSTPONING INTERRUPT")); - } else if (state() == InferiorRunningRequested_Kill) { - showMessage(_("RUNNING REQUESTED; POSTPONING INTERRUPT (KILL PENDING)")); - } else if (state() == InferiorRunning) { + //} else if (state() == InferiorStopRequested_Kill) { + // showMessage(_("CHILD ALREADY BEING INTERRUPTED (KILL PENDING)")); + // // FIXME + // shutdown(); + //} else if (state() == InferiorRunRequested) { + // if (cmd.flags & LosesChild) + // setState(InferiorRunRequested_Kill); + // showMessage(_("RUNNING REQUESTED; POSTPONING INTERRUPT")); + //} else if (state() == InferiorRunRequested_Kill) { + // showMessage(_("RUNNING REQUESTED; POSTPONING INTERRUPT (KILL PENDING)")); + } else if (state() == InferiorRunOk) { showStatusMessage(tr("Stopping temporarily"), 1000); interruptInferiorTemporarily(); } else { - qDebug() << "ATTEMPTING TO QUEUE COMMAND IN INAPPROPRIATE STATE" << state(); + qDebug() << "ATTEMPTING TO QUEUE COMMAND " + << cmd.command << "IN INAPPROPRIATE STATE" << state(); } } } else if (!cmd.command.isEmpty()) { @@ -804,8 +810,8 @@ void GdbEngine::flushCommand(const GdbCommand &cmd0) m_commandTimer->start(); - if (cmd.flags & LosesChild) - setState(InferiorShuttingDown); + //if (cmd.flags & LosesChild) + // setState(InferiorShutdownRequested); } int GdbEngine::commandTimeoutTime() const @@ -883,34 +889,32 @@ void GdbEngine::handleResultRecord(GdbResponse *response) showMessageBox(QMessageBox::Critical, tr("Executable failed"), QString::fromLocal8Bit(msg)); showStatusMessage(tr("Process failed to start")); - shutdown(); + //shutdown(); + notifyInferiorIll(); } else if (msg == "\"finish\" not meaningful in the outermost frame.") { // Handle a case known to appear on gdb 6.4 symbianelf when // the stack is cut due to access to protected memory. - showMessage(_("APPLYING WORKAROUND #2")); - setState(InferiorStopping); - setState(InferiorStopped); + //showMessage(_("APPLYING WORKAROUND #2")); + notifyInferiorStopOk(); } else if (msg.startsWith("Cannot find bounds of current function")) { // Happens when running "-exec-next" in a function for which // there is no debug information. Divert to "-exec-next-step" showMessage(_("APPLYING WORKAROUND #3")); - setState(InferiorStopping); - setState(InferiorStopped); + notifyInferiorStopOk(); executeNextI(); } else if (msg.startsWith("Couldn't get registers: No such process.")) { // Happens on archer-tromey-python 6.8.50.20090910-cvs // There might to be a race between a process shutting down // and library load messages. showMessage(_("APPLYING WORKAROUND #4")); - setState(InferiorStopping); - setState(InferiorStopped); - setState(InferiorShuttingDown); - setState(InferiorShutDown); - showStatusMessage(tr("Executable failed: %1") - .arg(QString::fromLocal8Bit(msg))); - shutdown(); - showMessageBox(QMessageBox::Critical, - tr("Executable failed"), QString::fromLocal8Bit(msg)); + notifyInferiorStopOk(); + //setState(InferiorShutdownRequested); + //setState(InferiorShutdownOk); + //showStatusMessage(tr("Executable failed: %1") + // .arg(QString::fromLocal8Bit(msg))); + //shutdown(); + //showMessageBox(QMessageBox::Critical, + // tr("Executable failed"), QString::fromLocal8Bit(msg)); } else { showMessageBox(QMessageBox::Critical, tr("Executable failed"), QString::fromLocal8Bit(msg)); @@ -993,7 +997,7 @@ void GdbEngine::handleResultRecord(GdbResponse *response) // was postponed. // This is done after the command callbacks so the running-requesting commands // can assert on the right state. - if (state() == InferiorRunning && !m_commandsToRunOnTemporaryBreak.isEmpty()) + if (state() == InferiorRunOk && !m_commandsToRunOnTemporaryBreak.isEmpty()) interruptInferiorTemporarily(); // Continue only if there are no commands wire anymore, so this will @@ -1069,7 +1073,7 @@ void GdbEngine::handleExecuteJumpToLine(const GdbResponse &response) } else if (response.resultClass == GdbResultDone) { // This happens on old gdb. Trigger the effect of a '*stopped'. showStatusMessage(tr("Jumped. Stopped")); - setState(InferiorStopped); + setState(InferiorStopOk); handleStop1(response); } } @@ -1087,7 +1091,7 @@ void GdbEngine::handleExecuteRunToLine(const GdbResponse &response) //>122^done gotoLocation(m_targetFrame, true); showStatusMessage(tr("Target line hit. Stopped")); - setState(InferiorStopped); + setState(InferiorStopOk); handleStop1(response); } } @@ -1101,8 +1105,8 @@ void GdbEngine::handleExecuteRunToFunction(const GdbResponse &response) // 14*stopped,thread-id="1",frame={addr="0x0000000000403ce4", // func="foo",args=[{name="str",value="@0x7fff0f450460"}], // file="main.cpp",fullname="/tmp/g/main.cpp",line="37"} - QTC_ASSERT(state() == InferiorStopping, qDebug() << state()) - setState(InferiorStopped); + QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state()) + setState(InferiorStopOk); showStatusMessage(tr("Function reached. Stopped")); GdbMi frame = response.data.findChild("frame"); StackFrame f = parseStackFrame(frame, 0); @@ -1163,20 +1167,16 @@ void GdbEngine::handleStopResponse(const GdbMi &data) { // This is gdb 7+'s initial *stopped in response to attach. // For consistency, we just discard it. - if (state() == InferiorSettingUp) + if (state() == InferiorSetupRequested) return; const QByteArray reason = data.findChild("reason").data(); if (isExitedReason(reason)) { - if (state() == InferiorRunning) { - setState(InferiorStopping); - } else { - // The user triggered a stop, but meanwhile the app simply exited ... - QTC_ASSERT(state() == InferiorStopping || state() == InferiorStopping_Kill, - qDebug() << state()); - } - setState(InferiorStopped); + // // The user triggered a stop, but meanwhile the app simply exited ... + // QTC_ASSERT(state() == InferiorStopRequested + // /*|| state() == InferiorStopRequested_Kill*/, + // qDebug() << state()); QString msg; if (reason == "exited") { msg = tr("Application exited with exit code %1") @@ -1188,34 +1188,36 @@ void GdbEngine::handleStopResponse(const GdbMi &data) msg = tr("Application exited normally"); } showStatusMessage(msg); - setState(InferiorShuttingDown); - setState(InferiorShutDown); - shutdown(); + notifyInferiorExited(); return; } if (!m_commandsToRunOnTemporaryBreak.isEmpty()) { - QTC_ASSERT(state() == InferiorStopping || state() == InferiorStopping_Kill, - qDebug() << state()) - setState(InferiorStopped); + QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state()) + //setState(InferiorStopOk); flushQueuedCommands(); - if (state() == InferiorStopped) { + if (state() == InferiorStopOk) { QTC_ASSERT(m_commandsDoneCallback == 0, /**/); m_commandsDoneCallback = &GdbEngine::autoContinueInferior; } else { - QTC_ASSERT(state() == InferiorShuttingDown, qDebug() << state()) + QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << state()) } return; } - if (state() == InferiorRunning) { + if (state() == InferiorRunOk) { // Stop triggered by a breakpoint or otherwise not directly // initiated by the user. - setState(InferiorStopping); + notifyInferiorSpontaneousStop(); + } else if (state() == InferiorRunRequested) { + // Stop triggered by somethin like "-exec-step\n" + // "&"Cannot access memory at address 0xbfffedd4\n" + // In this case a proper response 94^error,msg="" will follow and + // be handled in the result handler. } else { - QTC_ASSERT(state() == InferiorStopping, qDebug() << state()); + QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state()); + notifyInferiorStopOk(); } - setState(InferiorStopped); #if 0 // See http://vladimir_prus.blogspot.com/2007/12/debugger-stories-pending-breakpoints.html // Due to LD_PRELOADing the dumpers, these events can occur even before @@ -1534,34 +1536,36 @@ void GdbEngine::handleHasPython(const GdbResponse &response) } } +void GdbEngine::showExecutionError(const QString &message) +{ + showMessageBox(QMessageBox::Critical, tr("Execution Error"), + tr("Cannot continue debugged process:\n") + message); +} + void GdbEngine::handleExecuteContinue(const GdbResponse &response) { + QTC_ASSERT(state() == InferiorRunRequested, qDebug() << state()); if (response.resultClass == GdbResultRunning) { - // The "running" state is picked up in handleResponse() - QTC_ASSERT(state() == InferiorRunning, /**/); - } else { - if (state() == InferiorRunningRequested_Kill) { - setState(InferiorStopped); - shutdown(); + notifyInferiorRunOk(); + return; + } + QByteArray msg = response.data.findChild("msg").data(); + if (msg.startsWith("Cannot find bounds of current function") + || msg.startsWith("\"finish\" not meaningful in the outermost frame")) { + notifyInferiorRunFailed(); + if (isDying()) return; - } - QTC_ASSERT(state() == InferiorRunningRequested, /**/); - setState(InferiorStopped); - QByteArray msg = response.data.findChild("msg").data(); - if (msg.startsWith("Cannot find bounds of current function") - || msg.startsWith("\"finish\" not meaningful in the outermost frame")) { - if (!m_commandsToRunOnTemporaryBreak.isEmpty()) - flushQueuedCommands(); - showStatusMessage(tr("Stopped."), 5000); - reloadStack(true); - //showStatusMessage(tr("No debug information available. " - // "Leaving function...")); - //executeStepOut(); - } else { - showMessageBox(QMessageBox::Critical, tr("Execution Error"), - tr("Cannot continue debugged process:\n") + QString::fromLocal8Bit(msg)); - shutdown(); - } + if (!m_commandsToRunOnTemporaryBreak.isEmpty()) + flushQueuedCommands(); + QTC_ASSERT(state() == InferiorStopOk, qDebug() << state()); + showStatusMessage(tr("Stopped."), 5000); + reloadStack(true); + //showStatusMessage(tr("No debug information available. " + // "Leaving function...")); + //executeStepOut(); + } else { + showExecutionError(QString::fromLocal8Bit(msg)); + notifyInferiorIll(); } } @@ -1587,114 +1591,142 @@ QString GdbEngine::cleanupFullName(const QString &fileName) } #endif -void GdbEngine::shutdown() +void GdbEngine::shutdownInferior() +{ + QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << state()); + m_commandsToRunOnTemporaryBreak.clear(); + m_gdbAdapter->shutdownInferior(); +} + +void GdbEngine::defaultInferiorShutdown(const char *cmd) { + QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << state()); + postCommand(cmd, NeedsStop | LosesChild, CB(handleInferiorShutdown)); +} + +void GdbEngine::handleInferiorShutdown(const GdbResponse &response) +{ + QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << state()); + if (response.resultClass == GdbResultDone) { + notifyInferiorShutdownOk(); + return; + } + QByteArray ba = response.data.findChild("msg").data(); + if (ba.contains(": No such file or directory.")) { + // This happens when someone removed the binary behind our back. + // It is not really an error from a user's point of view. + showMessage(_("NOTE: " + ba)); + notifyInferiorShutdownOk(); + return; + } + showMessageBox(QMessageBox::Critical, + tr("Failed to shut down application"), + AbstractGdbAdapter::msgInferiorStopFailed(QString::fromLocal8Bit(ba))); + notifyInferiorShutdownFailed(); +} + +void GdbEngine::shutdownEngine() +{ + m_gdbAdapter->shutdownAdapter(); +} + +void GdbEngine::notifyAdapterShutdownFailed() +{ + showMessage(_("ADAPTER SHUTDOWN FAILED")); + QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state()); + notifyEngineShutdownFailed(); +} + +void GdbEngine::notifyAdapterShutdownOk() +{ + QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state()); showMessage(_("INITIATE GDBENGINE SHUTDOWN IN STATE %1, PROC: %2") - .arg(state()).arg(gdbProc()->state())); + .arg(lastGoodState()).arg(gdbProc()->state())); if (m_progress) { m_progress->setProgressValue(90); m_progress->reportCanceled(); m_progress->reportFinished(); } - switch (state()) { - case DebuggerNotReady: // Nothing to do! :) - case InferiorShuttingDown: // Will auto-trigger further shutdown steps - case EngineShuttingDown: // Do not disturb! :) - case InferiorRunningRequested_Kill: - case InferiorStopping_Kill: + + m_commandsDoneCallback = 0; + postCommand("-gdb-exit", GdbEngine::ExitRequest, CB(handleGdbExit)); +} + +void GdbEngine::handleGdbExit(const GdbResponse &response) +{ + if (response.resultClass == GdbResultExit) { + showMessage(_("GDB CLAIMS EXIT; WAITING")); + // Don't set state here, this will be handled in handleGdbFinished() + //notifyEngineShutdownOk(); + } else { + QString msg = m_gdbAdapter->msgGdbStopFailed( + QString::fromLocal8Bit(response.data.findChild("msg").data())); + qDebug() << (_("GDB WON'T EXIT (%1); KILLING IT").arg(msg)); + showMessage(_("GDB WON'T EXIT (%1); KILLING IT").arg(msg)); + gdbProc()->kill(); + } +} + +#if 0 + switch (lastGoodState()) { + case DebuggerNotReady: // Neutral. + notifyEngineShutdownOk(); + break; + case DebuggerFinished: // Should not happen. + case EngineRunFailed: // Should not happen. + case InferiorRunRequested: + case InferiorRunOk: + case InferiorStopRequested: + case InferiorStopOk: + QTC_ASSERT(false, qDebug() << lastGoodState()); + notifyEngineShutdownOk(); break; - case EngineSettingUp: // GDB is up, adapter is "doing something" - setState(EngineSetupFailed); - m_gdbAdapter->shutdown(); + case InferiorShutdownRequested: // Will auto-trigger further shutdown steps + case EngineShutdownRequested: // Do not disturb! :) + case EngineShutdownOk: + case EngineShutdownFailed: + //case InferiorRunRequested_Kill: + //case InferiorStopRequested_Kill: + QTC_ASSERT(false, qDebug() << lastGoodState()); + notifyEngineShutdownOk(); + break; + case EngineSetupRequested: // GDB is up, adapter is "doing something" + m_gdbAdapter->shutdownAdapter(); // fall-through case EngineSetupFailed: // Adapter "did something", but it did not help if (gdbProc()->state() == QProcess::Running) { m_commandsToRunOnTemporaryBreak.clear(); postCommand("-gdb-exit", GdbEngine::ExitRequest, CB(handleGdbExit)); } else { - setState(DebuggerNotReady); + gdbProc()->kill(); } break; - case InferiorRunningRequested: - case InferiorRunning: - case InferiorStopping: - case InferiorStopped: - m_commandsToRunOnTemporaryBreak.clear(); - postCommand(m_gdbAdapter->inferiorShutdownCommand(), - NeedsStop | LosesChild, CB(handleInferiorShutdown)); - break; + case EngineSetupOk: // We can't get here, really - case InferiorSetupOk: + case EngineRunRequested: case InferiorSetupFailed: - case InferiorShutDown: + case InferiorShutdownOk: case InferiorShutdownFailed: // Whatever case InferiorUnrunnable: m_commandsToRunOnTemporaryBreak.clear(); postCommand("-gdb-exit", GdbEngine::ExitRequest, CB(handleGdbExit)); - setState(EngineShuttingDown); // Do it after posting the command! break; - case InferiorSettingUp: // This may take some time, so just short-circuit it + case InferiorSetupRequested: // This may take some time, so just short-circuit it setState(InferiorSetupFailed); - // fall-through - case InferiorStopFailed: // Tough luck, I guess. But unreachable as of now anyway. - setState(EngineShuttingDown); gdbProc()->kill(); break; - } -} - -void GdbEngine::handleInferiorShutdown(const GdbResponse &response) -{ - QTC_ASSERT(state() == InferiorShuttingDown, qDebug() << state()); - if (response.resultClass == GdbResultDone) { - showMessage(_("INFERIOR SUCCESSFULLY SHUT DOWN")); - setState(InferiorShutDown); - } else { - QByteArray ba = response.data.findChild("msg").data(); - if (ba.contains(": No such file or directory.")) { - // This happens when someone removed the binary behind our back. - // It is not really an error from a user's point of view. - showMessage(_("INFERIOR SUCCESSFULLY SHUT DOWN")); - showMessage(_("NOTE: " + ba)); - setState(InferiorShutDown); - } else { - showMessage(_("INFERIOR SHUTDOWN FAILED")); - setState(InferiorShutdownFailed); - showMessageBox(QMessageBox::Critical, - tr("Failed to shut down application"), - m_gdbAdapter->msgInferiorStopFailed(QString::fromLocal8Bit(ba))); - } - } - shutdown(); // re-iterate... -} - -void GdbEngine::handleGdbExit(const GdbResponse &response) -{ - if (response.resultClass == GdbResultExit) { - showMessage(_("GDB CLAIMS EXIT; WAITING")); - m_commandsDoneCallback = 0; - // Don't set state here, this will be handled in handleGdbFinished() - } else { - QString msg = m_gdbAdapter->msgGdbStopFailed( - QString::fromLocal8Bit(response.data.findChild("msg").data())); - showMessage(_("GDB WON'T EXIT (%1); KILLING IT").arg(msg)); + case InferiorStopFailed: // Tough luck, I guess. But unreachable as of now anyway. gdbProc()->kill(); + break; } -} +#endif void GdbEngine::detachDebugger() { - QTC_ASSERT(state() == InferiorStopped, /**/); - QTC_ASSERT(startMode() != AttachCore, /**/); + QTC_ASSERT(state() == InferiorStopOk, qDebug() << state()); + QTC_ASSERT(startMode() != AttachCore, qDebug() << startMode()); postCommand("detach"); - setState(InferiorShuttingDown); - setState(InferiorShutDown); - shutdown(); -} - -void GdbEngine::exitDebugger() -{ - shutdown(); + notifyInferiorExited(); } void GdbEngine::quitDebugger() @@ -1704,7 +1736,7 @@ void GdbEngine::quitDebugger() // to force it down. On the other hand, there could be an answer, // and regular the inferior shutdown procedure could take a while. // And the RunControl::stop() is called synchroneously. - shutdown(); + shutdownEngine(); initializeVariables(); setState(DebuggerNotReady); } @@ -1764,7 +1796,7 @@ AbstractGdbAdapter *GdbEngine::createAdapter() void GdbEngine::setupEngine() { //qDebug() << "GDB START DEBUGGER"; - QTC_ASSERT(state() == EngineSettingUp, qDebug() << state()); + QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state()); QTC_ASSERT(m_debuggingHelperState == DebuggingHelperUninitialized, /**/); QTC_ASSERT(m_gdbAdapter == 0, /**/); @@ -1788,7 +1820,7 @@ void GdbEngine::setupEngine() } m_progress->setProgressValue(20); - QTC_ASSERT(state() == EngineSettingUp, /**/); + QTC_ASSERT(state() == EngineSetupRequested, /**/); m_gdbAdapter->startAdapter(); } @@ -1807,9 +1839,9 @@ unsigned GdbEngine::debuggerCapabilities() const void GdbEngine::continueInferiorInternal() { - QTC_ASSERT(state() == InferiorStopped || state() == InferiorSettingUp, - qDebug() << state()); - setState(InferiorRunningRequested); + QTC_ASSERT(state() == InferiorRunRequested, qDebug() << state()); + //QTC_ASSERT(state() == InferiorStopOk || state() == InferiorSetupRequested, + // qDebug() << state()); postCommand("-exec-continue", RunRequest, CB(handleExecuteContinue)); } @@ -1821,17 +1853,19 @@ void GdbEngine::autoContinueInferior() void GdbEngine::continueInferior() { + QTC_ASSERT(state() == InferiorStopOk, qDebug() << state()); resetLocation(); setTokenBarrier(); + notifyInferiorRunRequested(); continueInferiorInternal(); showStatusMessage(tr("Running requested..."), 5000); } void GdbEngine::executeStep() { - QTC_ASSERT(state() == InferiorStopped, qDebug() << state()); + QTC_ASSERT(state() == InferiorStopOk, qDebug() << state()); setTokenBarrier(); - setState(InferiorRunningRequested); + notifyInferiorRunRequested(); showStatusMessage(tr("Step requested..."), 5000); if (m_gdbAdapter->isTrkAdapter() && stackHandler()->stackSize() > 0) postCommand("sal step," + stackHandler()->topAddress().toLatin1()); @@ -1843,36 +1877,30 @@ void GdbEngine::executeStep() void GdbEngine::handleExecuteStep(const GdbResponse &response) { + QTC_ASSERT(state() == InferiorRunRequested, qDebug() << state()); if (response.resultClass == GdbResultRunning) { - // The "running" state is picked up in handleResponse(). - QTC_ASSERT(state() == InferiorRunning, /**/); - } else { - if (state() == InferiorRunningRequested_Kill) { - setState(InferiorStopped); - shutdown(); + notifyInferiorRunOk(); + return; + } + QByteArray msg = response.data.findChild("msg").data(); + if (msg.startsWith("Cannot find bounds of current function")) { + notifyInferiorRunFailed(); + if (isDying()) return; - } - QTC_ASSERT(state() == InferiorRunningRequested, /**/); - setState(InferiorStopped); - QByteArray msg = response.data.findChild("msg").data(); - if (msg.startsWith("Cannot find bounds of current function")) { - if (!m_commandsToRunOnTemporaryBreak.isEmpty()) - flushQueuedCommands(); - executeStepI(); // Fall back to instruction-wise stepping. - } else { - showMessageBox(QMessageBox::Critical, tr("Execution Error"), - tr("Cannot continue debugged process:\n") - + QString::fromLocal8Bit(msg)); - shutdown(); - } + if (!m_commandsToRunOnTemporaryBreak.isEmpty()) + flushQueuedCommands(); + executeStepI(); // Fall back to instruction-wise stepping. + } else { + showExecutionError(QString::fromLocal8Bit(msg)); + notifyInferiorIll(); } } void GdbEngine::executeStepI() { - QTC_ASSERT(state() == InferiorStopped, qDebug() << state()); + QTC_ASSERT(state() == InferiorStopOk, qDebug() << state()); setTokenBarrier(); - setState(InferiorRunningRequested); + notifyInferiorRunRequested(); showStatusMessage(tr("Step by instruction requested..."), 5000); if (isReverseDebugging()) postCommand("reverse-stepi", RunRequest, CB(handleExecuteContinue)); @@ -1882,19 +1910,19 @@ void GdbEngine::executeStepI() void GdbEngine::executeStepOut() { - QTC_ASSERT(state() == InferiorStopped, qDebug() << state()); + QTC_ASSERT(state() == InferiorStopOk, qDebug() << state()); postCommand("-stack-select-frame 0"); setTokenBarrier(); - setState(InferiorRunningRequested); + notifyInferiorRunRequested(); showStatusMessage(tr("Finish function requested..."), 5000); postCommand("-exec-finish", RunRequest, CB(handleExecuteContinue)); } void GdbEngine::executeNext() { - QTC_ASSERT(state() == InferiorStopped, qDebug() << state()); + QTC_ASSERT(state() == InferiorStopOk, qDebug() << state()); setTokenBarrier(); - setState(InferiorRunningRequested); + notifyInferiorRunRequested(); showStatusMessage(tr("Step next requested..."), 5000); if (m_gdbAdapter->isTrkAdapter() && stackHandler()->stackSize() > 0) postCommand("sal next," + stackHandler()->topAddress().toLatin1()); @@ -1906,35 +1934,31 @@ void GdbEngine::executeNext() void GdbEngine::handleExecuteNext(const GdbResponse &response) { + QTC_ASSERT(state() == InferiorRunRequested, qDebug() << state()); if (response.resultClass == GdbResultRunning) { - // The "running" state is picked up in handleResponse() - QTC_ASSERT(state() == InferiorRunning, /**/); - } else { - if (state() == InferiorRunningRequested_Kill) { - setState(InferiorStopped); - shutdown(); - return; - } - QTC_ASSERT(state() == InferiorRunningRequested, /**/); - setState(InferiorStopped); - QByteArray msg = response.data.findChild("msg").data(); - if (msg.startsWith("Cannot find bounds of current function")) { - if (!m_commandsToRunOnTemporaryBreak.isEmpty()) - flushQueuedCommands(); + notifyInferiorRunOk(); + return; + } + QTC_ASSERT(state() == InferiorStopOk, qDebug() << state()); + QByteArray msg = response.data.findChild("msg").data(); + if (msg.startsWith("Cannot find bounds of current function")) { + if (!m_commandsToRunOnTemporaryBreak.isEmpty()) + flushQueuedCommands(); + notifyInferiorRunFailed(); + if (!isDying()) executeNextI(); // Fall back to instruction-wise stepping. - } else { - showMessageBox(QMessageBox::Critical, tr("Execution Error"), - tr("Cannot continue debugged process:\n") + QString::fromLocal8Bit(msg)); - shutdown(); - } + } else { + showMessageBox(QMessageBox::Critical, tr("Execution Error"), + tr("Cannot continue debugged process:\n") + QString::fromLocal8Bit(msg)); + notifyInferiorIll(); } } void GdbEngine::executeNextI() { - QTC_ASSERT(state() == InferiorStopped, qDebug() << state()); + QTC_ASSERT(state() == InferiorStopOk, qDebug() << state()); setTokenBarrier(); - setState(InferiorRunningRequested); + notifyInferiorRunRequested(); showStatusMessage(tr("Step next instruction requested..."), 5000); if (isReverseDebugging()) postCommand("reverse-nexti", RunRequest, CB(handleExecuteContinue)); @@ -1944,9 +1968,9 @@ void GdbEngine::executeNextI() void GdbEngine::executeRunToLine(const QString &fileName, int lineNumber) { - QTC_ASSERT(state() == InferiorStopped, qDebug() << state()); + QTC_ASSERT(state() == InferiorStopOk, qDebug() << state()); setTokenBarrier(); - setState(InferiorRunningRequested); + notifyInferiorRunRequested(); showStatusMessage(tr("Run to line %1 requested...").arg(lineNumber), 5000); #if 1 m_targetFrame.file = fileName; @@ -1966,18 +1990,18 @@ void GdbEngine::executeRunToLine(const QString &fileName, int lineNumber) void GdbEngine::executeRunToFunction(const QString &functionName) { - QTC_ASSERT(state() == InferiorStopped, qDebug() << state()); + QTC_ASSERT(state() == InferiorStopOk, qDebug() << state()); setTokenBarrier(); postCommand("-break-insert -t " + functionName.toLatin1()); + showStatusMessage(tr("Run to function %1 requested...").arg(functionName), 5000); + notifyInferiorRunRequested(); continueInferiorInternal(); - //setState(InferiorRunningRequested); //postCommand("-exec-continue", handleExecuteRunToFunction); - showStatusMessage(tr("Run to function %1 requested...").arg(functionName), 5000); } void GdbEngine::executeJumpToLine(const QString &fileName, int lineNumber) { - QTC_ASSERT(state() == InferiorStopped, qDebug() << state()); + QTC_ASSERT(state() == InferiorStopOk, qDebug() << state()); StackFrame frame; frame.file = fileName; frame.line = lineNumber; @@ -1985,7 +2009,7 @@ void GdbEngine::executeJumpToLine(const QString &fileName, int lineNumber) QByteArray loc = '"' + breakLocation(fileName).toLocal8Bit() + '"' + ':' + QByteArray::number(lineNumber); postCommand("tbreak " + loc); - setState(InferiorRunningRequested); + notifyInferiorRunRequested(); postCommand("jump " + loc, RunRequest, CB(handleExecuteJumpToLine)); // will produce something like // &"jump \"/home/apoenitz/dev/work/test1/test1.cpp\":242" @@ -1999,16 +2023,16 @@ void GdbEngine::executeJumpToLine(const QString &fileName, int lineNumber) #else gotoLocation(frame, true); setBreakpoint(fileName, lineNumber); - setState(InferiorRunningRequested); + notifyInferiorRunRequested(); postCommand("jump " + loc, RunRequest); #endif } void GdbEngine::executeReturn() { - QTC_ASSERT(state() == InferiorStopped, qDebug() << state()); + QTC_ASSERT(state() == InferiorStopOk, qDebug() << state()); setTokenBarrier(); - setState(InferiorRunningRequested); + notifyInferiorRunRequested(); showStatusMessage(tr("Immediate return from function requested..."), 5000); postCommand("-exec-finish", RunRequest, CB(handleExecuteReturn)); } @@ -2016,9 +2040,13 @@ void GdbEngine::executeReturn() void GdbEngine::handleExecuteReturn(const GdbResponse &response) { if (response.resultClass == GdbResultDone) { + notifyInferiorStopOk(); updateAll(); + return; } + notifyInferiorRunFailed(); } + /*! \fn void GdbEngine::setTokenBarrier() \brief Discard the results of all pending watch-updating commands. @@ -2453,11 +2481,11 @@ void GdbEngine::attemptBreakpointSynchronization() showMessage(_("ATTEMPT BREAKPOINT SYNC")); switch (state()) { - case InferiorSettingUp: - case InferiorRunningRequested: - case InferiorRunning: - case InferiorStopping: - case InferiorStopped: + case InferiorSetupRequested: + case InferiorRunRequested: + case InferiorRunOk: + case InferiorStopRequested: + case InferiorStopOk: break; default: //qDebug() << "attempted breakpoint sync in state" << state(); @@ -2468,7 +2496,7 @@ void GdbEngine::attemptBreakpointSynchronization() // For best results, we rely on an up-to-date fullname mapping. // The listing completion will retrigger us, so no futher action is needed. if (m_sourcesListOutdated && theDebuggerBoolSetting(UsePreciseBreakpoints)) { - if (state() == InferiorRunning) { + if (state() == InferiorRunOk) { // FIXME: this is a hack // The hack solves the problem that we want both commands // (reloadSourceFiles and reloadBreakList) to be executed @@ -2641,7 +2669,7 @@ void GdbEngine::requestModuleSymbols(const QString &moduleName) void GdbEngine::reloadModules() { - if (state() == InferiorRunning || state() == InferiorStopped) + if (state() == InferiorRunOk || state() == InferiorStopOk) reloadModulesInternal(); } @@ -2717,7 +2745,7 @@ void GdbEngine::invalidateSourcesList() void GdbEngine::reloadSourceFiles() { - if ((state() == InferiorRunning || state() == InferiorStopped) + if ((state() == InferiorRunOk || state() == InferiorStopOk) && !m_sourcesListUpdating) reloadSourceFilesInternal(); } @@ -2752,7 +2780,7 @@ void GdbEngine::selectThread(int index) void GdbEngine::handleStackSelectThread(const GdbResponse &) { - QTC_ASSERT(state() == InferiorUnrunnable || state() == InferiorStopped, /**/); + QTC_ASSERT(state() == InferiorUnrunnable || state() == InferiorStopOk, /**/); //qDebug("FIXME: StackHandler::handleOutput: SelectThread"); showStatusMessage(tr("Retrieving data for stack view..."), 3000); reloadRegisters(); @@ -2842,7 +2870,7 @@ void GdbEngine::handleStackListFrames(const GdbResponse &response) // Immediately leave bogus frames. if (targetFrame == -1 && isBogus) { setTokenBarrier(); - setState(InferiorRunningRequested); + notifyInferiorRunRequested(); postCommand("-exec-finish", RunRequest, CB(handleExecuteContinue)); showStatusMessage(tr("Jumping out of bogus frame..."), 1000); return; @@ -2890,7 +2918,7 @@ void GdbEngine::handleStackListFrames(const GdbResponse &response) void GdbEngine::activateFrame(int frameIndex) { resetLocation(); - if (state() != InferiorStopped && state() != InferiorUnrunnable) + if (state() != InferiorStopOk && state() != InferiorUnrunnable) return; StackHandler *handler = stackHandler(); @@ -3020,7 +3048,7 @@ void GdbEngine::activateSnapshot(int index) if (state() == InferiorUnrunnable) { // All is well. We are looking at another core file. - setState(EngineShuttingDown); + setState(EngineShutdownRequested); setState(DebuggerNotReady); activateSnapshot2(); } else if (state() != DebuggerNotReady) { @@ -3044,9 +3072,9 @@ void GdbEngine::activateSnapshot(int index) void GdbEngine::handleActivateSnapshot(const GdbResponse &response) { Q_UNUSED(response); - setState(InferiorShuttingDown); - setState(InferiorShutDown); - setState(EngineShuttingDown); + setState(InferiorShutdownRequested); + setState(InferiorShutdownOk); + setState(EngineShutdownRequested); setState(DebuggerNotReady); activateSnapshot2(); } @@ -3055,7 +3083,7 @@ void GdbEngine::activateSnapshot2() { // Otherwise the stack data might be stale. // See http://sourceware.org/bugzilla/show_bug.cgi?id=1124. - setState(EngineSettingUp); + setState(EngineSetupRequested); postCommand("set stack-cache off"); handleAdapterStarted(); } @@ -3072,7 +3100,7 @@ void GdbEngine::reloadRegisters() if (!plugin()->isRegisterViewVisible()) return; - if (state() != InferiorStopped && state() != InferiorUnrunnable) + if (state() != InferiorStopOk && state() != InferiorUnrunnable) return; if (!m_registerNamesListed) { postCommand("-data-list-register-names", CB(handleRegisterListNames)); @@ -3214,7 +3242,7 @@ bool GdbEngine::showToolTip() void GdbEngine::setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos) { - if (state() != InferiorStopped || !isCppEditor(editor)) { + if (state() != InferiorStopOk || !isCppEditor(editor)) { //qDebug() << "SUPPRESSING DEBUGGER TOOLTIP, INFERIOR NOT STOPPED/Non Cpp editor"; return; } @@ -4152,7 +4180,7 @@ bool GdbEngine::checkDebuggingHelpers() void GdbEngine::handleGdbError(QProcess::ProcessError error) { - showMessage(_("HANDLE GDB ERROR")); + showMessage(_("HANDLE GDB ERROR: ") + errorMessage(error)); switch (error) { case QProcess::Crashed: break; // will get a processExited() as well @@ -4161,8 +4189,8 @@ void GdbEngine::handleGdbError(QProcess::ProcessError error) case QProcess::WriteError: case QProcess::Timedout: default: - gdbProc()->kill(); - setState(EngineShuttingDown, true); + //gdbProc()->kill(); + //setState(EngineShutdownRequested, true); showMessageBox(QMessageBox::Critical, tr("Gdb I/O Error"), errorMessage(error)); break; @@ -4171,27 +4199,40 @@ void GdbEngine::handleGdbError(QProcess::ProcessError error) void GdbEngine::handleGdbFinished(int code, QProcess::ExitStatus type) { + //qDebug() << "GDB PROCESS FINISHED"; showMessage(_("GDB PROCESS FINISHED, status %1, code %2").arg(type).arg(code)); +/* if (!m_gdbAdapter) { showMessage(_("NO ADAPTER PRESENT")); - } else if (state() == EngineShuttingDown) { + } else if (state() == EngineShutdownRequested) { showMessage(_("GOING TO SHUT DOWN ADAPTER")); - m_gdbAdapter->shutdown(); + //m_gdbAdapter->shutdownEngine(); FIXME AAA } else if (state() != EngineSetupFailed) { + showStatusMessage(msg); + //m_gdbAdapter->shutdownEngine(); + } + initializeVariables(); +*/ + if (state() == EngineShutdownRequested) { + notifyEngineShutdownOk(); + } else if (state() == InferiorRunOk) { + // This could either be a real gdb crash or a quickly exited inferior + // in the terminal adapter. In this case the stub proc will die soon, + // too, so there's no need to act here. + showMessage(_("The gdb process exited somewhat unexpectedly.")); + notifyEngineSpontaneousShutdown(); + } else { QString msg = tr("The gdb process exited unexpectedly (%1).") .arg((type == QProcess::CrashExit) ? tr("crashed") : tr("code %1").arg(code)); showMessageBox(QMessageBox::Critical, tr("Unexpected Gdb Exit"), msg); - showStatusMessage(msg); - m_gdbAdapter->shutdown(); + notifyEngineSpontaneousShutdown(); } - initializeVariables(); - setState(DebuggerNotReady, true); } void GdbEngine::handleAdapterStartFailed(const QString &msg, const QString &settingsIdHint) { - setState(EngineSetupFailed); + QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state()); showMessage(_("ADAPTER START FAILED")); if (!msg.isEmpty()) { const QString title = tr("Adapter start failed"); @@ -4202,11 +4243,12 @@ void GdbEngine::handleAdapterStartFailed(const QString &msg, const QString &sett _(Debugger::Constants::DEBUGGER_SETTINGS_CATEGORY), settingsIdHint); } } - shutdown(); + notifyEngineSetupFailed(); } void GdbEngine::handleAdapterStarted() { + QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state()); if (m_progress) m_progress->setProgressValue(25); showMessage(_("ADAPTER SUCCESSFULLY STARTED")); @@ -4215,13 +4257,14 @@ void GdbEngine::handleAdapterStarted() void GdbEngine::setupInferior() { - QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state()); - showStatusMessage(tr("Starting inferior...")); + QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); + showStatusMessage(tr("Setting up inferior...")); m_gdbAdapter->setupInferior(); } void GdbEngine::handleInferiorPrepared() { + QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); const QByteArray qtInstallPath = startParameters().qtInstallPath.toLocal8Bit(); if (!qtInstallPath.isEmpty()) { QByteArray qtBuildPath; @@ -4251,17 +4294,19 @@ void GdbEngine::handleInferiorPrepared() void GdbEngine::finishInferiorSetup() { + QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); showMessage(_("BREAKPOINTS SET, CONTINUING INFERIOR STARTUP")); notifyInferiorSetupOk(); } void GdbEngine::runEngine() { + QTC_ASSERT(state() == EngineRunRequested, qDebug() << state()); showMessage(_("RUN ENGINE")); - m_gdbAdapter->runAdapter(); + m_gdbAdapter->runEngine(); } -void GdbEngine::handleInferiorSetupFailed(const QString &msg) +void GdbEngine::notifyInferiorSetupFailed(const QString &msg) { showStatusMessage(tr("Failed to start application: ") + msg); if (state() == EngineSetupFailed) { @@ -4270,7 +4315,7 @@ void GdbEngine::handleInferiorSetupFailed(const QString &msg) } showMessage(_("INFERIOR START FAILED")); showMessageBox(QMessageBox::Critical, tr("Failed to start application"), msg); - notifyInferiorSetupFailed(); + DebuggerEngine::notifyInferiorSetupFailed(); } void GdbEngine::handleAdapterCrashed(const QString &msg) diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index 25ccbd8c62..abb906db35 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -110,10 +110,10 @@ private: ////////// General Interface ////////// virtual void runEngine(); virtual unsigned debuggerCapabilities() const; - virtual void exitDebugger(); virtual void quitDebugger(); virtual void detachDebugger(); - virtual void shutdown(); + virtual void shutdownEngine(); + virtual void shutdownInferior(); virtual void executeDebuggerCommand(const QString &command); virtual QString qtNamespace() const { return m_dumperHelper.qtNamespace(); } @@ -136,6 +136,7 @@ private: ////////// Gdb Process Management ////////// void handleGdbExit(const GdbResponse &response); void handleAdapterStarted(); + void defaultInferiorShutdown(const char *cmd); // Something went wrong with the adapter *before* adapterStarted() was emitted. // Make sure to clean up everything before emitting this signal. @@ -149,7 +150,10 @@ private: ////////// Gdb Process Management ////////// void finishInferiorSetup(); // The adapter is still running just fine, but it failed to acquire a debuggee. - void handleInferiorSetupFailed(const QString &msg); + void notifyInferiorSetupFailed(const QString &msg); + + void notifyAdapterShutdownOk(); + void notifyAdapterShutdownFailed(); // Something went wrong with the adapter *after* adapterStarted() was emitted. // Make sure to clean up everything before emitting this signal. @@ -530,6 +534,7 @@ private: ////////// View & Data Stuff ////////// int buttons = 0); QMainWindow *mainWindow() const; AbstractGdbProcess *gdbProc() const; + void showExecutionError(const QString &message); static QString m_toolTipExpression; static QPoint m_toolTipPos; diff --git a/src/plugins/debugger/gdb/localplaingdbadapter.cpp b/src/plugins/debugger/gdb/localplaingdbadapter.cpp index bd5099a4b9..1e3994b019 100644 --- a/src/plugins/debugger/gdb/localplaingdbadapter.cpp +++ b/src/plugins/debugger/gdb/localplaingdbadapter.cpp @@ -68,7 +68,7 @@ AbstractGdbAdapter::DumperHandling LocalPlainGdbAdapter::dumperHandling() const void LocalPlainGdbAdapter::startAdapter() { - QTC_ASSERT(state() == EngineSettingUp, qDebug() << state()); + QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state()); showMessage(_("TRYING TO START ADAPTER")); QStringList gdbArgs; @@ -94,6 +94,28 @@ void LocalPlainGdbAdapter::startAdapter() m_engine->handleAdapterStarted(); } +void LocalPlainGdbAdapter::setupInferior() +{ + AbstractPlainGdbAdapter::setupInferior(); +} + +void LocalPlainGdbAdapter::runEngine() +{ + AbstractPlainGdbAdapter::runEngine(); +} + +void LocalPlainGdbAdapter::shutdownInferior() +{ + m_engine->defaultInferiorShutdown("kill"); +} + +void LocalPlainGdbAdapter::shutdownAdapter() +{ + showMessage(_("PLAIN ADAPTER SHUTDOWN %1").arg(state())); + m_outputCollector.shutdown(); + m_engine->notifyAdapterShutdownOk(); +} + void LocalPlainGdbAdapter::checkForReleaseBuild() { // Quick check for a "release" build @@ -128,14 +150,10 @@ void LocalPlainGdbAdapter::interruptInferior() return; } - if (!interruptProcess(attachedPID)) + if (!interruptProcess(attachedPID)) { showMessage(_("CANNOT INTERRUPT %1").arg(attachedPID)); -} - -void LocalPlainGdbAdapter::shutdown() -{ - showMessage(_("PLAIN ADAPTER SHUTDOWN %1").arg(state())); - m_outputCollector.shutdown(); + m_engine->notifyInferiorStopFailed(); + } } QByteArray LocalPlainGdbAdapter::execFilePath() const diff --git a/src/plugins/debugger/gdb/localplaingdbadapter.h b/src/plugins/debugger/gdb/localplaingdbadapter.h index 12a0bc8211..adee27de4b 100644 --- a/src/plugins/debugger/gdb/localplaingdbadapter.h +++ b/src/plugins/debugger/gdb/localplaingdbadapter.h @@ -52,14 +52,17 @@ class LocalPlainGdbAdapter : public AbstractPlainGdbAdapter public: LocalPlainGdbAdapter(GdbEngine *engine, QObject *parent = 0); - virtual DumperHandling dumperHandling() const; - +private: void startAdapter(); + void setupInferior(); + void runEngine(); void interruptInferior(); - void shutdown(); + void shutdownInferior(); + void shutdownAdapter(); + + DumperHandling dumperHandling() const; AbstractGdbProcess *gdbProc() { return &m_gdbProc; } -private: virtual QByteArray execFilePath() const; virtual bool infoTargetNecessary() const; virtual QByteArray toLocalEncoding(const QString &s) const; diff --git a/src/plugins/debugger/gdb/pythongdbengine.cpp b/src/plugins/debugger/gdb/pythongdbengine.cpp index 8126c95ba5..74679e9f21 100644 --- a/src/plugins/debugger/gdb/pythongdbengine.cpp +++ b/src/plugins/debugger/gdb/pythongdbengine.cpp @@ -196,7 +196,7 @@ void GdbEngine::updateAllPython() { PRECONDITION; //PENDING_DEBUG("UPDATING ALL\n"); - QTC_ASSERT(state() == InferiorUnrunnable || state() == InferiorStopped, /**/); + QTC_ASSERT(state() == InferiorUnrunnable || state() == InferiorStopOk, /**/); reloadModulesInternal(); postCommand("-stack-list-frames", CB(handleStackListFrames), QVariant::fromValue<StackCookie>(StackCookie(false, true))); diff --git a/src/plugins/debugger/gdb/remotegdbserveradapter.cpp b/src/plugins/debugger/gdb/remotegdbserveradapter.cpp index d674c701b5..6e9bc9b869 100644 --- a/src/plugins/debugger/gdb/remotegdbserveradapter.cpp +++ b/src/plugins/debugger/gdb/remotegdbserveradapter.cpp @@ -84,7 +84,7 @@ AbstractGdbAdapter::DumperHandling RemoteGdbServerAdapter::dumperHandling() cons void RemoteGdbServerAdapter::startAdapter() { - QTC_ASSERT(state() == EngineSettingUp, qDebug() << state()); + QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state()); showMessage(_("TRYING TO START ADAPTER")); // FIXME: make asynchroneous @@ -156,7 +156,7 @@ void RemoteGdbServerAdapter::readUploadStandardError() void RemoteGdbServerAdapter::setupInferior() { - QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state()); + QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); m_engine->postCommand("set architecture " + startParameters().remoteArchitecture.toLatin1()); @@ -181,14 +181,14 @@ void RemoteGdbServerAdapter::setupInferior() void RemoteGdbServerAdapter::handleSetTargetAsync(const GdbResponse &response) { - QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state()); + QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); if (response.resultClass == GdbResultError) qDebug() << "Adapter too old: does not support asynchronous mode."; } void RemoteGdbServerAdapter::handleFileExecAndSymbols(const GdbResponse &response) { - QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state()); + QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); if (response.resultClass == GdbResultDone) { //m_breakHandler->clearBreakMarkers(); @@ -202,15 +202,15 @@ void RemoteGdbServerAdapter::handleFileExecAndSymbols(const GdbResponse &respons } else { QString msg = tr("Starting remote executable failed:\n"); msg += QString::fromLocal8Bit(response.data.findChild("msg").data()); - m_engine->handleInferiorSetupFailed(msg); + m_engine->notifyInferiorSetupFailed(msg); } } void RemoteGdbServerAdapter::handleTargetRemote(const GdbResponse &record) { - QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state()); + QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); if (record.resultClass == GdbResultDone) { - setState(InferiorStopped); + setState(InferiorStopOk); // gdb server will stop the remote application itself. showMessage(_("INFERIOR STARTED")); showMessage(msgAttachedToStoppedInferior(), StatusBar); @@ -219,11 +219,11 @@ void RemoteGdbServerAdapter::handleTargetRemote(const GdbResponse &record) // 16^error,msg="hd:5555: Connection timed out." QString msg = msgConnectRemoteServerFailed( QString::fromLocal8Bit(record.data.findChild("msg").data())); - m_engine->handleInferiorSetupFailed(msg); + m_engine->notifyInferiorSetupFailed(msg); } } -void RemoteGdbServerAdapter::runAdapter() +void RemoteGdbServerAdapter::runEngine() { m_engine->continueInferiorInternal(); } @@ -235,9 +235,14 @@ void RemoteGdbServerAdapter::interruptInferior() m_engine->postCommand("-exec-interrupt", GdbEngine::Immediate); } -void RemoteGdbServerAdapter::shutdown() +void RemoteGdbServerAdapter::shutdownInferior() { - // FIXME: cleanup missing + m_engine->defaultInferiorShutdown("kill"); +} + +void RemoteGdbServerAdapter::shutdownAdapter() +{ + m_engine->notifyAdapterShutdownOk(); } } // namespace Internal diff --git a/src/plugins/debugger/gdb/remotegdbserveradapter.h b/src/plugins/debugger/gdb/remotegdbserveradapter.h index 3a9e79d0f8..7d8ed8f38d 100644 --- a/src/plugins/debugger/gdb/remotegdbserveradapter.h +++ b/src/plugins/debugger/gdb/remotegdbserveradapter.h @@ -50,16 +50,18 @@ class RemoteGdbServerAdapter : public AbstractGdbAdapter public: RemoteGdbServerAdapter(GdbEngine *engine, int toolChainType, QObject *parent = 0); - virtual DumperHandling dumperHandling() const; +private: + DumperHandling dumperHandling() const; void startAdapter(); void setupInferior(); - void runAdapter(); + void runEngine(); void interruptInferior(); - void shutdown(); + void shutdownInferior(); + void shutdownAdapter(); + AbstractGdbProcess *gdbProc() { return &m_gdbProc; } -private: Q_SLOT void readUploadStandardOutput(); Q_SLOT void readUploadStandardError(); Q_SLOT void uploadProcError(QProcess::ProcessError error); diff --git a/src/plugins/debugger/gdb/remoteplaingdbadapter.cpp b/src/plugins/debugger/gdb/remoteplaingdbadapter.cpp index 662044b702..5121504797 100644 --- a/src/plugins/debugger/gdb/remoteplaingdbadapter.cpp +++ b/src/plugins/debugger/gdb/remoteplaingdbadapter.cpp @@ -45,7 +45,7 @@ RemotePlainGdbAdapter::RemotePlainGdbAdapter(GdbEngine *engine, QObject *parent) void RemotePlainGdbAdapter::startAdapter() { - QTC_ASSERT(state() == EngineSettingUp, qDebug() << state()); + QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state()); showMessage(QLatin1String("TRYING TO START ADAPTER")); if (!startParameters().workingDirectory.isEmpty()) @@ -87,5 +87,15 @@ void RemotePlainGdbAdapter::handleApplicationOutput(const QByteArray &output) showMessage(QString::fromUtf8(output), AppOutput); } +void RemotePlainGdbAdapter::shutdownInferior() +{ + m_engine->defaultInferiorShutdown("kill"); +} + +void RemotePlainGdbAdapter::shutdownAdapter() +{ + m_engine->notifyAdapterShutdownOk(); +} + } // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/gdb/remoteplaingdbadapter.h b/src/plugins/debugger/gdb/remoteplaingdbadapter.h index a9e089bec7..f6a6bf32cd 100644 --- a/src/plugins/debugger/gdb/remoteplaingdbadapter.h +++ b/src/plugins/debugger/gdb/remoteplaingdbadapter.h @@ -39,16 +39,19 @@ namespace Internal { class RemotePlainGdbAdapter : public AbstractPlainGdbAdapter { Q_OBJECT - friend class RemoteGdbProcess; + public: + friend class RemoteGdbProcess; RemotePlainGdbAdapter(GdbEngine *engine, QObject *parent = 0); - virtual void startAdapter(); - virtual void interruptInferior(); - virtual AbstractGdbProcess *gdbProc() { return &m_gdbProc; } - virtual DumperHandling dumperHandling() const { return DumperLoadedByGdbPreload; } - private: + void startAdapter(); + void interruptInferior(); + void shutdownInferior(); + void shutdownAdapter(); + AbstractGdbProcess *gdbProc() { return &m_gdbProc; } + DumperHandling dumperHandling() const { return DumperLoadedByGdbPreload; } + virtual QByteArray execFilePath() const; virtual bool infoTargetNecessary() const; virtual QByteArray toLocalEncoding(const QString &s) const; diff --git a/src/plugins/debugger/gdb/tcftrkgdbadapter.cpp b/src/plugins/debugger/gdb/tcftrkgdbadapter.cpp index 993608966c..c4863ebffa 100644 --- a/src/plugins/debugger/gdb/tcftrkgdbadapter.cpp +++ b/src/plugins/debugger/gdb/tcftrkgdbadapter.cpp @@ -252,16 +252,15 @@ void TcfTrkGdbAdapter::handleTcfTrkRunControlModuleLoadContextSuspendedEvent(con void TcfTrkGdbAdapter::handleTargetRemote(const GdbResponse &record) { - QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state()); + QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); if (record.resultClass == GdbResultDone) { - setState(InferiorStopped); m_engine->handleInferiorPrepared(); if (debug) qDebug() << "handleTargetRemote" << m_session.toString(); } else { QString msg = tr("Connecting to TRK server adapter failed:\n") + QString::fromLocal8Bit(record.data.findChild("msg").data()); - m_engine->handleInferiorSetupFailed(msg); + m_engine->notifyInferiorSetupFailed(msg); } } @@ -337,7 +336,7 @@ void TcfTrkGdbAdapter::startGdb() void TcfTrkGdbAdapter::tcftrkDeviceError(const QString &errorString) { logMessage(errorString); - if (state() == EngineSettingUp) { + if (state() == EngineSetupRequested) { m_engine->handleAdapterStartFailed(errorString, QString()); } else { m_engine->handleAdapterCrashed(errorString); @@ -956,7 +955,7 @@ void TcfTrkGdbAdapter::startAdapter() // Unixish gdbs accept only forward slashes m_symbolFile.replace(QLatin1Char('\\'), QLatin1Char('/')); // Start - QTC_ASSERT(state() == EngineSettingUp, qDebug() << state()); + QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state()); showMessage(_("TRYING TO START ADAPTER")); logMessage(QLatin1String("### Starting TcfTrkGdbAdapter")); @@ -985,7 +984,7 @@ void TcfTrkGdbAdapter::startAdapter() void TcfTrkGdbAdapter::setupInferior() { - QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state()); + QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); m_trkDevice->sendProcessStartCommand(TcfTrkCallback(this, &TcfTrkGdbAdapter::handleCreateProcess), m_remoteExecutable, m_uid, m_remoteArguments, QString(), true); @@ -1011,7 +1010,7 @@ void TcfTrkGdbAdapter::handleCreateProcess(const TcfTrkCommandResult &result) if (!result) { const QString errorMessage = result.errorString(); logMessage(QString::fromLatin1("Failed to start process: %1").arg(errorMessage), LogError); - m_engine->handleInferiorSetupFailed(result.errorString()); + m_engine->notifyInferiorSetupFailed(result.errorString()); return; } QTC_ASSERT(!result.values.isEmpty(), return); @@ -1029,8 +1028,10 @@ void TcfTrkGdbAdapter::handleCreateProcess(const TcfTrkCommandResult &result) m_session.dataseg = 0; } -void TcfTrkGdbAdapter::runAdapter() +void TcfTrkGdbAdapter::runEngine() { + m_engine->notifyInferiorStopOk(); + // Trigger the initial "continue" manually. m_engine->continueInferiorInternal(); } @@ -1086,9 +1087,15 @@ void TcfTrkGdbAdapter::cleanup() } //!m_trkIODevice.isNull() } -void TcfTrkGdbAdapter::shutdown() +void TcfTrkGdbAdapter::shutdownInferior() +{ + m_engine->defaultInferiorShutdown("kill"); +} + +void TcfTrkGdbAdapter::shutdownAdapter() { cleanup(); + m_engine->notifyAdapterShutdownOk(); } void TcfTrkGdbAdapter::trkReloadRegisters() diff --git a/src/plugins/debugger/gdb/tcftrkgdbadapter.h b/src/plugins/debugger/gdb/tcftrkgdbadapter.h index 280f755f1c..675faadfc0 100644 --- a/src/plugins/debugger/gdb/tcftrkgdbadapter.h +++ b/src/plugins/debugger/gdb/tcftrkgdbadapter.h @@ -105,9 +105,10 @@ public: private: void startAdapter(); void setupInferior(); - void runAdapter(); + void runEngine(); void interruptInferior(); - void shutdown(); + void shutdownInferior(); + void shutdownAdapter(); void handleWriteRegister(const tcftrk::TcfTrkCommandResult &result); void reportRegisters(); void handleReadRegisters(const tcftrk::TcfTrkCommandResult &result); diff --git a/src/plugins/debugger/gdb/termgdbadapter.cpp b/src/plugins/debugger/gdb/termgdbadapter.cpp index 89909a728f..ff573722c5 100644 --- a/src/plugins/debugger/gdb/termgdbadapter.cpp +++ b/src/plugins/debugger/gdb/termgdbadapter.cpp @@ -81,7 +81,7 @@ AbstractGdbAdapter::DumperHandling TermGdbAdapter::dumperHandling() const void TermGdbAdapter::startAdapter() { - QTC_ASSERT(state() == EngineSettingUp, qDebug() << state()); + QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state()); showMessage(_("TRYING TO START ADAPTER")); // Currently, adapters are not re-used @@ -111,13 +111,13 @@ void TermGdbAdapter::startAdapter() void TermGdbAdapter::handleInferiorSetupOk() { - QTC_ASSERT(state() == EngineSettingUp, qDebug() << state()); + QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state()); m_engine->handleAdapterStarted(); } void TermGdbAdapter::setupInferior() { - QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state()); + QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); const qint64 attachedPID = m_stubProc.applicationPID(); m_engine->notifyInferiorPid(attachedPID); m_engine->postCommand("attach " + QByteArray::number(attachedPID), @@ -126,9 +126,8 @@ void TermGdbAdapter::setupInferior() void TermGdbAdapter::handleStubAttached(const GdbResponse &response) { - QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state()); + QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); if (response.resultClass == GdbResultDone) { - setState(InferiorStopped); showMessage(_("INFERIOR ATTACHED")); m_engine->handleInferiorPrepared(); #ifdef Q_OS_LINUX @@ -136,12 +135,15 @@ void TermGdbAdapter::handleStubAttached(const GdbResponse &response) #endif } else if (response.resultClass == GdbResultError) { QString msg = QString::fromLocal8Bit(response.data.findChild("msg").data()); - m_engine->handleInferiorSetupFailed(msg); + m_engine->notifyInferiorSetupFailed(msg); } } -void TermGdbAdapter::runAdapter() +void TermGdbAdapter::runEngine() { + QTC_ASSERT(state() == EngineRunRequested, qDebug() << state()); + m_engine->notifyEngineRunAndInferiorStopOk(); + m_engine->notifyInferiorRunRequested(); m_engine->continueInferiorInternal(); } @@ -171,10 +173,23 @@ void TermGdbAdapter::stubMessage(const QString &msg, bool) void TermGdbAdapter::stubExited() { + if (state() == EngineShutdownRequested || state() == DebuggerFinished) { + showMessage(_("STUB EXITED EXPECTEDLY")); + return; + } showMessage(_("STUB EXITED")); - if (state() != EngineSettingUp // From previous instance - && state() != EngineShuttingDown && state() != DebuggerNotReady) - m_engine->handleAdapterCrashed(QString()); + qDebug() << "STUB EXITED IN STATE: " << state(); + m_engine->notifyEngineIll(); +} + +void TermGdbAdapter::shutdownInferior() +{ + m_engine->defaultInferiorShutdown("kill"); +} + +void TermGdbAdapter::shutdownAdapter() +{ + m_engine->notifyAdapterShutdownOk(); } } // namespace Internal diff --git a/src/plugins/debugger/gdb/termgdbadapter.h b/src/plugins/debugger/gdb/termgdbadapter.h index 448dda4c54..e0f483d0f9 100644 --- a/src/plugins/debugger/gdb/termgdbadapter.h +++ b/src/plugins/debugger/gdb/termgdbadapter.h @@ -53,15 +53,18 @@ public: TermGdbAdapter(GdbEngine *engine, QObject *parent = 0); ~TermGdbAdapter(); - virtual DumperHandling dumperHandling() const; +private: + DumperHandling dumperHandling() const; void startAdapter(); void setupInferior(); - void runAdapter(); + void runEngine(); void interruptInferior(); + void shutdownInferior(); + void shutdownAdapter(); + AbstractGdbProcess *gdbProc() { return &m_gdbProc; } -private: void handleStubAttached(const GdbResponse &response); #ifdef Q_OS_LINUX void handleEntryPoint(const GdbResponse &response); diff --git a/src/plugins/debugger/gdb/trkgdbadapter.cpp b/src/plugins/debugger/gdb/trkgdbadapter.cpp index dc4cb7feb9..e865b975e3 100644 --- a/src/plugins/debugger/gdb/trkgdbadapter.cpp +++ b/src/plugins/debugger/gdb/trkgdbadapter.cpp @@ -254,7 +254,7 @@ void TrkGdbAdapter::emitDelayedInferiorSetupFailed(const QString &msg) void TrkGdbAdapter::slotEmitDelayedInferiorSetupFailed() { - m_engine->handleInferiorSetupFailed(m_adapterFailMessage); + m_engine->notifyInferiorSetupFailed(m_adapterFailMessage); } @@ -1501,7 +1501,7 @@ void TrkGdbAdapter::startAdapter() // Unixish gdbs accept only forward slashes m_symbolFile.replace(QLatin1Char('\\'), QLatin1Char('/')); // Start - QTC_ASSERT(state() == EngineSettingUp, qDebug() << state()); + QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state()); showMessage(_("TRYING TO START ADAPTER")); logMessage(QLatin1String("### Starting TrkGdbAdapter")); @@ -1545,14 +1545,14 @@ void TrkGdbAdapter::startAdapter() void TrkGdbAdapter::setupInferior() { - QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state()); + QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); sendTrkMessage(0x40, TrkCB(handleCreateProcess), trk::Launcher::startProcessMessage(m_remoteExecutable, m_remoteArguments)); } void TrkGdbAdapter::handleCreateProcess(const TrkResult &result) { - QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state()); + QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); // 40 00 00] //logMessage(" RESULT: " + result.toString()); // [80 08 00 00 00 01 B5 00 00 01 B6 78 67 40 00 00 40 00 00] @@ -1602,18 +1602,18 @@ void TrkGdbAdapter::handleCreateProcess(const TrkResult &result) void TrkGdbAdapter::handleTargetRemote(const GdbResponse &record) { - QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state()); + QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); if (record.resultClass == GdbResultDone) { - setState(InferiorStopped); + setState(InferiorStopOk); m_engine->handleInferiorPrepared(); } else { QString msg = tr("Connecting to TRK server adapter failed:\n") + QString::fromLocal8Bit(record.data.findChild("msg").data()); - m_engine->handleInferiorSetupFailed(msg); + m_engine->notifyInferiorSetupFailed(msg); } } -void TrkGdbAdapter::runAdapter() +void TrkGdbAdapter::runEngine() { m_engine->continueInferiorInternal(); } @@ -1856,7 +1856,12 @@ void TrkGdbAdapter::cleanup() m_gdbServer = 0; } -void TrkGdbAdapter::shutdown() +void TrkGdbAdapter::shutdownInferior() +{ + m_engine->defaultInferiorShutdown("kill"); +} + +void TrkGdbAdapter::shutdownAdapter() { cleanup(); } diff --git a/src/plugins/debugger/gdb/trkgdbadapter.h b/src/plugins/debugger/gdb/trkgdbadapter.h index ee54693502..1e7873815e 100644 --- a/src/plugins/debugger/gdb/trkgdbadapter.h +++ b/src/plugins/debugger/gdb/trkgdbadapter.h @@ -113,9 +113,10 @@ private: void startAdapter(); bool initializeDevice(const QString &remoteChannel, QString *errorMessage); void setupInferior(); - void runAdapter(); + void runEngine(); void interruptInferior(); - void shutdown(); + void shutdownInferior(); + void shutdownAdapter(); AbstractGdbProcess *gdbProc() { return &m_gdbProc; } void cleanup(); diff --git a/src/plugins/debugger/pdb/pdbengine.cpp b/src/plugins/debugger/pdb/pdbengine.cpp index 06ecc90297..6e660ec650 100644 --- a/src/plugins/debugger/pdb/pdbengine.cpp +++ b/src/plugins/debugger/pdb/pdbengine.cpp @@ -118,29 +118,26 @@ void PdbEngine::postCommand(const QByteArray &command, m_pdbProc.write(cmd.command + "\n"); } -void PdbEngine::shutdown() +void PdbEngine::shutdownInferior() { - exitDebugger(); + QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << state()); + notifyInferiorShutdownOk(); } -void PdbEngine::exitDebugger() +void PdbEngine::shutdownEngine() { - if (state() == DebuggerNotReady) - return; - SDEBUG("PdbEngine::exitDebugger()"); + QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state()); + SDEBUG("PdbEngine::shutdownEngine()"); m_pdbProc.kill(); //if (m_scriptEngine->isEvaluating()) // m_scriptEngine->abortEvaluation(); - setState(InferiorShuttingDown); - setState(InferiorShutDown); - setState(EngineShuttingDown); //m_scriptEngine->setAgent(0); - setState(DebuggerNotReady); + notifyEngineShutdownOk(); } void PdbEngine::setupEngine() { - QTC_ASSERT(state() == EngineSettingUp, qDebug() << state()); + QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state()); m_scriptFileName = QFileInfo(startParameters().executable).absoluteFilePath(); QFile scriptFile(m_scriptFileName); @@ -187,7 +184,6 @@ void PdbEngine::setupEngine() const QString title = tr("Adapter start failed"); Core::ICore::instance()->showWarningWithOptions(title, msg); } - shutdown(); notifyEngineSetupFailed(); return; } @@ -196,7 +192,7 @@ void PdbEngine::setupEngine() void PdbEngine::setupInferior() { - QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state()); + QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); attemptBreakpointSynchronization(); showMessage(_("PDB STARTED, INITIALIZING IT")); @@ -215,54 +211,54 @@ void PdbEngine::runEngine() void PdbEngine::interruptInferior() { - setState(InferiorStopped); + setState(InferiorStopOk); } void PdbEngine::executeStep() { resetLocation(); - setState(InferiorRunningRequested); - setState(InferiorRunning); + setState(InferiorRunRequested); + setState(InferiorRunOk); postCommand("step", CB(handleUpdateAll)); } void PdbEngine::executeStepI() { resetLocation(); - setState(InferiorRunningRequested); - setState(InferiorRunning); + setState(InferiorRunRequested); + setState(InferiorRunOk); postCommand("step", CB(handleUpdateAll)); } void PdbEngine::executeStepOut() { resetLocation(); - setState(InferiorRunningRequested); - setState(InferiorRunning); + setState(InferiorRunRequested); + setState(InferiorRunOk); postCommand("finish", CB(handleUpdateAll)); } void PdbEngine::executeNext() { resetLocation(); - setState(InferiorRunningRequested); - setState(InferiorRunning); + setState(InferiorRunRequested); + setState(InferiorRunOk); postCommand("next", CB(handleUpdateAll)); } void PdbEngine::executeNextI() { resetLocation(); - setState(InferiorRunningRequested); - setState(InferiorRunning); + setState(InferiorRunRequested); + setState(InferiorRunOk); postCommand("next", CB(handleUpdateAll)); } void PdbEngine::continueInferior() { resetLocation(); - setState(InferiorRunningRequested); - setState(InferiorRunning); + setState(InferiorRunRequested); + setState(InferiorRunOk); // Callback will be triggered e.g. when breakpoint is hit. postCommand("continue", CB(handleUpdateAll)); } @@ -290,7 +286,7 @@ void PdbEngine::executeJumpToLine(const QString &fileName, int lineNumber) void PdbEngine::activateFrame(int frameIndex) { resetLocation(); - if (state() != InferiorStopped && state() != InferiorUnrunnable) + if (state() != InferiorStopOk && state() != InferiorUnrunnable) return; StackHandler *handler = stackHandler(); @@ -460,7 +456,7 @@ void PdbEngine::setToolTipExpression(const QPoint &mousePos, Q_UNUSED(editor) Q_UNUSED(cursorPos) - if (state() != InferiorStopped) { + if (state() != InferiorStopOk) { //SDEBUG("SUPPRESSING DEBUGGER TOOLTIP, INFERIOR NOT STOPPED"); return; } @@ -516,7 +512,7 @@ void PdbEngine::setToolTipExpression(const QPoint &mousePos, } #if 0 - //if (status() != InferiorStopped) + //if (status() != InferiorStopOk) // return; // FIXME: 'exp' can contain illegal characters @@ -566,7 +562,7 @@ void PdbEngine::handlePdbError(QProcess::ProcessError error) case QProcess::Timedout: default: m_pdbProc.kill(); - setState(EngineShuttingDown, true); + setState(EngineShutdownRequested, true); plugin()->showMessageBox(QMessageBox::Critical, tr("Pdb I/O Error"), errorMessage(error)); break; @@ -665,8 +661,8 @@ void PdbEngine::handleResponse(const QByteArray &response0) frame.line = lineNumber; if (frame.line > 0 && QFileInfo(frame.file).exists()) { gotoLocation(frame, true); - setState(InferiorStopping); - setState(InferiorStopped); + setState(InferiorStopRequested); + setState(InferiorStopOk); return; } } @@ -682,8 +678,8 @@ void PdbEngine::handleFirstCommand(const PdbResponse &response) void PdbEngine::handleUpdateAll(const PdbResponse &response) { Q_UNUSED(response); - setState(InferiorStopping); - setState(InferiorStopped); + setState(InferiorStopRequested); + setState(InferiorStopOk); updateAll(); } diff --git a/src/plugins/debugger/pdb/pdbengine.h b/src/plugins/debugger/pdb/pdbengine.h index 199e96c76c..d6778b89dc 100644 --- a/src/plugins/debugger/pdb/pdbengine.h +++ b/src/plugins/debugger/pdb/pdbengine.h @@ -69,15 +69,14 @@ private: void executeStepI(); void executeNextI(); - void shutdown(); - void setToolTipExpression(const QPoint &mousePos, - TextEditor::ITextEditor *editor, int cursorPos); - void setupEngine(); void setupInferior(); void runEngine(); + void shutdownInferior(); + void shutdownEngine(); - void exitDebugger(); + void setToolTipExpression(const QPoint &mousePos, + TextEditor::ITextEditor *editor, int cursorPos); void continueInferior(); void interruptInferior(); @@ -92,7 +91,7 @@ private: void attemptBreakpointSynchronization(); void assignValueInDebugger(const QString &expr, const QString &value); - void executeDebuggerCommand(const QString & command); + void executeDebuggerCommand(const QString &command); void loadSymbols(const QString &moduleName); void loadAllSymbols(); diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp index f3d9ac68f6..04da9d3b5a 100644 --- a/src/plugins/debugger/qml/qmlengine.cpp +++ b/src/plugins/debugger/qml/qmlengine.cpp @@ -207,18 +207,31 @@ void QmlEngine::executeDebuggerCommand(const QString &command) //enqueueCommand(tcf); } -void QmlEngine::shutdown() +void QmlEngine::setupInferior() { - exitDebugger(); + QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); + attemptBreakpointSynchronization(); + notifyInferiorSetupOk(); +} - //m_objectTreeWidget->saveSettings(m_settings); - //m_propertiesWidget->saveSettings(m_settings); - //m_settings.saveSettings(Core::ICore::instance()->settings()); +void QmlEngine::runEngine() +{ + QTC_ASSERT(state() == EngineRunRequested, qDebug() << state()); + //notifyEngineRunOk(); } -void QmlEngine::exitDebugger() +void QmlEngine::shutdownInferior() { - SDEBUG("QmlEngine::exitDebugger()"); + QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << state()); + notifyInferiorShutdownOk(); +} + +void QmlEngine::shutdownEngine() +{ + QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state()); + //m_objectTreeWidget->saveSettings(m_settings); + //m_propertiesWidget->saveSettings(m_settings); + //m_settings.saveSettings(Core::ICore::instance()->settings()); } const int serverPort = 3768; @@ -226,7 +239,7 @@ const int serverPort = 3768; void QmlEngine::setupEngine() { #if 0 - QTC_ASSERT(state() == EngineStarting, qDebug() << state()); + QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state()); const DebuggerStartParameters &sp = startParameters(); const int pos = sp.remoteChannel.indexOf(QLatin1Char(':')); const QString host = sp.remoteChannel.left(pos); @@ -302,8 +315,8 @@ void QmlEngine::setupConnection() notifyEngineSetupOk(); qDebug() << "CONNECTION SUCCESSFUL"; - setState(InferiorRunningRequested); - setState(InferiorRunning); + setState(InferiorRunRequested); + setState(InferiorRunOk); // reloadEngines(); @@ -316,8 +329,8 @@ void QmlEngine::continueInferior() QDataStream rs(&reply, QIODevice::WriteOnly); rs << QByteArray("CONTINUE"); sendMessage(reply); - setState(InferiorRunningRequested); - setState(InferiorRunning); + setState(InferiorRunRequested); + setState(InferiorRunOk); } void QmlEngine::interruptInferior() @@ -336,8 +349,8 @@ void QmlEngine::executeStep() QDataStream rs(&reply, QIODevice::WriteOnly); rs << QByteArray("STEPINTO"); sendMessage(reply); - setState(InferiorRunningRequested); - setState(InferiorRunning); + setState(InferiorRunRequested); + setState(InferiorRunOk); } void QmlEngine::executeStepI() @@ -347,8 +360,8 @@ void QmlEngine::executeStepI() QDataStream rs(&reply, QIODevice::WriteOnly); rs << QByteArray("STEPINTO"); sendMessage(reply); - setState(InferiorRunningRequested); - setState(InferiorRunning); + setState(InferiorRunRequested); + setState(InferiorRunOk); } void QmlEngine::executeStepOut() @@ -358,8 +371,8 @@ void QmlEngine::executeStepOut() QDataStream rs(&reply, QIODevice::WriteOnly); rs << QByteArray("STEPOUT"); sendMessage(reply); - setState(InferiorRunningRequested); - setState(InferiorRunning); + setState(InferiorRunRequested); + setState(InferiorRunOk); } void QmlEngine::executeNext() @@ -368,8 +381,8 @@ void QmlEngine::executeNext() QDataStream rs(&reply, QIODevice::WriteOnly); rs << QByteArray("STEPOVER"); sendMessage(reply); - setState(InferiorRunningRequested); - setState(InferiorRunning); + setState(InferiorRunRequested); + setState(InferiorRunOk); SDEBUG("QmlEngine::nextExec()"); } @@ -619,8 +632,8 @@ void QmlEngine::messageReceived(const QByteArray &message) showMessage(_("RECEIVED RESPONSE: ") + quoteUnprintableLatin1(message)); if (command == "STOPPED") { - setState(InferiorStopping); - setState(InferiorStopped); + setState(InferiorStopRequested); + setState(InferiorStopOk); QList<QPair<QString, QPair<QString, qint32> > > backtrace; QList<QPair<QString, QVariant> > watches; @@ -713,7 +726,7 @@ void QmlEngine::handleProcError(QProcess::ProcessError error) case QProcess::Timedout: default: m_proc.kill(); - setState(EngineShuttingDown, true); + setState(EngineShutdownRequested, true); plugin()->showMessageBox(QMessageBox::Critical, tr("Gdb I/O Error"), errorMessage(error)); break; @@ -1253,7 +1266,7 @@ void QmlEngine::debuggerStateChanged(int newState) if (m_simultaneousCppAndQmlDebugMode) { switch(newState) { - case Debugger::EngineSettingUp: + case Debugger::EngineSetupRequested: { m_connectionInitialized = false; break; @@ -1262,9 +1275,9 @@ void QmlEngine::debuggerStateChanged(int newState) case Debugger::InferiorSetupFailed: emit statusMessage(QString(tr("Debugging failed: could not start C++ debugger."))); break; - case Debugger::InferiorRunningRequested: + case Debugger::InferiorRunRequested: { - if (m_cppDebuggerState == Debugger::InferiorStopped) { + if (m_cppDebuggerState == Debugger::InferiorStopOk) { // re-enable UI again m_objectTreeWidget->setEnabled(true); m_propertiesWidget->setEnabled(true); @@ -1272,7 +1285,7 @@ void QmlEngine::debuggerStateChanged(int newState) } break; } - case Debugger::InferiorRunning: + case Debugger::InferiorRunOk: { if (!m_connectionInitialized) { m_connectionInitialized = true; @@ -1281,14 +1294,14 @@ void QmlEngine::debuggerStateChanged(int newState) } break; } - case Debugger::InferiorStopped: + case Debugger::InferiorStopOk: { m_objectTreeWidget->setEnabled(false); m_propertiesWidget->setEnabled(false); m_expressionWidget->setEnabled(false); break; } - case Debugger::EngineShuttingDown: + case Debugger::EngineShutdownRequested: { m_connectionInitialized = false; // here it's safe to enable the debugger windows again - diff --git a/src/plugins/debugger/qml/qmlengine.h b/src/plugins/debugger/qml/qmlengine.h index 55dabf75c1..1b7c94a889 100644 --- a/src/plugins/debugger/qml/qmlengine.h +++ b/src/plugins/debugger/qml/qmlengine.h @@ -86,10 +86,13 @@ private: void executeStepI(); void executeNextI(); - void shutdown(); - void setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos); void setupEngine(); - void exitDebugger(); + void setupInferior(); + void runEngine(); + void shutdownInferior(); + void shutdownEngine(); + + void setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos); void continueInferior(); void interruptInferior(); diff --git a/src/plugins/debugger/registerwindow.cpp b/src/plugins/debugger/registerwindow.cpp index 62837c4c5c..849471fc7d 100644 --- a/src/plugins/debugger/registerwindow.cpp +++ b/src/plugins/debugger/registerwindow.cpp @@ -170,7 +170,7 @@ void RegisterWindow::contextMenuEvent(QContextMenuEvent *ev) QAction *actReload = menu.addAction(tr("Reload Register Listing")); actReload->setEnabled((engineCapabilities & RegisterCapability) - && (state == InferiorStopped || state == InferiorUnrunnable)); + && (state == InferiorStopOk || state == InferiorUnrunnable)); menu.addSeparator(); diff --git a/src/plugins/debugger/script/scriptengine.cpp b/src/plugins/debugger/script/scriptengine.cpp index cbc9f9d96a..1de6c32618 100644 --- a/src/plugins/debugger/script/scriptengine.cpp +++ b/src/plugins/debugger/script/scriptengine.cpp @@ -65,7 +65,7 @@ #include <QtScript/QScriptValue> #include <QtScript/QScriptValueIterator> -#define DEBUG_SCRIPT 1 +//#define DEBUG_SCRIPT 1 #if DEBUG_SCRIPT # define SDEBUG(s) qDebug() << s #else @@ -101,34 +101,44 @@ public: int baseLineNumber); void scriptUnload(qint64 id); + void showMessage(const QString &msg); + private: void maybeBreakNow(bool byFunction); ScriptEngine *q; + int m_depth; + int m_contextDepth; }; ScriptAgent::ScriptAgent(ScriptEngine *debugger, QScriptEngine *script) - : QScriptEngineAgent(script), q(debugger) + : QScriptEngineAgent(script), q(debugger), m_depth(0), m_contextDepth(0) {} +void ScriptAgent::showMessage(const QString &msg) +{ + SDEBUG(msg); + q->showMessage(msg, LogMisc); +} + void ScriptAgent::contextPop() { - SDEBUG("ScriptAgent::contextPop: "); + //showMessage(_("ContextPop: %1").arg(m_contextDepth)); + --m_contextDepth; } void ScriptAgent::contextPush() { - SDEBUG("ScriptAgent::contextPush: "); + ++m_contextDepth; + //showMessage(_("ContextPush: %1 ").arg(m_contextDepth)); } void ScriptAgent::exceptionCatch(qint64 scriptId, const QScriptValue & exception) { Q_UNUSED(scriptId) Q_UNUSED(exception) - const QString msg = QString::fromLatin1("An exception was caught on %1: '%2'"). - arg(scriptId).arg(exception.toString()); - SDEBUG(msg); - q->showMessage(msg, LogMisc); + showMessage(_("An exception was caught on %1: '%2'"). + arg(scriptId).arg(exception.toString())); } void ScriptAgent::exceptionThrow(qint64 scriptId, const QScriptValue &exception, @@ -137,16 +147,15 @@ void ScriptAgent::exceptionThrow(qint64 scriptId, const QScriptValue &exception, Q_UNUSED(scriptId) Q_UNUSED(exception) Q_UNUSED(hasHandler) - const QString msg = QString::fromLatin1("An exception occurred on %1: '%2'"). - arg(scriptId).arg(exception.toString()); - SDEBUG(msg); - q->showMessage(msg, LogMisc); + showMessage(_("An exception occurred on %1: '%2'"). + arg(scriptId).arg(exception.toString())); } void ScriptAgent::functionEntry(qint64 scriptId) { Q_UNUSED(scriptId) - q->showMessage(QString::fromLatin1("Function entry occurred on %1").arg(scriptId), LogMisc); + ++m_depth; + //showMessage(_("Function entry occurred on %1, depth: %2").arg(scriptId)); q->checkForBreakCondition(true); } @@ -154,17 +163,17 @@ void ScriptAgent::functionExit(qint64 scriptId, const QScriptValue &returnValue) { Q_UNUSED(scriptId) Q_UNUSED(returnValue) - const QString msg = QString::fromLatin1("Function exit occurred on %1: '%2'").arg(scriptId).arg(returnValue.toString()); - SDEBUG(msg); - q->showMessage(msg, LogMisc); + --m_depth; + //showMessage(_("Function exit occurred on %1: '%2'"). + // arg(scriptId).arg(returnValue.toString())); } void ScriptAgent::positionChange(qint64 scriptId, int lineNumber, int columnNumber) { - SDEBUG("ScriptAgent::position: " << lineNumber); Q_UNUSED(scriptId) Q_UNUSED(lineNumber) Q_UNUSED(columnNumber) + //showMessage(_("Position: %1").arg(lineNumber)); q->checkForBreakCondition(false); } @@ -175,14 +184,13 @@ void ScriptAgent::scriptLoad(qint64 scriptId, const QString &program, Q_UNUSED(program) Q_UNUSED(fileName) Q_UNUSED(baseLineNumber) - q->showMessage(QString::fromLatin1("Loaded: %1 id: %2") - .arg(fileName).arg(scriptId), LogMisc); + showMessage(_("Loaded: %1 id: %2").arg(fileName).arg(scriptId)); } void ScriptAgent::scriptUnload(qint64 scriptId) { Q_UNUSED(scriptId) - SDEBUG("ScriptAgent::scriptUnload: " << scriptId); + showMessage(_("Unload script id %1 ").arg(scriptId)); } @@ -207,37 +215,36 @@ void ScriptEngine::executeDebuggerCommand(const QString &command) XSDEBUG("FIXME: ScriptEngine::executeDebuggerCommand()"); } -void ScriptEngine::shutdown() +void ScriptEngine::shutdownInferior() { - exitDebugger(); -} - -void ScriptEngine::exitDebugger() -{ - if (state() == DebuggerNotReady) - return; - SDEBUG("ScriptEngine::exitDebugger()"); + QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << state()); + SDEBUG("ScriptEngine::shutdownInferior()"); + m_scriptEngine->setAgent(0); + //m_scriptAgent.reset(0); m_stopped = false; m_stopOnNextLine = false; if (m_scriptEngine->isEvaluating()) m_scriptEngine->abortEvaluation(); - setState(InferiorShuttingDown); - setState(InferiorShutDown); + notifyInferiorShutdownOk(); +} - setState(EngineShuttingDown); +void ScriptEngine::shutdownEngine() +{ + QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state()); m_scriptEngine->setAgent(0); - setState(DebuggerNotReady); + notifyEngineShutdownOk(); } void ScriptEngine::setupEngine() { - QTC_ASSERT(state() == EngineSettingUp, qDebug() << state()); + QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state()); showMessage(_("STARTING SCRIPT DEBUGGER"), LogMisc); if (m_scriptEngine.isNull()) m_scriptEngine = Core::ICore::instance()->scriptManager()->scriptEngine(); - if (!m_scriptAgent) - m_scriptAgent.reset(new ScriptAgent(this, m_scriptEngine.data())); + QTC_ASSERT(!m_scriptAgent, /**/); + m_scriptAgent.reset(new ScriptAgent(this, m_scriptEngine.data())); m_scriptEngine->setAgent(m_scriptAgent.data()); + //m_scriptEngine->setAgent(new ScriptAgent(this, m_scriptEngine.data())); /* Keep the gui alive (have the engine call processEvents() while the script * is run in the foreground). */ m_scriptEngine->setProcessEventsInterval(1 /*ms*/); @@ -251,12 +258,12 @@ void ScriptEngine::setupEngine() void ScriptEngine::setupInferior() { - QTC_ASSERT(state() == InferiorSettingUp, qDebug() << state()); + QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); m_scriptFileName = QFileInfo(startParameters().executable).absoluteFilePath(); showMessage(_("SCRIPT FILE: ") + m_scriptFileName); QFile scriptFile(m_scriptFileName); if (!scriptFile.open(QIODevice::ReadOnly|QIODevice::Text)) { - showMessage(QString::fromLatin1("Cannot open %1: %2"). + showMessage(_("Cannot open %1: %2"). arg(m_scriptFileName, scriptFile.errorString()), LogError); notifyEngineSetupFailed(); return; @@ -270,6 +277,8 @@ void ScriptEngine::setupInferior() void ScriptEngine::continueInferior() { + QTC_ASSERT(state() == InferiorStopOk, qDebug() << state()); + notifyInferiorRunRequested(); SDEBUG("ScriptEngine::continueInferior()"); m_stopped = false; m_stopOnNextLine = false; @@ -280,7 +289,7 @@ static const char *qtExtensionsC[] = { "qt.sql", "qt.opengl", "qt.webkit", "qt.xmlpatterns", "qt.uitools" }; -bool ScriptEngine::importExtensions() +void ScriptEngine::importExtensions() { SDEBUG("ScriptEngine::importExtensions()"); QStringList extensions; @@ -288,11 +297,11 @@ bool ScriptEngine::importExtensions() for (int e = 0; e < extCount; e++) extensions.append(QLatin1String(qtExtensionsC[e])); if (m_scriptEngine->importedExtensions().contains(extensions.front())) - return true; + return; // true; QDir dir(QLatin1String("/home/apoenitz/dev/qtscriptgenerator")); if (!dir.cd(QLatin1String("plugins"))) { fprintf(stderr, "plugins folder does not exist -- did you build the bindings?\n"); - return false; + return; // false; } QStringList paths = qApp->libraryPaths(); paths << dir.absolutePath(); @@ -319,45 +328,43 @@ bool ScriptEngine::importExtensions() qPrintable(failExtensions.join(QLatin1String(", "))), qPrintable(dir.absolutePath())); } } - return failExtensions.isEmpty(); + return; // failExtensions.isEmpty(); } void ScriptEngine::runEngine() { - QTC_ASSERT(state() == InferiorSetupOk, qDebug() << state()); - setState(InferiorRunningRequested); + QTC_ASSERT(state() == EngineRunRequested, qDebug() << state()); + SDEBUG("ScriptEngine::runEngine()"); + notifyEngineRunAndInferiorRunOk(); showStatusMessage(tr("Running requested..."), 5000); showMessage(QLatin1String("Running: ") + m_scriptFileName, LogMisc); - SDEBUG("ScriptEngine::runEngine()"); importExtensions(); - setState(InferiorRunning); const QScriptValue result = m_scriptEngine->evaluate(m_scriptContents, m_scriptFileName); - setState(InferiorStopping); - setState(InferiorStopped); QString msg; if (m_scriptEngine->hasUncaughtException()) { - msg = QString::fromLatin1("An exception occurred during execution at line: %1\n%2\n") + msg = _("An exception occurred during execution at line: %1\n%2\n") .arg(m_scriptEngine->uncaughtExceptionLineNumber()) .arg(m_scriptEngine->uncaughtException().toString()); msg += m_scriptEngine->uncaughtExceptionBacktrace() .join(QString(QLatin1Char('\n'))); } else { - msg = QString::fromLatin1("Evaluation returns '%1'") - .arg(result.toString()); + msg = _("Evaluation returns '%1'").arg(result.toString()); } showMessage(msg, LogMisc); - exitDebugger(); + showMessage(_("This was the outermost function.")); + notifyInferiorExited(); } void ScriptEngine::interruptInferior() { - m_stopped = false; m_stopOnNextLine = true; XSDEBUG("ScriptEngine::interruptInferior()"); } void ScriptEngine::executeStep() { + QTC_ASSERT(state() == InferiorStopOk, qDebug() << state()); + notifyInferiorRunRequested(); //SDEBUG("ScriptEngine::stepExec()"); m_stopped = false; m_stopOnNextLine = true; @@ -365,6 +372,8 @@ void ScriptEngine::executeStep() void ScriptEngine::executeStepI() { + QTC_ASSERT(state() == InferiorStopOk, qDebug() << state()); + notifyInferiorRunRequested(); //SDEBUG("ScriptEngine::stepIExec()"); m_stopped = false; m_stopOnNextLine = true; @@ -372,6 +381,8 @@ void ScriptEngine::executeStepI() void ScriptEngine::executeStepOut() { + QTC_ASSERT(state() == InferiorStopOk, qDebug() << state()); + notifyInferiorRunRequested(); //SDEBUG("ScriptEngine::stepOutExec()"); m_stopped = false; m_stopOnNextLine = true; @@ -379,6 +390,8 @@ void ScriptEngine::executeStepOut() void ScriptEngine::executeNext() { + QTC_ASSERT(state() == InferiorStopOk, qDebug() << state()); + notifyInferiorRunRequested(); //SDEBUG("ScriptEngine::nextExec()"); m_stopped = false; m_stopOnNextLine = true; @@ -386,6 +399,8 @@ void ScriptEngine::executeNext() void ScriptEngine::executeNextI() { + QTC_ASSERT(state() == InferiorStopOk, qDebug() << state()); + notifyInferiorRunRequested(); //SDEBUG("ScriptEngine::nextIExec()"); m_stopped = false; m_stopOnNextLine = true; @@ -393,6 +408,8 @@ void ScriptEngine::executeNextI() void ScriptEngine::executeRunToLine(const QString &fileName, int lineNumber) { + QTC_ASSERT(state() == InferiorStopOk, qDebug() << state()); + notifyInferiorRunRequested(); Q_UNUSED(fileName) Q_UNUSED(lineNumber) SDEBUG("FIXME: ScriptEngine::runToLineExec()"); @@ -400,12 +417,16 @@ void ScriptEngine::executeRunToLine(const QString &fileName, int lineNumber) void ScriptEngine::executeRunToFunction(const QString &functionName) { + QTC_ASSERT(state() == InferiorStopOk, qDebug() << state()); + notifyInferiorRunRequested(); Q_UNUSED(functionName) XSDEBUG("FIXME: ScriptEngine::runToFunctionExec()"); } void ScriptEngine::executeJumpToLine(const QString &fileName, int lineNumber) { + QTC_ASSERT(state() == InferiorStopOk, qDebug() << state()); + notifyInferiorRunRequested(); Q_UNUSED(fileName) Q_UNUSED(lineNumber) XSDEBUG("FIXME: ScriptEngine::jumpToLineExec()"); @@ -481,7 +502,7 @@ void ScriptEngine::setToolTipExpression(const QPoint &mousePos, Q_UNUSED(editor) Q_UNUSED(cursorPos) - if (state() != InferiorStopped) { + if (state() != InferiorStopOk) { //SDEBUG("SUPPRESSING DEBUGGER TOOLTIP, INFERIOR NOT STOPPED"); return; } @@ -537,7 +558,7 @@ void ScriptEngine::setToolTipExpression(const QPoint &mousePos, } #if 0 - //if (m_manager->status() != InferiorStopped) + //if (m_manager->status() != InferiorStopOk) // return; // FIXME: 'exp' can contain illegal characters @@ -591,6 +612,11 @@ static BreakpointData *findBreakPointByFileName(BreakHandler *handler, bool ScriptEngine::checkForBreakCondition(bool byFunction) { + // FIXME: Should that ever happen after setAgent(0) in shutdownInferior()? + // In practice, it does, so chicken out. + if (targetState() == DebuggerFinished) + return false; + const QScriptContext *context = m_scriptEngine->currentContext(); const QScriptContextInfo info(context); @@ -599,7 +625,7 @@ bool ScriptEngine::checkForBreakCondition(bool byFunction) const QString fileName = info.fileName(); const int lineNumber = byFunction ? info.functionStartLineNumber() : info.lineNumber(); - SDEBUG("checkForBreakCondition" << byFunction << functionName + SDEBUG(Q_FUNC_INFO << byFunction << functionName << lineNumber << fileName); if (m_stopOnNextLine) { // Interrupt inferior @@ -627,8 +653,7 @@ bool ScriptEngine::checkForBreakCondition(bool byFunction) data->pending = false; data->updateMarker(); } - setState(InferiorStopping); - setState(InferiorStopped); + notifyInferiorSpontaneousStop(); SDEBUG("Stopped at " << lineNumber << fileName); showStatusMessage(tr("Stopped at %1:%2.").arg(fileName).arg(lineNumber), 5000); @@ -644,7 +669,7 @@ void ScriptEngine::updateLocals() { QScriptContext *context = m_scriptEngine->currentContext(); watchHandler()->beginCycle(); - //SDEBUG("UPDATE LOCALS"); + SDEBUG(Q_FUNC_INFO); // // Build stack @@ -674,24 +699,22 @@ void ScriptEngine::updateLocals() WatchData data; data.iname = "local"; - data.name = QString::fromLatin1(data.iname); + data.name = _(data.iname); data.scriptValue = context->activationObject(); watchHandler()->beginCycle(); updateSubItem(data); watchHandler()->endCycle(); - // FIXME: Use an extra thread. This here is evil + // FIXME: Use an extra thread. This here is evil. m_stopped = true; showStatusMessage(tr("Stopped."), 5000); while (m_stopped) { //SDEBUG("LOOPING"); QApplication::processEvents(); } - setState(InferiorRunningRequested); - setState(InferiorRunning); // Clear any exceptions occurred during locals evaluation. m_scriptEngine->clearExceptions(); m_scriptEngine->setAgent(m_scriptAgent.data()); - SDEBUG("Continuing"); + notifyInferiorRunOk(); } void ScriptEngine::updateWatchData(const WatchData &data) @@ -713,7 +736,7 @@ void ScriptEngine::updateSubItem(const WatchData &data0) { WatchData data = data0; QList<WatchData> children; - SDEBUG("\nUPDATE SUBITEM: " << data.toString() << data.scriptValue.toString()); + //SDEBUG("\nUPDATE SUBITEM: " << data.toString() << data.scriptValue.toString()); QTC_ASSERT(data.isValid(), return); if (data.isTypeNeeded() || data.isValueNeeded()) { diff --git a/src/plugins/debugger/script/scriptengine.h b/src/plugins/debugger/script/scriptengine.h index 4f153f52d4..b27ba493e6 100644 --- a/src/plugins/debugger/script/scriptengine.h +++ b/src/plugins/debugger/script/scriptengine.h @@ -68,13 +68,13 @@ private: void executeStepI(); void executeNextI(); - void shutdown(); void setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos); void setupEngine(); void setupInferior(); void runEngine(); - void exitDebugger(); + void shutdownInferior(); + void shutdownEngine(); void continueInferior(); void interruptInferior(); @@ -108,7 +108,7 @@ private: private: friend class ScriptAgent; - bool importExtensions(); + void importExtensions(); QSharedPointer<QScriptEngine> m_scriptEngine; QString m_scriptContents; diff --git a/src/plugins/debugger/tcf/tcfengine.cpp b/src/plugins/debugger/tcf/tcfengine.cpp index 29589ad444..f534d000fd 100644 --- a/src/plugins/debugger/tcf/tcfengine.cpp +++ b/src/plugins/debugger/tcf/tcfengine.cpp @@ -155,14 +155,11 @@ void TcfEngine::socketReadyRead() void TcfEngine::socketConnected() { showStatusMessage("Socket connected."); - if (m_socket->waitForConnected(2000)) - notifyEngineSetupOk(); - else - notifyEngineSetupFailed(); } void TcfEngine::socketDisconnected() { + showStatusMessage("Socket disconnected."); XSDEBUG("FIXME: TcfEngine::socketDisconnected()"); } @@ -171,7 +168,7 @@ void TcfEngine::socketError(QAbstractSocket::SocketError) QString msg = tr("%1.").arg(m_socket->errorString()); //QMessageBox::critical(q->mainWindow(), tr("Error"), msg); showStatusMessage(msg); - exitDebugger(); + notifyEngineIll(); } void TcfEngine::executeDebuggerCommand(const QString &command) @@ -189,29 +186,46 @@ void TcfEngine::executeDebuggerCommand(const QString &command) enqueueCommand(tcf); } -void TcfEngine::shutdown() -{ - m_congestion = 0; - m_inAir = 0; - m_services.clear(); - exitDebugger(); -} - -void TcfEngine::exitDebugger() -{ - SDEBUG("TcfEngine::exitDebugger()"); -} - void TcfEngine::setupEngine() { - QTC_ASSERT(state() == EngineSettingUp, qDebug() << state()); - setState(InferiorRunningRequested); + QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state()); showStatusMessage(tr("Running requested..."), 5000); const DebuggerStartParameters &sp = startParameters(); const int pos = sp.remoteChannel.indexOf(QLatin1Char(':')); const QString host = sp.remoteChannel.left(pos); const quint16 port = sp.remoteChannel.mid(pos + 1).toInt(); m_socket->connectToHost(host, port); + if (m_socket->waitForConnected()) + notifyEngineSetupOk(); + else + notifyEngineSetupFailed(); +} + +void TcfEngine::setupInferior() +{ + QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); + notifyInferiorSetupOk(); +} + +void TcfEngine::runEngine() +{ + QTC_ASSERT(state() == EngineRunRequested, qDebug() << state()); + //notifyEngineRunOk(); +} + +void TcfEngine::shutdownInferior() +{ + QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << state()); + notifyInferiorShutdownOk(); +} + +void TcfEngine::shutdownEngine() +{ + QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state()); + m_congestion = 0; + m_inAir = 0; + m_services.clear(); + notifyEngineShutdownOk(); } void TcfEngine::continueInferior() diff --git a/src/plugins/debugger/tcf/tcfengine.h b/src/plugins/debugger/tcf/tcfengine.h index 570255f39c..583a28734b 100644 --- a/src/plugins/debugger/tcf/tcfengine.h +++ b/src/plugins/debugger/tcf/tcfengine.h @@ -72,10 +72,14 @@ private: void executeStepI(); void executeNextI(); - void shutdown(); - void setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor *editor, int cursorPos); void setupEngine(); - void exitDebugger(); + void setupInferior(); + void runEngine(); + void shutdownInferior(); + void shutdownEngine(); + + void setToolTipExpression(const QPoint &mousePos, + TextEditor::ITextEditor *editor, int cursorPos); void continueInferior(); void interruptInferior(); @@ -90,7 +94,7 @@ private: void attemptBreakpointSynchronization(); void assignValueInDebugger(const QString &expr, const QString &value); - void executeDebuggerCommand(const QString & command); + void executeDebuggerCommand(const QString &command); void loadSymbols(const QString &moduleName); void loadAllSymbols(); |