Commit 7c31bd66 authored by Kai Koehne's avatar Kai Koehne

QmlCpp Debugging: Only set C++ breakpoints after QML is connected

If one hits a C++ breakpoint before the QmlEngine is properly set up
the debugging actions are all disabled. Patch 58faedc4 tried to
fix this by automatically executing continue in these cases, but
this let to errors on Mac OS X. Instead just delay the setting of
C++ breakpoints.

Task-number: QTCREATORBUG-5681
Change-Id: I149dea9b453ed7abd33a1a93b5b546d7c6cda8fd
Reviewed-on: http://codereview.qt.nokia.com/2568Reviewed-by: default avatarQt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: default avatarChristiaan Janssen <christiaan.janssen@nokia.com>
parent 0697765f
......@@ -9487,6 +9487,13 @@
libraries on devices. Then select the device as the target before you
start debugging.
\section1 Mixed C++/QML Debugging
You can debug both the C++ and QML parts of your application at the same time:
Select the checkboxes for both languages in the \gui{Run Settings}. However,
C++ breakpoints will be ignored until the debugger has attached also to the QML
engine.
\section1 Starting QML Debugging
To start the application, choose \gui {Debug > Start Debugging
......
......@@ -4862,7 +4862,8 @@ void GdbEngine::handleInferiorPrepared()
}
// Initial attempt to set breakpoints.
if (startParameters().startMode != AttachCore) {
if (startParameters().startMode != AttachCore
&& !isSlaveEngine()) {
showStatusMessage(tr("Setting breakpoints..."));
showMessage(tr("Setting breakpoints..."));
attemptBreakpointSynchronization();
......
......@@ -287,7 +287,15 @@ void QmlCppEngine::updateAll()
void QmlCppEngine::attemptBreakpointSynchronization()
{
d->m_cppEngine->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_qmlEngine->attemptBreakpointSynchronization();
}
......@@ -549,15 +557,18 @@ void QmlCppEngine::slaveEngineStateChanged
case InferiorRunOk:
if (state() == EngineRunRequested) {
if (otherEngine->state() == InferiorRunOk)
if (otherEngine->state() == InferiorRunOk) {
attemptBreakpointSynchronization();
notifyEngineRunAndInferiorRunOk();
else if (otherEngine->state() == InferiorStopOk)
notifyEngineRunAndInferiorStopOk();
else
} else {
EDEBUG("... WAITING FOR OTHER INFERIOR RUN");
}
} else {
if (otherEngine->state() == InferiorRunOk) {
EDEBUG("PLANNED INFERIOR RUN");
if (state() == InferiorStopOk) {
notifyInferiorRunRequested();
}
notifyInferiorRunOk();
} else if (otherEngine->state() == InferiorStopOk) {
EDEBUG("PLANNED SINGLE INFERIOR RUN");
......@@ -595,9 +606,6 @@ void QmlCppEngine::slaveEngineStateChanged
} else if (state() == InferiorStopRequested) {
EDEBUG("... AN INFERIOR STOPPED EXPECTEDLY");
notifyInferiorStopOk();
} else if (otherEngine->state() == EngineRunRequested && otherEngine == d->m_qmlEngine) {
EDEBUG("... BREAKPOINT HIT IN C++ BEFORE QML STARTUP");
QTimer::singleShot(0, this, SLOT(skipCppBreakpoint()));
} else if (state() == EngineRunRequested) {
EDEBUG("... AN INFERIOR FAILED STARTUP, OTHER STOPPED EXPECTEDLY");
// wait for failure notification from other engine
......@@ -686,32 +694,6 @@ void QmlCppEngine::showMessage(const QString &msg, int channel, int timeout) con
DebuggerEngine::showMessage(msg, channel, timeout);
}
void QmlCppEngine::skipCppBreakpoint()
{
// only used to skip breakpoint in CPP when QML not ready yet
QTC_ASSERT(d->m_cppEngine->state() == InferiorStopOk, return);
QTC_ASSERT(d->m_qmlEngine->state() == EngineRunRequested, return);
if (!d->m_msg) {
Core::ICore * const core = Core::ICore::instance();
d->m_msg = new QMessageBox(core->mainWindow());
}
if (d->m_msg->isHidden()) {
d->m_msg->setIcon(QMessageBox::Warning);
d->m_msg->setWindowTitle(tr("QML/C++ Debugging"));
d->m_msg->setText(tr("Cannot stop execution before QML engine is started. Skipping breakpoint.\n"
"Suggestions: Move the breakpoint after QmlApplicationViewer instantiation or switch to C++ only debugging."));
d->m_msg->setStandardButtons(QMessageBox::Ok);
d->m_msg->setDefaultButton(QMessageBox::Ok);
d->m_msg->setModal(false);
d->m_msg->show();
}
d->m_cppEngine->continueInferior();
resetLocation();
}
DebuggerEngine *QmlCppEngine::cppEngine() const
{
return d->m_cppEngine;
......
......@@ -125,9 +125,6 @@ protected:
void notifyEngineRunAndInferiorRunOk();
void notifyInferiorShutdownOk();
protected slots:
void skipCppBreakpoint();
private:
void engineStateChanged(DebuggerState newState);
void setState(DebuggerState newState, bool forced = false);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment