forked from qt-creator/qt-creator
QmlCppDebugger: Decouple states of engines
The main engine now follows mostly the state of the gdb engine, only if a breakpoint is hit/while stepping the state of the qml engine is used. This allows us to hit C++ breakpoints at any time (also when the qml engine hasn't been able to connect yet), and also fixes the invalid transition warnings. Change-Id: If67a56fd28b098952be2606d0a46e04c27835f66 Reviewed-on: http://codereview.qt-project.org/5897 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Friedemann Kleint <Friedemann.Kleint@nokia.com>
This commit is contained in:
@@ -1208,6 +1208,12 @@ void DebuggerEngine::quitDebugger()
|
|||||||
case InferiorRunOk:
|
case InferiorRunOk:
|
||||||
d->doInterruptInferior();
|
d->doInterruptInferior();
|
||||||
break;
|
break;
|
||||||
|
case EngineRunRequested:
|
||||||
|
notifyEngineRunFailed();
|
||||||
|
break;
|
||||||
|
case EngineRunFailed:
|
||||||
|
case DebuggerFinished:
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// FIXME: We should disable the actions connected to that.
|
// FIXME: We should disable the actions connected to that.
|
||||||
notifyInferiorIll();
|
notifyInferiorIll();
|
||||||
|
|||||||
@@ -283,16 +283,18 @@ void QmlCppEngine::updateAll()
|
|||||||
|
|
||||||
void QmlCppEngine::attemptBreakpointSynchronization()
|
void QmlCppEngine::attemptBreakpointSynchronization()
|
||||||
{
|
{
|
||||||
if (d->m_qmlEngine->state() == InferiorRunOk
|
|
||||||
|| d->m_qmlEngine->state() == InferiorRunRequested
|
|
||||||
|| d->m_qmlEngine->state() == InferiorStopOk
|
|
||||||
|| d->m_qmlEngine->state() == InferiorStopRequested) {
|
|
||||||
// We expect both engines to be set up correctly before hitting
|
|
||||||
// any breakpoints, therefore ignore any breakpoints that would
|
|
||||||
// be hit before QDeclarativeEngine is set up.
|
|
||||||
d->m_cppEngine->attemptBreakpointSynchronization();
|
d->m_cppEngine->attemptBreakpointSynchronization();
|
||||||
}
|
|
||||||
|
switch (d->m_qmlEngine->state()) {
|
||||||
|
case InferiorRunOk:
|
||||||
|
case InferiorRunRequested:
|
||||||
|
case InferiorStopOk: // fall through
|
||||||
|
case InferiorStopRequested:
|
||||||
d->m_qmlEngine->attemptBreakpointSynchronization();
|
d->m_qmlEngine->attemptBreakpointSynchronization();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QmlCppEngine::acceptsBreakpoint(BreakpointModelId id) const
|
bool QmlCppEngine::acceptsBreakpoint(BreakpointModelId id) const
|
||||||
@@ -470,6 +472,7 @@ void QmlCppEngine::runEngine()
|
|||||||
void QmlCppEngine::shutdownInferior()
|
void QmlCppEngine::shutdownInferior()
|
||||||
{
|
{
|
||||||
EDEBUG("\nMASTER SHUTDOWN INFERIOR");
|
EDEBUG("\nMASTER SHUTDOWN INFERIOR");
|
||||||
|
d->m_cppEngine->quitDebugger();
|
||||||
d->m_qmlEngine->quitDebugger();
|
d->m_qmlEngine->quitDebugger();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -498,84 +501,63 @@ void QmlCppEngine::slaveEngineStateChanged
|
|||||||
EDEBUG(" OTHER ENGINE: " << otherEngine << otherEngine->state());
|
EDEBUG(" OTHER ENGINE: " << otherEngine << otherEngine->state());
|
||||||
EDEBUG(" COMBINED ENGINE: " << this << state() << isDying());
|
EDEBUG(" COMBINED ENGINE: " << this << state() << isDying());
|
||||||
|
|
||||||
|
// Idea is to follow the state of the cpp engine,
|
||||||
|
// except where we are stepping in QML
|
||||||
|
|
||||||
|
if (slaveEngine == d->m_cppEngine) {
|
||||||
switch (newState) {
|
switch (newState) {
|
||||||
|
|
||||||
case DebuggerNotReady:
|
case DebuggerNotReady:
|
||||||
|
// Can this ever happen?
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EngineSetupRequested:
|
case EngineSetupRequested:
|
||||||
|
QTC_CHECK(state() == EngineSetupRequested);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EngineSetupFailed:
|
case EngineSetupFailed:
|
||||||
|
qmlEngine()->quitDebugger();
|
||||||
notifyEngineSetupFailed();
|
notifyEngineSetupFailed();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EngineSetupOk:
|
case EngineSetupOk:
|
||||||
if (otherEngine->state() == EngineSetupOk)
|
|
||||||
notifyEngineSetupOk();
|
notifyEngineSetupOk();
|
||||||
else
|
|
||||||
EDEBUG("... WAITING FOR OTHER ENGINE SETUP...");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case InferiorSetupRequested:
|
case InferiorSetupRequested:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case InferiorSetupFailed:
|
case InferiorSetupFailed:
|
||||||
if (otherEngine->state() == InferiorRunOk)
|
qmlEngine()->quitDebugger();
|
||||||
otherEngine->quitDebugger();
|
|
||||||
else
|
|
||||||
notifyInferiorSetupFailed();
|
notifyInferiorSetupFailed();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case InferiorSetupOk:
|
case InferiorSetupOk:
|
||||||
if (otherEngine->state() == InferiorSetupOk)
|
|
||||||
notifyInferiorSetupOk();
|
notifyInferiorSetupOk();
|
||||||
else
|
|
||||||
EDEBUG("... WAITING FOR OTHER INFERIOR SETUP...");
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case EngineRunRequested:
|
case EngineRunRequested:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EngineRunFailed:
|
case EngineRunFailed:
|
||||||
if (otherEngine->state() == InferiorRunOk)
|
qmlEngine()->quitDebugger();
|
||||||
otherEngine->quitDebugger();
|
|
||||||
else
|
|
||||||
notifyEngineRunFailed();
|
notifyEngineRunFailed();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case InferiorUnrunnable:
|
case InferiorUnrunnable:
|
||||||
|
notifyInferiorUnrunnable();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case InferiorRunRequested:
|
case InferiorRunRequested:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case InferiorRunOk:
|
case InferiorRunOk:
|
||||||
if (state() == EngineRunRequested) {
|
if (state() == EngineRunRequested)
|
||||||
if (otherEngine->state() == InferiorRunOk) {
|
|
||||||
attemptBreakpointSynchronization();
|
|
||||||
notifyEngineRunAndInferiorRunOk();
|
notifyEngineRunAndInferiorRunOk();
|
||||||
} else {
|
else if (state() == InferiorRunRequested)
|
||||||
EDEBUG("... WAITING FOR OTHER INFERIOR RUN");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (otherEngine->state() == InferiorRunOk) {
|
|
||||||
EDEBUG("PLANNED INFERIOR RUN");
|
|
||||||
if (state() == InferiorStopOk) {
|
|
||||||
notifyInferiorRunRequested();
|
|
||||||
}
|
|
||||||
notifyInferiorRunOk();
|
notifyInferiorRunOk();
|
||||||
} else if (otherEngine->state() == InferiorStopOk) {
|
|
||||||
EDEBUG("PLANNED SINGLE INFERIOR RUN");
|
|
||||||
} else {
|
|
||||||
EDEBUG(" **** INFERIOR RUN NOT OK ****");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case InferiorRunFailed:
|
case InferiorRunFailed:
|
||||||
|
qmlEngine()->quitDebugger();
|
||||||
notifyInferiorRunFailed();
|
notifyInferiorRunFailed();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -584,30 +566,28 @@ void QmlCppEngine::slaveEngineStateChanged
|
|||||||
|
|
||||||
case InferiorStopOk:
|
case InferiorStopOk:
|
||||||
if (isDying()) {
|
if (isDying()) {
|
||||||
EDEBUG("... AN INFERIOR STOPPED DURING SHUTDOWN ");
|
EDEBUG("... CPP ENGINE STOPPED DURING SHUTDOWN ");
|
||||||
if (state() == InferiorStopRequested) {
|
if (state() == InferiorStopRequested)
|
||||||
notifyInferiorStopOk();
|
notifyInferiorStopOk();
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (slaveEngine != d->m_activeEngine) {
|
if (d->m_activeEngine != cppEngine()) {
|
||||||
QString engineName = slaveEngine == d->m_cppEngine
|
showStatusMessage(tr("Cpp debugger activated"));
|
||||||
? QLatin1String("C++") : QLatin1String("QML");
|
d->m_activeEngine = cppEngine();
|
||||||
showStatusMessage(tr("%1 debugger activated").arg(engineName));
|
|
||||||
d->m_activeEngine = slaveEngine;
|
|
||||||
}
|
}
|
||||||
if (otherEngine->state() == InferiorStopOk) {
|
switch (state()) {
|
||||||
EDEBUG("... BOTH STOPPED ");
|
case InferiorStopRequested:
|
||||||
} else if (otherEngine->state() == InferiorShutdownOk) {
|
EDEBUG("... CPP ENGINE STOPPED EXPECTEDLY");
|
||||||
EDEBUG("... STOPP ");
|
|
||||||
} else if (state() == InferiorStopRequested) {
|
|
||||||
EDEBUG("... AN INFERIOR STOPPED EXPECTEDLY");
|
|
||||||
notifyInferiorStopOk();
|
notifyInferiorStopOk();
|
||||||
} else if (state() == EngineRunRequested) {
|
break;
|
||||||
EDEBUG("... AN INFERIOR FAILED STARTUP, OTHER STOPPED EXPECTEDLY");
|
case EngineRunRequested:
|
||||||
// wait for failure notification from other engine
|
EDEBUG("... CPP ENGINE STOPPED ON STARTUP");
|
||||||
} else {
|
notifyEngineRunAndInferiorStopOk();
|
||||||
EDEBUG("... AN INFERIOR STOPPED SPONTANEOUSLY");
|
break;
|
||||||
|
default:
|
||||||
|
QTC_CHECK(state() == InferiorRunOk);
|
||||||
|
EDEBUG("... CPP ENGINE STOPPED SPONTANEOUSLY");
|
||||||
notifyInferiorSpontaneousStop();
|
notifyInferiorSpontaneousStop();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -617,6 +597,8 @@ void QmlCppEngine::slaveEngineStateChanged
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case InferiorExitOk:
|
case InferiorExitOk:
|
||||||
|
qmlEngine()->quitDebugger();
|
||||||
|
notifyInferiorExited();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case InferiorShutdownRequested:
|
case InferiorShutdownRequested:
|
||||||
@@ -627,45 +609,43 @@ void QmlCppEngine::slaveEngineStateChanged
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case InferiorShutdownOk:
|
case InferiorShutdownOk:
|
||||||
if (otherEngine->state() == InferiorShutdownOk) {
|
if (state() == InferiorShutdownRequested)
|
||||||
if (state() == InferiorRunOk)
|
|
||||||
notifyInferiorExited();
|
|
||||||
else
|
|
||||||
notifyInferiorShutdownOk();
|
notifyInferiorShutdownOk();
|
||||||
} else if (otherEngine->state() == InferiorRunOk) {
|
|
||||||
otherEngine->quitDebugger();
|
|
||||||
} else if (otherEngine->state() == InferiorStopOk) {
|
|
||||||
otherEngine->quitDebugger();
|
|
||||||
} else if (otherEngine->state() == EngineRunFailed) {
|
|
||||||
EDEBUG("... INFERIOR STOPPED, OTHER ENGINE FAILED");
|
|
||||||
notifyEngineRunFailed();
|
|
||||||
} else if (otherEngine->state() == InferiorSetupFailed) {
|
|
||||||
EDEBUG("... INFERIOR STOPPED, OTHER INFERIOR FAILED");
|
|
||||||
notifyInferiorSetupFailed();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EngineShutdownRequested:
|
case EngineShutdownRequested:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EngineShutdownFailed:
|
case EngineShutdownFailed:
|
||||||
|
qmlEngine()->quitDebugger();
|
||||||
notifyEngineShutdownFailed();
|
notifyEngineShutdownFailed();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EngineShutdownOk:
|
case EngineShutdownOk: {
|
||||||
if (otherEngine->state() == EngineShutdownOk)
|
qmlEngine()->quitDebugger();
|
||||||
; // Wait for DebuggerFinished.
|
notifyEngineShutdownOk();
|
||||||
else
|
|
||||||
EDEBUG("... WAITING FOR OTHER ENGINE SHUTDOWN...");
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case DebuggerFinished:
|
case DebuggerFinished:
|
||||||
if (otherEngine->state() == DebuggerFinished)
|
|
||||||
notifyEngineShutdownOk();
|
|
||||||
else
|
|
||||||
EDEBUG("... WAITING FOR OTHER DEBUGGER TO FINISH...");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// QML engine state change
|
||||||
|
if (newState == InferiorStopOk) {
|
||||||
|
if (d->m_activeEngine != qmlEngine()) {
|
||||||
|
showStatusMessage(tr("QML debugger activated"));
|
||||||
|
d->m_activeEngine = qmlEngine();
|
||||||
|
}
|
||||||
|
if (state() == InferiorRunOk)
|
||||||
|
notifyInferiorSpontaneousStop();
|
||||||
|
else
|
||||||
|
notifyInferiorStopOk();
|
||||||
|
} else if (newState == InferiorRunOk) {
|
||||||
|
if (d->m_activeEngine == qmlEngine())
|
||||||
|
notifyInferiorRunOk();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlCppEngine::handleRemoteSetupDone(int gdbServerPort, int qmlPort)
|
void QmlCppEngine::handleRemoteSetupDone(int gdbServerPort, int qmlPort)
|
||||||
|
|||||||
@@ -249,8 +249,10 @@ void QmlEngine::connectionError(QAbstractSocket::SocketError socketError)
|
|||||||
if (socketError == QAbstractSocket::RemoteHostClosedError)
|
if (socketError == QAbstractSocket::RemoteHostClosedError)
|
||||||
showMessage(tr("QML Debugger: Remote host closed connection."), StatusBar);
|
showMessage(tr("QML Debugger: Remote host closed connection."), StatusBar);
|
||||||
|
|
||||||
|
if (!isSlaveEngine()) { // normal flow for slave engine when gdb exits
|
||||||
notifyInferiorSpontaneousStop();
|
notifyInferiorSpontaneousStop();
|
||||||
notifyInferiorIll();
|
notifyInferiorIll();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlEngine::serviceConnectionError(const QString &serviceName)
|
void QmlEngine::serviceConnectionError(const QString &serviceName)
|
||||||
|
|||||||
Reference in New Issue
Block a user