forked from qt-creator/qt-creator
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 58faedc4e 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/2568
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Christiaan Janssen <christiaan.janssen@nokia.com>
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user