diff --git a/src/plugins/debugger/debuggerconstants.h b/src/plugins/debugger/debuggerconstants.h index 9676d9d956397ed9184de844302b18feebaba31c..99b4317fc572b8fbff017498169d5c48414a6105 100644 --- a/src/plugins/debugger/debuggerconstants.h +++ b/src/plugins/debugger/debuggerconstants.h @@ -114,9 +114,12 @@ enum DebuggerState InferiorSetupRequested, InferiorSetupFailed, + InferiorSetupOk, EngineRunRequested, EngineRunFailed, + EngineRunOk, + InferiorUnrunnable, // Used in the core dump adapter InferiorRunRequested, // Debuggee requested to run @@ -124,16 +127,19 @@ enum DebuggerState InferiorRunFailed, // Debuggee running InferiorStopRequested, // Debuggee running, stop requested + InferiorStopSpontaneous, // Debuggee stopped spontaneously InferiorStopOk, // Debuggee stopped InferiorStopFailed, // Debuggee not stopped, will kill debugger + InferiorExitOk, + InferiorShutdownRequested, - InferiorShutdownOk, InferiorShutdownFailed, + InferiorShutdownOk, EngineShutdownRequested, - EngineShutdownOk, EngineShutdownFailed, + EngineShutdownOk, DebuggerFinished }; diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index c3d066849c8eeb1d186e61f44675914ae960c817..720f8f54a1453dc6a12bdbfd38db0169ab6328ac 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -182,7 +182,8 @@ public: m_threadsHandler(), m_watchHandler(engine), m_disassemblerAgent(engine), - m_memoryAgent(engine) + m_memoryAgent(engine), + m_isStateDebugging(false) { connect(&m_locationTimer, SIGNAL(timeout()), SLOT(resetLocation())); } @@ -229,8 +230,8 @@ public slots: void raiseApplication() { - QTC_ASSERT(m_runControl, return); - m_runControl->bringApplicationToForeground(m_inferiorPid); + QTC_ASSERT(runControl(), return); + runControl()->bringApplicationToForeground(m_inferiorPid); } void scheduleResetLocation() @@ -250,6 +251,9 @@ public slots: public: DebuggerState state() const { return m_state; } + bool isMasterEngine() const { return m_engine->isMasterEngine(); } + DebuggerRunControl *runControl() const + { return m_masterEngine ? m_masterEngine->runControl() : m_runControl; } DebuggerEngine *m_engine; // Not owned. DebuggerEngine *m_masterEngine; // Not owned @@ -280,6 +284,8 @@ public: MemoryAgent m_memoryAgent; QScopedPointer<TextEditor::BaseTextMark> m_locationMark; QTimer m_locationTimer; + + bool m_isStateDebugging; }; @@ -310,16 +316,20 @@ const char *DebuggerEngine::stateName(int s) SN(EngineSetupOk) SN(EngineSetupFailed) SN(EngineRunFailed) + SN(EngineRunOk) SN(InferiorSetupRequested) SN(InferiorSetupFailed) + SN(InferiorSetupOk) SN(EngineRunRequested) SN(InferiorRunRequested) SN(InferiorRunOk) SN(InferiorRunFailed) SN(InferiorUnrunnable) + SN(InferiorStopSpontaneous) SN(InferiorStopRequested) SN(InferiorStopOk) SN(InferiorStopFailed) + SN(InferiorExitOk) SN(InferiorShutdownRequested) SN(InferiorShutdownOk) SN(InferiorShutdownFailed) @@ -476,6 +486,10 @@ void DebuggerEngine::setRegisterValue(int regnr, const QString &value) void DebuggerEngine::showMessage(const QString &msg, int channel, int timeout) const { + if (d->m_masterEngine) { + d->m_masterEngine->showMessage(msg, channel, timeout); + return; + } //if (msg.size() && msg.at(0).isUpper() && msg.at(1).isUpper()) // qDebug() << qPrintable(msg) << "IN STATE" << state(); debuggerCore()->showMessage(msg, channel, timeout); @@ -488,17 +502,16 @@ void DebuggerEngine::showMessage(const QString &msg, int channel, int timeout) c void DebuggerEngine::startDebugger(DebuggerRunControl *runControl) { - if (!isSlaveEngine()) { - d->m_progress.setProgressRange(0, 1000); - Core::FutureProgress *fp = Core::ICore::instance()->progressManager() - ->addTask(d->m_progress.future(), - tr("Launching"), _("Debugger.Launcher")); - fp->setKeepOnFinish(Core::FutureProgress::DontKeepOnFinish); - d->m_progress.reportStarted(); - } QTC_ASSERT(runControl, notifyEngineSetupFailed(); return); QTC_ASSERT(!d->m_runControl, notifyEngineSetupFailed(); return); + d->m_progress.setProgressRange(0, 1000); + Core::FutureProgress *fp = Core::ICore::instance()->progressManager() + ->addTask(d->m_progress.future(), + tr("Launching"), _("Debugger.Launcher")); + fp->setKeepOnFinish(Core::FutureProgress::DontKeepOnFinish); + d->m_progress.reportStarted(); + d->m_runControl = runControl; d->m_inferiorPid = d->m_startParameters.attachPID > 0 @@ -671,32 +684,42 @@ static bool isAllowedTransition(DebuggerState from, DebuggerState to) return to == InferiorSetupRequested || to == EngineShutdownRequested; case InferiorSetupRequested: - return to == EngineRunRequested || to == InferiorSetupFailed; + return to == InferiorSetupOk || to == InferiorSetupFailed; case InferiorSetupFailed: return to == EngineShutdownRequested; + case InferiorSetupOk: + return to == EngineRunRequested; case EngineRunRequested: - return to == InferiorRunRequested || to == InferiorStopRequested - || to == InferiorUnrunnable || to == EngineRunFailed; - + return to == EngineRunOk || EngineRunFailed; case EngineRunFailed: return to == EngineShutdownRequested; + case EngineRunOk: + return InferiorRunOk || to == InferiorStopOk + || to == InferiorUnrunnable; case InferiorRunRequested: return to == InferiorRunOk || to == InferiorRunFailed; case InferiorRunFailed: return to == InferiorStopOk; case InferiorRunOk: - return to == InferiorStopRequested || to == InferiorStopOk; + return to == InferiorStopRequested || to == InferiorStopSpontaneous + || InferiorExitOk; + //|| to == InferiorStopOk; case InferiorStopRequested: return to == InferiorStopOk || to == InferiorStopFailed; + case InferiorStopSpontaneous: + return to == InferiorStopOk; case InferiorStopOk: return to == InferiorRunRequested || to == InferiorShutdownRequested - || to == InferiorStopOk; + || to == InferiorStopOk || InferiorExitOk; case InferiorStopFailed: return to == EngineShutdownRequested; + case InferiorExitOk: + return to == InferiorShutdownOk; + case InferiorUnrunnable: return to == InferiorShutdownRequested; case InferiorShutdownRequested: @@ -724,27 +747,28 @@ static bool isAllowedTransition(DebuggerState from, DebuggerState to) void DebuggerEngine::notifyEngineSetupFailed() { showMessage(_("NOTE: ENGINE SETUP FAILED")); - QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state()); + QTC_ASSERT(state() == EngineSetupRequested, qDebug() << this << state()); setState(EngineSetupFailed); - QTC_ASSERT(d->m_runControl, return); - d->m_runControl->startFailed(); + if (isMasterEngine()) + runControl()->startFailed(); setState(DebuggerFinished); } void DebuggerEngine::notifyEngineSetupOk() { showMessage(_("NOTE: ENGINE SETUP OK")); - QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state()); + QTC_ASSERT(state() == EngineSetupRequested, qDebug() << this << state()); setState(EngineSetupOk); - QTC_ASSERT(d->m_runControl, return); showMessage(_("QUEUE: SETUP INFERIOR")); - QTimer::singleShot(0, d, SLOT(doSetupInferior())); + if (isMasterEngine()) + QTimer::singleShot(0, d, SLOT(doSetupInferior())); } void DebuggerEnginePrivate::doSetupInferior() { + QTC_ASSERT(isMasterEngine(), return); m_engine->showMessage(_("CALL: SETUP INFERIOR")); - QTC_ASSERT(state() == EngineSetupOk, qDebug() << state()); + QTC_ASSERT(state() == EngineSetupOk, qDebug() << m_engine << state()); m_progress.setProgressValue(250); m_engine->setState(InferiorSetupRequested); m_engine->setupInferior(); @@ -753,22 +777,26 @@ void DebuggerEnginePrivate::doSetupInferior() void DebuggerEngine::notifyInferiorSetupFailed() { showMessage(_("NOTE: INFERIOR SETUP FAILED")); - QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); + QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << this << state()); setState(InferiorSetupFailed); - d->queueShutdownEngine(); + if (isMasterEngine()) + d->queueShutdownEngine(); } void DebuggerEngine::notifyInferiorSetupOk() { showMessage(_("NOTE: INFERIOR SETUP OK")); - QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); - d->queueRunEngine(); + QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << this << state()); + setState(InferiorSetupOk); + if (isMasterEngine()) + d->queueRunEngine(); } void DebuggerEnginePrivate::doRunEngine() { + QTC_ASSERT(isMasterEngine(), return); m_engine->showMessage(_("CALL: RUN ENGINE")); - QTC_ASSERT(state() == EngineRunRequested, qDebug() << state()); + QTC_ASSERT(state() == EngineRunRequested, qDebug() << m_engine << state()); m_progress.setProgressValue(300); m_engine->runEngine(); } @@ -778,19 +806,20 @@ void DebuggerEngine::notifyInferiorUnrunnable() showMessage(_("NOTE: INFERIOR UNRUNNABLE")); d->m_progress.setProgressValue(1000); d->m_progress.reportFinished(); - QTC_ASSERT(state() == EngineRunRequested, qDebug() << state()); + QTC_ASSERT(state() == EngineRunRequested, qDebug() << this << state()); setState(InferiorUnrunnable); } void DebuggerEngine::notifyEngineRunFailed() { showMessage(_("NOTE: ENGINE RUN FAILED")); - QTC_ASSERT(state() == EngineRunRequested, qDebug() << state()); + QTC_ASSERT(state() == EngineRunRequested, qDebug() << this << state()); d->m_progress.setProgressValue(900); d->m_progress.reportCanceled(); d->m_progress.reportFinished(); setState(EngineRunFailed); - d->queueShutdownEngine(); + if (isMasterEngine()) + d->queueShutdownEngine(); } void DebuggerEngine::notifyEngineRunAndInferiorRunOk() @@ -798,9 +827,10 @@ void DebuggerEngine::notifyEngineRunAndInferiorRunOk() showMessage(_("NOTE: ENGINE RUN AND INFERIOR RUN OK")); d->m_progress.setProgressValue(1000); d->m_progress.reportFinished(); - QTC_ASSERT(state() == EngineRunRequested, qDebug() << state()); - setState(InferiorRunRequested); - notifyInferiorRunOk(); + QTC_ASSERT(state() == EngineRunRequested, qDebug() << this << state()); + setState(EngineRunOk); + if (isMasterEngine()) + setState(InferiorRunOk); } void DebuggerEngine::notifyEngineRunAndInferiorStopOk() @@ -808,29 +838,30 @@ void DebuggerEngine::notifyEngineRunAndInferiorStopOk() showMessage(_("NOTE: ENGINE RUN AND INFERIOR STOP OK")); d->m_progress.setProgressValue(1000); d->m_progress.reportFinished(); - QTC_ASSERT(state() == EngineRunRequested, qDebug() << state()); - setState(InferiorStopRequested); - notifyInferiorStopOk(); + QTC_ASSERT(state() == EngineRunRequested, qDebug() << this << state()); + setState(EngineRunOk); + if (isMasterEngine()) + setState(InferiorStopOk); } void DebuggerEngine::notifyInferiorRunRequested() { showMessage(_("NOTE: INFERIOR RUN REQUESTED")); - QTC_ASSERT(state() == InferiorStopOk, qDebug() << state()); + QTC_ASSERT(state() == InferiorStopOk, qDebug() << this << state()); setState(InferiorRunRequested); } void DebuggerEngine::notifyInferiorRunOk() { showMessage(_("NOTE: INFERIOR RUN OK")); - QTC_ASSERT(state() == InferiorRunRequested, qDebug() << state()); + QTC_ASSERT(state() == InferiorRunRequested, qDebug() << this << state()); setState(InferiorRunOk); } void DebuggerEngine::notifyInferiorRunFailed() { showMessage(_("NOTE: INFERIOR RUN FAILED")); - QTC_ASSERT(state() == InferiorRunRequested, qDebug() << state()); + QTC_ASSERT(state() == InferiorRunRequested, qDebug() << this << state()); setState(InferiorRunFailed); setState(InferiorStopOk); if (isDying()) @@ -856,28 +887,32 @@ void DebuggerEngine::notifyInferiorStopOk() showMessage(_("NOTE: ... IGNORING STOP MESSAGE")); return; } - QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state()); + QTC_ASSERT(state() == InferiorStopRequested, qDebug() << this << state()); setState(InferiorStopOk); } void DebuggerEngine::notifyInferiorSpontaneousStop() { showMessage(_("NOTE: INFERIOR SPONTANEOUES STOP")); - QTC_ASSERT(state() == InferiorRunOk, qDebug() << state()); - setState(InferiorStopOk); + QTC_ASSERT(state() == InferiorRunOk, qDebug() << this << state()); + setState(InferiorStopSpontaneous); + if (isMasterEngine()) + setState(InferiorStopOk); } void DebuggerEngine::notifyInferiorStopFailed() { showMessage(_("NOTE: INFERIOR STOP FAILED")); - QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state()); + QTC_ASSERT(state() == InferiorStopRequested, qDebug() << this << state()); setState(InferiorStopFailed); - d->queueShutdownEngine(); + if (isMasterEngine()) + d->queueShutdownEngine(); } void DebuggerEnginePrivate::doInterruptInferior() { - QTC_ASSERT(state() == InferiorRunOk, qDebug() << state()); + //QTC_ASSERT(isMasterEngine(), return); + QTC_ASSERT(state() == InferiorRunOk, qDebug() << m_engine << state()); m_engine->setState(InferiorStopRequested); m_engine->showMessage(_("CALL: INTERRUPT INFERIOR")); m_engine->interruptInferior(); @@ -885,7 +920,8 @@ void DebuggerEnginePrivate::doInterruptInferior() void DebuggerEnginePrivate::doShutdownInferior() { - QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << state()); + //QTC_ASSERT(isMasterEngine(), return); + QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << m_engine << state()); resetLocation(); m_targetState = DebuggerFinished; m_engine->showMessage(_("CALL: SHUTDOWN INFERIOR")); @@ -895,10 +931,11 @@ void DebuggerEnginePrivate::doShutdownInferior() void DebuggerEngine::notifyInferiorShutdownOk() { showMessage(_("INFERIOR SUCCESSFULLY SHUT DOWN")); - QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << state()); + QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << this << state()); d->m_lastGoodState = DebuggerNotReady; // A "neutral" value. setState(InferiorShutdownOk); - d->queueShutdownEngine(); + if (isMasterEngine()) + d->queueShutdownEngine(); } void DebuggerEngine::notifyInferiorShutdownFailed() @@ -906,7 +943,8 @@ void DebuggerEngine::notifyInferiorShutdownFailed() showMessage(_("INFERIOR SHUTDOWN FAILED")); QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << this << state()); setState(InferiorShutdownFailed); - d->queueShutdownEngine(); + if (isMasterEngine()) + d->queueShutdownEngine(); } void DebuggerEngine::notifyInferiorIll() @@ -928,7 +966,8 @@ void DebuggerEngine::notifyInferiorIll() void DebuggerEnginePrivate::doShutdownEngine() { - QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state()); + QTC_ASSERT(isMasterEngine(), qDebug() << m_engine; return); + QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << m_engine << state()); m_targetState = DebuggerFinished; m_engine->showMessage(_("CALL: SHUTDOWN ENGINE")); m_engine->shutdownEngine(); @@ -937,28 +976,29 @@ void DebuggerEnginePrivate::doShutdownEngine() void DebuggerEngine::notifyEngineShutdownOk() { showMessage(_("NOTE: ENGINE SHUTDOWN OK")); - QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state()); + QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << this << state()); setState(EngineShutdownOk); - d->queueFinishDebugger(); + if (isMasterEngine()) + d->queueFinishDebugger(); } void DebuggerEngine::notifyEngineShutdownFailed() { showMessage(_("NOTE: ENGINE SHUTDOWN FAILED")); - QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state()); + QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << this << state()); setState(EngineShutdownFailed); - d->queueFinishDebugger(); + if (isMasterEngine()) + d->queueFinishDebugger(); } void DebuggerEnginePrivate::doFinishDebugger() { + QTC_ASSERT(isMasterEngine(), return); m_engine->showMessage(_("NOTE: FINISH DEBUGGER")); - QTC_ASSERT(state() == DebuggerFinished, qDebug() << state()); + QTC_ASSERT(state() == DebuggerFinished, qDebug() << m_engine << state()); resetLocation(); - if (!m_engine->isSlaveEngine()) { - QTC_ASSERT(m_runControl, return); + if (isMasterEngine()) m_runControl->debuggingFinished(); - } } void DebuggerEngine::notifyEngineIll() @@ -980,10 +1020,12 @@ void DebuggerEngine::notifyEngineIll() case InferiorStopOk: showMessage(_("FORWARDING STATE TO InferiorShutdownFailed")); setState(InferiorShutdownFailed, true); - d->queueShutdownEngine(); + if (isMasterEngine()) + d->queueShutdownEngine(); break; default: - d->queueShutdownEngine(); + if (isMasterEngine()) + d->queueShutdownEngine(); break; } } @@ -992,14 +1034,16 @@ void DebuggerEngine::notifyEngineSpontaneousShutdown() { showMessage(_("NOTE: ENGINE SPONTANEOUS SHUTDOWN")); setState(EngineShutdownOk, true); - d->queueFinishDebugger(); + if (isMasterEngine()) + d->queueFinishDebugger(); } void DebuggerEngine::notifyInferiorExited() { + qDebug() << "\nSPONTANEUOUS EXIT: " << this << d->m_state; showMessage(_("NOTE: INFERIOR EXITED")); d->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. @@ -1009,13 +1053,28 @@ void DebuggerEngine::notifyInferiorExited() } setState(InferiorShutdownRequested); setState(InferiorShutdownOk); - d->queueShutdownEngine(); +*/ + setState(InferiorExitOk); + if (isMasterEngine()) { + setState(InferiorShutdownOk); + d->queueShutdownEngine(); + } +} + +void DebuggerEngine::slaveEngineStateChanged(DebuggerEngine *slaveEngine, + DebuggerState state) +{ + Q_UNUSED(slaveEngine); + Q_UNUSED(state); } void DebuggerEngine::setState(DebuggerState state, bool forced) { - //qDebug() << "STATUS CHANGE: FROM " << stateName(d->m_state) - // << " TO " << stateName(state); + if (isStateDebugging()) { + qDebug() << "STATUS CHANGE: " << this + << " FROM " << stateName(d->m_state) << " TO " << stateName(state) + << isMasterEngine(); + } DebuggerState oldState = d->m_state; d->m_state = state; @@ -1024,7 +1083,7 @@ void DebuggerEngine::setState(DebuggerState state, bool forced) .arg(stateName(oldState)).arg(oldState).arg(stateName(state)).arg(state) .arg(forced ? " BY FORCE" : ""); if (!forced && !isAllowedTransition(oldState, state)) - qDebug() << "UNEXPECTED STATE TRANSITION: " << msg; + qDebug() << "*** UNEXPECTED STATE TRANSITION: " << this << msg; if (state == DebuggerFinished) { // Give up ownership on claimed breakpoints. @@ -1040,16 +1099,31 @@ void DebuggerEngine::setState(DebuggerState state, bool forced) showMessage(msg, LogDebug); updateViews(); - emit stateChanged(d->m_state); + if (isMasterEngine()) + emit stateChanged(d->m_state); + + if (isSlaveEngine()) + masterEngine()->slaveEngineStateChanged(this, state); +} + +void DebuggerEngine::setSilentState(DebuggerState state) +{ + qDebug() << "SILENT STATUS CHANGE: " << this + << " FROM " << stateName(d->m_state) << " TO " << stateName(state) + << isMasterEngine(); + + DebuggerState oldState = d->m_state; + d->m_state = state; + if (!isAllowedTransition(oldState, state)) + qDebug() << "*** SILENT UNEXPECTED STATE TRANSITION " << this; } void DebuggerEngine::updateViews() { // The slave engines are not entitled to change the view. Their wishes // should be coordinated by their master engine. - if (isSlaveEngine()) - return; - debuggerCore()->updateState(this); + if (isMasterEngine()) + debuggerCore()->updateState(this); } bool DebuggerEngine::isSlaveEngine() const @@ -1057,6 +1131,11 @@ bool DebuggerEngine::isSlaveEngine() const return d->m_masterEngine != 0; } +bool DebuggerEngine::isMasterEngine() const +{ + return d->m_masterEngine == 0; +} + DebuggerEngine *DebuggerEngine::masterEngine() const { return d->m_masterEngine; @@ -1078,14 +1157,18 @@ bool DebuggerEngine::debuggerActionsEnabled(DebuggerState state) case InferiorStopRequested: case InferiorRunRequested: case InferiorRunFailed: + case InferiorSetupOk: case DebuggerNotReady: case EngineSetupRequested: case EngineSetupOk: case EngineSetupFailed: case EngineRunRequested: case EngineRunFailed: + case EngineRunOk: case InferiorSetupFailed: case InferiorStopFailed: + case InferiorStopSpontaneous: + case InferiorExitOk: case InferiorShutdownRequested: case InferiorShutdownOk: case InferiorShutdownFailed: @@ -1150,7 +1233,7 @@ void DebuggerEngine::progressPing() DebuggerRunControl *DebuggerEngine::runControl() const { - return d->m_runControl; + return d->runControl(); } void DebuggerEngine::setToolTipExpression @@ -1305,21 +1388,21 @@ void DebuggerEngine::attemptBreakpointSynchronization() void DebuggerEngine::insertBreakpoint(BreakpointId id) { BreakpointState state = breakHandler()->state(id); - QTC_ASSERT(state == BreakpointInsertRequested, qDebug() << state); + QTC_ASSERT(state == BreakpointInsertRequested, qDebug() << id << this << state); QTC_ASSERT(false, /**/); } void DebuggerEngine::removeBreakpoint(BreakpointId id) { BreakpointState state = breakHandler()->state(id); - QTC_ASSERT(state == BreakpointRemoveRequested, qDebug() << state); + QTC_ASSERT(state == BreakpointRemoveRequested, qDebug() << id << this << state); QTC_ASSERT(false, /**/); } void DebuggerEngine::changeBreakpoint(BreakpointId id) { BreakpointState state = breakHandler()->state(id); - QTC_ASSERT(state == BreakpointChangeRequested, qDebug() << state); + QTC_ASSERT(state == BreakpointChangeRequested, qDebug() << id << this << state); QTC_ASSERT(false, /**/); } @@ -1511,6 +1594,16 @@ void DebuggerEngine::handleRemoteSetupFailed(const QString &message) Q_UNUSED(message); } +bool DebuggerEngine::isStateDebugging() const +{ + return d->m_isStateDebugging; +} + +void DebuggerEngine::setStateDebugging(bool on) +{ + d->m_isStateDebugging = on; +} + } // namespace Debugger #include "debuggerengine.moc" diff --git a/src/plugins/debugger/debuggerengine.h b/src/plugins/debugger/debuggerengine.h index 11a159610464ecf4cc7fb108f78f5609169f9d5b..6273a319ea888760c24661c7dd9a2d854405e54f 100644 --- a/src/plugins/debugger/debuggerengine.h +++ b/src/plugins/debugger/debuggerengine.h @@ -241,6 +241,7 @@ public: virtual void updateViews(); bool isSlaveEngine() const; + bool isMasterEngine() const; DebuggerEngine *masterEngine() const; signals: @@ -320,7 +321,7 @@ protected: virtual void frameUp(); virtual void frameDown(); - DebuggerRunControl *runControl() const; // FIXME: Protect. + DebuggerRunControl *runControl() const; static QString msgWatchpointTriggered(BreakpointId id, int number, quint64 address); @@ -338,12 +339,18 @@ protected: static bool isCppBreakpoint(const Internal::BreakpointParameters &p); + bool isStateDebugging() const; + void setStateDebugging(bool on); + private: // Wrapper engine needs access to state of its subengines. friend class Internal::QmlCppEngine; friend class Internal::DebuggerPluginPrivate; - void setState(DebuggerState state, bool forced = false); + virtual void setState(DebuggerState state, bool forced = false); + virtual void setSilentState(DebuggerState state); + virtual void slaveEngineStateChanged(DebuggerEngine *engine, + DebuggerState state); friend class DebuggerEnginePrivate; DebuggerEnginePrivate *d; diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index b5b12dc02304d0b5135b2cbaccc7602ee711ce65..c21874b5c4d889baef87055d25e279598da9b33f 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -141,7 +141,10 @@ static bool stateAcceptsGdbCommands(DebuggerState state) return true; case DebuggerNotReady: case InferiorStopFailed: + case InferiorStopSpontaneous: + case InferiorSetupOk: case EngineRunFailed: + case EngineRunOk: case InferiorRunFailed: case EngineShutdownOk: case EngineShutdownFailed: diff --git a/src/plugins/debugger/qml/qmlcppengine.cpp b/src/plugins/debugger/qml/qmlcppengine.cpp index 8183272bca5d20d5f8128703f748250bcf2736dd..4acaa6ca425ec494e1038a6269bd6bf8bfc88855 100644 --- a/src/plugins/debugger/qml/qmlcppengine.cpp +++ b/src/plugins/debugger/qml/qmlcppengine.cpp @@ -5,9 +5,12 @@ #include "debuggercore.h" #include <qmljseditor/qmljseditorconstants.h> + #include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/ieditor.h> +#include <utils/qtcassert.h> + #include <QtCore/QTimer> namespace Debugger { @@ -42,14 +45,12 @@ private: DebuggerEngine *m_qmlEngine; DebuggerEngine *m_cppEngine; DebuggerEngine *m_activeEngine; - DebuggerState m_errorState; }; QmlCppEnginePrivate::QmlCppEnginePrivate() : m_qmlEngine(0), m_cppEngine(0), - m_activeEngine(0), - m_errorState(InferiorRunOk) + m_activeEngine(0) {} @@ -70,10 +71,12 @@ QmlCppEngine::QmlCppEngine(const DebuggerStartParameters &sp) } d->m_activeEngine = d->m_cppEngine; - connect(d->m_cppEngine, SIGNAL(stateChanged(DebuggerState)), - SLOT(slaveEngineStateChanged(DebuggerState))); - connect(d->m_qmlEngine, SIGNAL(stateChanged(DebuggerState)), - SLOT(slaveEngineStateChanged(DebuggerState))); + + if (1) { + setStateDebugging(true); + d->m_cppEngine->setStateDebugging(true); + d->m_qmlEngine->setStateDebugging(true); + } } QmlCppEngine::~QmlCppEngine() @@ -217,61 +220,66 @@ void QmlCppEngine::detachDebugger() void QmlCppEngine::executeStep() { + notifyInferiorRunRequested(); d->m_activeEngine->executeStep(); } void QmlCppEngine::executeStepOut() { + notifyInferiorRunRequested(); d->m_activeEngine->executeStepOut(); } void QmlCppEngine::executeNext() { + notifyInferiorRunRequested(); d->m_activeEngine->executeNext(); } void QmlCppEngine::executeStepI() { + notifyInferiorRunRequested(); d->m_activeEngine->executeStepI(); } void QmlCppEngine::executeNextI() { + notifyInferiorRunRequested(); d->m_activeEngine->executeNextI(); } void QmlCppEngine::executeReturn() { + notifyInferiorRunRequested(); d->m_activeEngine->executeReturn(); } void QmlCppEngine::continueInferior() { - if (d->m_activeEngine->state() == InferiorStopOk) { - d->m_activeEngine->continueInferior(); + qDebug() << "\nMASTER CONTINUE INFERIOR" + << d->m_cppEngine->state() << d->m_qmlEngine->state(); + notifyInferiorRunRequested(); + if (d->m_cppEngine->state() == InferiorStopOk) { + d->m_cppEngine->continueInferior(); + } else if (d->m_qmlEngine->state() == InferiorStopOk) { + d->m_qmlEngine->continueInferior(); } else { - notifyInferiorRunRequested(); + QTC_ASSERT(false, qDebug() << "MASTER CANNOT CONTINUE INFERIOR" + << d->m_cppEngine->state() << d->m_qmlEngine->state()); + notifyEngineIll(); } } void QmlCppEngine::interruptInferior() { - if (d->m_activeEngine->state() == InferiorRunOk) { - d->m_activeEngine->requestInterruptInferior(); - } else { - if (d->m_activeEngine->state() == InferiorStopOk && (!checkErrorState(InferiorStopFailed))) { - notifyInferiorStopOk(); - } - } + qDebug() << "\nMASTER INTERRUPT INFERIOR"; } void QmlCppEngine::requestInterruptInferior() { + qDebug() << "\nMASTER REQUEST INTERUPT INFERIOR"; DebuggerEngine::requestInterruptInferior(); - - if (d->m_activeEngine->state() == InferiorRunOk) { - d->m_activeEngine->requestInterruptInferior(); - } + d->m_cppEngine->requestInterruptInferior(); } void QmlCppEngine::executeRunToLine(const QString &fileName, int lineNumber) @@ -306,240 +314,264 @@ void QmlCppEngine::frameDown() ///////////////////////////////////////////////////////// -bool QmlCppEngine::checkErrorState(const DebuggerState stateToCheck) +void QmlCppEngine::setupEngine() { - if (d->m_errorState != stateToCheck) - return false; + qDebug() << "\nMASTER SETUP ENGINE"; + QTC_ASSERT(d->m_cppEngine->state() == DebuggerNotReady, /**/); + QTC_ASSERT(d->m_qmlEngine->state() == DebuggerNotReady, /**/); + d->m_qmlEngine->setSilentState(EngineSetupRequested); + d->m_cppEngine->setSilentState(EngineSetupRequested); + d->m_qmlEngine->setupEngine(); // Always succeeds. + d->m_cppEngine->setupEngine(); // May fail. +} - // reset state ( so that more than one error can accumulate over time ) - d->m_errorState = InferiorRunOk; - switch (stateToCheck) { - case InferiorRunOk: - // nothing to do - break; - case EngineRunFailed: - notifyEngineRunFailed(); - break; - case EngineSetupFailed: - notifyEngineSetupFailed(); - break; - case EngineShutdownFailed: - notifyEngineShutdownFailed(); - break; - case InferiorSetupFailed: - notifyInferiorSetupFailed(); - break; - case InferiorRunFailed: - notifyInferiorRunFailed(); - break; - case InferiorUnrunnable: - notifyInferiorUnrunnable(); - break; - case InferiorStopFailed: - notifyInferiorStopFailed(); - break; - case InferiorShutdownFailed: - notifyInferiorShutdownFailed(); - break; - default: - // unexpected - break; - } - return true; +void QmlCppEngine::notifyEngineRunAndInferiorRunOk() +{ + qDebug() << "\nMASTER NOTIFY ENGINE RUN AND INFERIOR RUN OK"; + DebuggerEngine::notifyEngineRunAndInferiorRunOk(); } void QmlCppEngine::notifyInferiorRunOk() { + qDebug() << "\nMASTER NOTIFY INFERIOR RUN OK"; DebuggerEngine::notifyInferiorRunOk(); } -void QmlCppEngine::setupEngine() +void QmlCppEngine::notifyInferiorSpontaneousStop() { - d->m_cppEngine->startDebugger(runControl()); + qDebug() << "\nMASTER SPONTANEOUS STOP OK"; + DebuggerEngine::notifyInferiorSpontaneousStop(); } -void QmlCppEngine::setupInferior() +void QmlCppEngine::notifyInferiorShutdownOk() { - if (!checkErrorState(InferiorSetupFailed)) { - notifyInferiorSetupOk(); - } + qDebug() << "\nMASTER INFERIOR SHUTDOWN OK"; + DebuggerEngine::notifyInferiorShutdownOk(); } -void QmlCppEngine::runEngine() +void QmlCppEngine::setupInferior() { - if (!checkErrorState(EngineRunFailed)) { - if (d->m_errorState == InferiorRunOk) { - switch (d->m_activeEngine->state()) { - case InferiorRunOk: - notifyEngineRunAndInferiorRunOk(); - break; - case InferiorStopOk: - notifyEngineRunAndInferiorStopOk(); - break; - default: // not supported? - notifyEngineRunFailed(); - break; - } - } else { - notifyEngineRunFailed(); - } - } + qDebug() << "\nMASTER SETUP INFERIOR"; + QTC_ASSERT(d->m_cppEngine->state() == EngineSetupOk, /**/); + QTC_ASSERT(d->m_qmlEngine->state() == EngineSetupOk, /**/); + d->m_qmlEngine->setSilentState(InferiorSetupRequested); + d->m_cppEngine->setSilentState(InferiorSetupRequested); + d->m_cppEngine->setupInferior(); + d->m_qmlEngine->setupInferior(); } -void QmlCppEngine::shutdownInferior() +void QmlCppEngine::runEngine() { - if (!checkErrorState(InferiorShutdownFailed)) { - if (d->m_cppEngine->state() == InferiorStopOk) { - d->m_cppEngine->quitDebugger(); - } else { - notifyInferiorShutdownOk(); - } - } + qDebug() << "\nMASTER RUN ENGINE"; + QTC_ASSERT(d->m_cppEngine->state() == InferiorSetupOk, /**/); + QTC_ASSERT(d->m_qmlEngine->state() == InferiorSetupOk, /**/); + d->m_qmlEngine->setSilentState(EngineRunRequested); + d->m_cppEngine->setSilentState(EngineRunRequested); + d->m_cppEngine->runEngine(); + d->m_qmlEngine->runEngine(); } -void QmlCppEngine::initEngineShutdown() +void QmlCppEngine::shutdownInferior() { - if (d->m_qmlEngine->state() != DebuggerFinished) { - d->m_qmlEngine->quitDebugger(); - } else - if (d->m_cppEngine->state() != DebuggerFinished) { - d->m_cppEngine->quitDebugger(); - } else - if (state() == EngineSetupRequested) { - if (!runControl() || d->m_errorState == EngineSetupFailed) { - notifyEngineSetupFailed(); - } else { - notifyEngineSetupOk(); - } - } else - if (state() == InferiorStopRequested) { - checkErrorState(InferiorStopFailed); - } else - if (state() == InferiorShutdownRequested && !checkErrorState(InferiorShutdownFailed)) { - notifyInferiorShutdownOk(); - } else - if (state() != DebuggerFinished) { - quitDebugger(); - } + qDebug() << "\nMASTER SHUTDOWN INFERIOR"; + d->m_qmlEngine->quitDebugger(); } void QmlCppEngine::shutdownEngine() { - if (!checkErrorState(EngineShutdownFailed)) { - showStatusMessage(tr("Debugging finished")); - notifyEngineShutdownOk(); - } + qDebug() << "\nMASTER SHUTDOWN ENGINE"; + QTC_ASSERT(d->m_cppEngine->state() == InferiorShutdownOk, /**/); + QTC_ASSERT(d->m_qmlEngine->state() == InferiorShutdownOk, /**/); + d->m_qmlEngine->setSilentState(EngineShutdownRequested); + d->m_cppEngine->setSilentState(EngineShutdownRequested); + d->m_qmlEngine->shutdownEngine(); + d->m_cppEngine->shutdownEngine(); } -void QmlCppEngine::setupSlaveEngine() +void QmlCppEngine::setState(DebuggerState newState, bool forced) { - if (d->m_qmlEngine->state() == DebuggerNotReady) - d->m_qmlEngine->startDebugger(runControl()); + qDebug() << "SET MASTER STATE: " << newState; + qDebug() << " CPP STATE: " << d->m_cppEngine->state(); + qDebug() << " QML STATE: " << d->m_qmlEngine->state(); + DebuggerEngine::setState(newState, forced); } -void QmlCppEngine::slaveEngineStateChanged(const DebuggerState newState) +void QmlCppEngine::slaveEngineStateChanged + (DebuggerEngine *slaveEngine, const DebuggerState newState) { - DebuggerEngine *slaveEngine = qobject_cast<DebuggerEngine *>(sender()); - if (newState == InferiorStopOk && slaveEngine != d->m_activeEngine) { - QString engineName = slaveEngine == d->m_cppEngine - ? QLatin1String("C++") : QLatin1String("QML"); - showStatusMessage(tr("%1 debugger activated").arg(engineName)); - d->m_activeEngine = d->m_qmlEngine; - } + const bool isCpp = slaveEngine == d->m_cppEngine; + //const bool isQml = slaveEngine == d->m_qmlEngine; + DebuggerEngine *otherEngine = isCpp ? d->m_qmlEngine : d->m_cppEngine; + + qDebug() << "GOT SLAVE STATE: " << slaveEngine << newState; + qDebug() << " OTHER ENGINE: " << otherEngine << otherEngine->state(); + qDebug() << " COMBINED ENGINE: " << this << state() << isDying(); switch (newState) { - case InferiorRunOk: - // startup? - if (d->m_qmlEngine->state() == DebuggerNotReady) { - setupSlaveEngine(); - } else - if (d->m_cppEngine->state() == DebuggerNotReady) { - setupEngine(); - } else - if (state() == EngineSetupRequested) { + + case DebuggerNotReady: + case InferiorUnrunnable: + break; + + case EngineSetupRequested: + break; + + case EngineSetupFailed: + notifyEngineSetupFailed(); + break; + + case EngineSetupOk: + if (otherEngine->state() == EngineSetupOk) notifyEngineSetupOk(); - } else - // breakpoint? - if (state() == InferiorStopOk) { - continueInferior(); - } else - if (state() == InferiorStopRequested) { - checkErrorState(InferiorStopFailed); - } else - if (state() == InferiorRunRequested && (!checkErrorState(InferiorRunFailed)) && (!checkErrorState(InferiorUnrunnable))) { - notifyInferiorRunOk(); + else + qDebug() << "... WAITING FOR OTHER ENGINE SETUP..."; + break; + + + case InferiorSetupRequested: + break; + + case InferiorSetupFailed: + notifyInferiorSetupFailed(); + break; + + case InferiorSetupOk: + if (otherEngine->state() == InferiorSetupOk) + notifyInferiorSetupOk(); + else + qDebug() << "... WAITING FOR OTHER INFERIOR SETUP..."; + break; + + + case EngineRunRequested: + break; + + case EngineRunFailed: + notifyEngineRunFailed(); + break; + + case EngineRunOk: + if (otherEngine->state() == EngineRunOk) { + // This is conditionalized on isMasterEngine() in the + // base class, so do it here manually. + slaveEngine->setSilentState(InferiorRunOk); + otherEngine->setSilentState(InferiorRunOk); + notifyEngineRunAndInferiorRunOk(); + } else { + qDebug() << "... WAITING FOR OTHER ENGINE RUN..."; } break; + case InferiorRunRequested: - // follow the inferior - if (state() == InferiorStopOk && checkErrorState(InferiorRunOk)) { - continueInferior(); + break; + + case InferiorRunFailed: + notifyInferiorRunFailed(); + break; + + case InferiorRunOk: + qDebug() << "PLANNED INFERIOR RUN"; + if (otherEngine->state() == InferiorRunOk) + notifyInferiorRunOk(); + else + qDebug() << " **** INFERIOR RUN NOT OK ****"; + break; + + + case InferiorStopSpontaneous: + notifyInferiorSpontaneousStop(); + slaveEngine->setSilentState(InferiorStopOk); + if (slaveEngine != d->m_activeEngine) { + QString engineName = slaveEngine == d->m_cppEngine + ? QLatin1String("C++") : QLatin1String("QML"); + showStatusMessage(tr("%1 debugger activated").arg(engineName)); + d->m_activeEngine = slaveEngine; } break; case InferiorStopRequested: - // follow the inferior - if (state() == InferiorRunOk && checkErrorState(InferiorRunOk)) { - requestInterruptInferior(); - } + break; + + case InferiorStopFailed: + notifyInferiorStopFailed(); break; case InferiorStopOk: - // check breakpoints - if (state() == InferiorRunRequested) { - checkErrorState(InferiorRunFailed); - } else - if (checkErrorState(InferiorRunOk)) { - if (state() == InferiorRunOk) { - requestInterruptInferior(); - } else - if (state() == InferiorStopRequested) { - interruptInferior(); + if (isDying()) { + qDebug() << "... AN INFERIOR STOPPED DURING SHUTDOWN "; + } else { + if (otherEngine->state() == InferiorShutdownOk) { + qDebug() << "... STOPP "; + } else if (state() == InferiorStopRequested) { + qDebug() << "... AN INFERIOR STOPPED EXPECTEDLY"; + notifyInferiorStopOk(); + } else { + qDebug() << "... AN INFERIOR STOPPED UNEXPECTEDLY"; + notifyInferiorSpontaneousStop(); } } break; - case EngineRunFailed: - case EngineSetupFailed: - case EngineShutdownFailed: - case InferiorSetupFailed: - case InferiorRunFailed: - case InferiorUnrunnable: - case InferiorStopFailed: - case InferiorShutdownFailed: - if (d->m_errorState == InferiorRunOk) { - d->m_errorState = newState; + + case InferiorExitOk: + slaveEngine->setSilentState(InferiorShutdownOk); + if (otherEngine->state() == InferiorShutdownOk) { + notifyInferiorExited(); + } else { + if (state() == InferiorRunOk) + notifyInferiorSpontaneousStop(); + otherEngine->notifyInferiorExited(); } break; case InferiorShutdownRequested: break; + case InferiorShutdownFailed: + notifyInferiorShutdownFailed(); + break; + + case InferiorShutdownOk: + if (otherEngine->state() == InferiorShutdownOk) + notifyInferiorShutdownOk(); + else if (otherEngine->state() == InferiorRunOk) + otherEngine->quitDebugger(); + else if (otherEngine->state() == InferiorStopOk) + otherEngine->quitDebugger(); + break; + + case EngineShutdownRequested: - // we have to abort the setup before the sub-engines die - // because we depend on an active runcontrol that will be shut down by the dying engine - if (state() == EngineSetupRequested) - notifyEngineSetupFailed(); break; - case DebuggerFinished: - initEngineShutdown(); + case EngineShutdownFailed: + notifyEngineShutdownFailed(); break; - default: + case EngineShutdownOk: + if (otherEngine->state() == EngineShutdownOk) + notifyEngineShutdownOk(); + else + qDebug() << "... WAITING FOR OTHER ENGINE SHUTDOWN..."; break; + + + case DebuggerFinished: + break; } } void QmlCppEngine::handleRemoteSetupDone(int gdbServerPort, int qmlPort) { + //qDebug() << "MASETER REMOTE SETUP DONE"; d->m_qmlEngine->handleRemoteSetupDone(gdbServerPort, qmlPort); d->m_cppEngine->handleRemoteSetupDone(gdbServerPort, qmlPort); } void QmlCppEngine::handleRemoteSetupFailed(const QString &message) { + //qDebug() << "MASETER REMOTE SETUP FAILED"; d->m_qmlEngine->handleRemoteSetupFailed(message); d->m_cppEngine->handleRemoteSetupFailed(message); } diff --git a/src/plugins/debugger/qml/qmlcppengine.h b/src/plugins/debugger/qml/qmlcppengine.h index f7aa33513e81d4626f38bf3226f548f4bcdc7865..47723628dec2d633fb5cd37ff9703321ba8d82a5 100644 --- a/src/plugins/debugger/qml/qmlcppengine.h +++ b/src/plugins/debugger/qml/qmlcppengine.h @@ -16,86 +16,83 @@ class DEBUGGER_EXPORT QmlCppEngine : public DebuggerEngine public: explicit QmlCppEngine(const DebuggerStartParameters &sp); - virtual ~QmlCppEngine(); + ~QmlCppEngine(); - virtual void setToolTipExpression(const QPoint &mousePos, + void setToolTipExpression(const QPoint &mousePos, TextEditor::ITextEditor * editor, int cursorPos); - virtual void updateWatchData(const WatchData &data, + void updateWatchData(const WatchData &data, const WatchUpdateFlags &flags); - virtual void watchPoint(const QPoint &); - virtual void fetchMemory(MemoryAgent *, QObject *, - quint64 addr, quint64 length); - virtual void fetchDisassembler(DisassemblerAgent *); - virtual void activateFrame(int index); + void watchPoint(const QPoint &); + void fetchMemory(MemoryAgent *, QObject *, quint64 addr, quint64 length); + void fetchDisassembler(DisassemblerAgent *); + void activateFrame(int index); - virtual void reloadModules(); - virtual void examineModules(); - virtual void loadSymbols(const QString &moduleName); - virtual void loadAllSymbols(); - virtual void requestModuleSymbols(const QString &moduleName); + void reloadModules(); + void examineModules(); + void loadSymbols(const QString &moduleName); + void loadAllSymbols(); + void requestModuleSymbols(const QString &moduleName); - virtual void reloadRegisters(); - virtual void reloadSourceFiles(); - virtual void reloadFullStack(); + void reloadRegisters(); + void reloadSourceFiles(); + void reloadFullStack(); - virtual void setRegisterValue(int regnr, const QString &value); - virtual unsigned debuggerCapabilities() const; + void setRegisterValue(int regnr, const QString &value); + unsigned debuggerCapabilities() const; - virtual bool isSynchronous() const; - virtual QByteArray qtNamespace() const; + bool isSynchronous() const; + QByteArray qtNamespace() const; - virtual void createSnapshot(); - virtual void updateAll(); + void createSnapshot(); + void updateAll(); - virtual void attemptBreakpointSynchronization(); - virtual bool acceptsBreakpoint(BreakpointId id) const; - virtual void selectThread(int index); + void attemptBreakpointSynchronization(); + bool acceptsBreakpoint(BreakpointId id) const; + void selectThread(int index); - virtual void assignValueInDebugger(const WatchData *data, + void assignValueInDebugger(const WatchData *data, const QString &expr, const QVariant &value); DebuggerEngine *cppEngine() const; - virtual void handleRemoteSetupDone(int gdbServerPort, int qmlPort); - virtual void handleRemoteSetupFailed(const QString &message); + void handleRemoteSetupDone(int gdbServerPort, int qmlPort); + void handleRemoteSetupFailed(const QString &message); protected: - virtual void detachDebugger(); - virtual void executeStep(); - virtual void executeStepOut(); - virtual void executeNext(); - virtual void executeStepI(); - virtual void executeNextI(); - virtual void executeReturn(); - virtual void continueInferior(); - virtual void interruptInferior(); - virtual void requestInterruptInferior(); - - virtual void executeRunToLine(const QString &fileName, int lineNumber); - virtual void executeRunToFunction(const QString &functionName); - virtual void executeJumpToLine(const QString &fileName, int lineNumber); - virtual void executeDebuggerCommand(const QString &command); - - virtual void frameUp(); - virtual void frameDown(); - - virtual void notifyInferiorRunOk(); - -protected: - virtual void setupEngine(); - virtual void setupInferior(); - virtual void runEngine(); - virtual void shutdownInferior(); - virtual void shutdownEngine(); - -private slots: - void slaveEngineStateChanged(DebuggerState state); - void setupSlaveEngine(); + void detachDebugger(); + void executeStep(); + void executeStepOut(); + void executeNext(); + void executeStepI(); + void executeNextI(); + void executeReturn(); + void continueInferior(); + void interruptInferior(); + void requestInterruptInferior(); + + void executeRunToLine(const QString &fileName, int lineNumber); + void executeRunToFunction(const QString &functionName); + void executeJumpToLine(const QString &fileName, int lineNumber); + void executeDebuggerCommand(const QString &command); + + void frameUp(); + void frameDown(); + + void setupEngine(); + void setupInferior(); + void runEngine(); + void shutdownInferior(); + void shutdownEngine(); + + void notifyInferiorRunOk(); + void notifyInferiorSpontaneousStop(); + void notifyEngineRunAndInferiorRunOk(); + void notifyInferiorShutdownOk(); private: - void initEngineShutdown(); - bool checkErrorState(DebuggerState stateToCheck); void engineStateChanged(DebuggerState newState); + void setState(DebuggerState newState, bool forced = false); + void slaveEngineStateChanged(DebuggerEngine *slaveEngine, DebuggerState state); private: QScopedPointer<QmlCppEnginePrivate> d; diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp index b8c197cd0ca515397e63685fe779e8ee47a1eefa..b0bae0a62671bc33cad71be3395e778f1db82b21 100644 --- a/src/plugins/debugger/qml/qmlengine.cpp +++ b/src/plugins/debugger/qml/qmlengine.cpp @@ -208,7 +208,7 @@ void QmlEngine::setupInferior() connect(&d->m_applicationLauncher, SIGNAL(bringToForegroundRequested(qint64)), runControl(), - SLOT(bringApplicationToForeground(qint64))); + SLOT(bringApplicationToForeground(qint64))); d->m_applicationLauncher.setEnvironment(startParameters().environment); d->m_applicationLauncher.setWorkingDirectory(startParameters().workingDirectory); @@ -675,7 +675,8 @@ void QmlEngine::messageReceived(const QByteArray &message) stream >> command; if (command == "STOPPED") { - if (state() == InferiorRunOk) + qDebug() << command << this << state(); + if (state() == InferiorRunOk || state() == EngineRunOk) notifyInferiorSpontaneousStop(); QString logString = QString(command);