diff --git a/src/plugins/debugger/debuggerdialogs.cpp b/src/plugins/debugger/debuggerdialogs.cpp index 199a6f52180bf86e27a220de63aab38115d20ced..dedee2a22dec33822f9c96902c9edebb5e6d3a41 100644 --- a/src/plugins/debugger/debuggerdialogs.cpp +++ b/src/plugins/debugger/debuggerdialogs.cpp @@ -28,6 +28,7 @@ **************************************************************************/ #include "debuggerdialogs.h" +#include "debuggerconstants.h" #include "ui_attachcoredialog.h" #include "ui_attachexternaldialog.h" @@ -39,6 +40,8 @@ # include "shared/dbgwinutils.h" #endif +#include <coreplugin/icore.h> + #include <QtCore/QDebug> #include <QtCore/QDir> #include <QtCore/QFile> @@ -49,7 +52,7 @@ #include <QtGui/QPushButton> #include <QtGui/QProxyModel> #include <QtGui/QSortFilterProxyModel> - +#include <QtGui/QMessageBox> namespace Debugger { namespace Internal { @@ -606,5 +609,28 @@ bool AddressDialog::isValid() const return ok; } +int warningWithSettings(const QString &title, + const QString &text, + const QString &details, + const QString &settingsId, + QWidget *parent) +{ + QMessageBox msgBox(QMessageBox::Warning, title, text, + QMessageBox::Ok, parent); + if (details.isEmpty()) + msgBox.setDetailedText(details); + QAbstractButton *settingsButton = 0; + if (!settingsId.isEmpty()) + settingsButton = msgBox.addButton(QCoreApplication::translate("Debugger::MessageBox", "Settings..."), + QMessageBox::AcceptRole); + const int dialogCode = msgBox.exec(); + if (settingsButton && msgBox.clickedButton() == settingsButton) { + Core::ICore::instance()->showOptionsDialog(QLatin1String(Debugger::Constants::DEBUGGER_SETTINGS_CATEGORY), + settingsId); + return 2; + } + return dialogCode; +} + } // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/debuggerdialogs.h b/src/plugins/debugger/debuggerdialogs.h index d20f7e7c249cfe23cdc5a3ce8cb8bceef69a98dd..974844e4fdc561958908bd0ef950e7a4eb085804 100644 --- a/src/plugins/debugger/debuggerdialogs.h +++ b/src/plugins/debugger/debuggerdialogs.h @@ -63,6 +63,14 @@ struct ProcData QString state; }; +// Display a warning with an additional button to open +// the debugger settings dialog if settingsId is nonempty. +int warningWithSettings(const QString &title, + const QString &text, + const QString &details = QString(), + const QString &settingsId = QString(), + QWidget *parent = 0); + class AttachCoreDialog : public QDialog { Q_OBJECT diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp index 660340bb4c433937b333277161f4285d8ffe9c8c..b658dddeea90a4b9a654ac59f6e6635f1a4f8bee 100644 --- a/src/plugins/debugger/debuggermanager.cpp +++ b/src/plugins/debugger/debuggermanager.cpp @@ -1001,17 +1001,9 @@ void DebuggerManager::startNewDebugger(const DebuggerStartParametersPtr &sp) if (!d->m_engine) { emit debuggingFinished(); // Create Message box with possibility to go to settings - QAbstractButton *settingsButton = 0; - QMessageBox msgBox(QMessageBox::Warning, tr("Warning"), - tr("Cannot debug '%1' (tool chain: '%2'): %3"). - arg(d->m_startParameters->executable, toolChainName, errorMessage), - QMessageBox::Ok); - if (!settingsIdHint.isEmpty()) - settingsButton = msgBox.addButton(tr("Settings..."), QMessageBox::AcceptRole); - msgBox.exec(); - if (msgBox.clickedButton() == settingsButton) - Core::ICore::instance()->showOptionsDialog( - _(Debugger::Constants::DEBUGGER_SETTINGS_CATEGORY), settingsIdHint); + const QString msg = tr("Cannot debug '%1' (tool chain: '%2'): %3"). + arg(d->m_startParameters->executable, toolChainName, errorMessage); + warningWithSettings(tr("Warning"), msg, QString(), settingsIdHint); return; } diff --git a/src/plugins/debugger/gdb/abstractgdbadapter.h b/src/plugins/debugger/gdb/abstractgdbadapter.h index e471f4fcd88c3b9e7a35b972ff9379244e2a6f21..53d49770fada2a2fe010395be6848a913e0c8495 100644 --- a/src/plugins/debugger/gdb/abstractgdbadapter.h +++ b/src/plugins/debugger/gdb/abstractgdbadapter.h @@ -69,7 +69,7 @@ public: signals: void adapterStarted(); - void adapterStartFailed(const QString &msg); + void adapterStartFailed(const QString &msg, const QString &settingsIdHint); void adapterShutDown(); void adapterShutdownFailed(const QString &msg); void adapterCrashed(const QString &msg); diff --git a/src/plugins/debugger/gdb/attachgdbadapter.cpp b/src/plugins/debugger/gdb/attachgdbadapter.cpp index 6cf129963454b14db491866b0a5ea1d09869644d..0918bf866c0786411642bb800636a7b6cd045cf5 100644 --- a/src/plugins/debugger/gdb/attachgdbadapter.cpp +++ b/src/plugins/debugger/gdb/attachgdbadapter.cpp @@ -80,7 +80,7 @@ void AttachGdbAdapter::startAdapter() if (!m_engine->m_outputCollector.listen()) { emit adapterStartFailed(tr("Cannot set up communication with child process: %1") - .arg(m_engine->m_outputCollector.errorString())); + .arg(m_engine->m_outputCollector.errorString()), QString()); return; } gdbArgs.prepend(_("--tty=") + m_engine->m_outputCollector.serverName()); diff --git a/src/plugins/debugger/gdb/coregdbadapter.cpp b/src/plugins/debugger/gdb/coregdbadapter.cpp index 5fa80055c5e98ad4787aa98ffde27fc217e558db..92edb42e68dc69a84b4e724137614ff11214067b 100644 --- a/src/plugins/debugger/gdb/coregdbadapter.cpp +++ b/src/plugins/debugger/gdb/coregdbadapter.cpp @@ -80,7 +80,7 @@ void CoreGdbAdapter::startAdapter() if (!m_engine->m_outputCollector.listen()) { emit adapterStartFailed(tr("Cannot set up communication with child process: %1") - .arg(m_engine->m_outputCollector.errorString())); + .arg(m_engine->m_outputCollector.errorString()), QString()); return; } gdbArgs.prepend(_("--tty=") + m_engine->m_outputCollector.serverName()); diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index b92e8e7b548a367435fd87c19706815185cefeea..a45e32086454cd306296133b167974486329269d 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -261,8 +261,8 @@ void GdbEngine::connectAdapter() connect(m_gdbAdapter, SIGNAL(adapterStarted()), this, SLOT(handleAdapterStarted())); - connect(m_gdbAdapter, SIGNAL(adapterStartFailed(QString)), - this, SLOT(handleAdapterStartFailed(QString))); + connect(m_gdbAdapter, SIGNAL(adapterStartFailed(QString,QString)), + this, SLOT(handleAdapterStartFailed(QString,QString))); connect(m_gdbAdapter, SIGNAL(adapterShutDown()), this, SLOT(handleAdapterShutDown())); connect(m_gdbAdapter, SIGNAL(adapterShutdownFailed(QString)), @@ -4051,10 +4051,11 @@ void GdbEngine::gotoLocation(const StackFrame &frame, bool setMarker) // Starting up & shutting down // -void GdbEngine::handleAdapterStartFailed(const QString &msg) +void GdbEngine::handleAdapterStartFailed(const QString &msg, const QString &settingsIdHint) { + setState(AdapterStartFailed); debugMessage(_("ADAPTER START FAILED")); - showMessageBox(QMessageBox::Critical, tr("Adapter start failed"), msg); + warningWithSettings(tr("Adapter start failed"), msg, QString(), settingsIdHint); shutdown(); } diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index a3135449f524e886060fa56f02fd39a986a6a337..1bc2d60e4307cdd9a108528697842bf7dcb3b4df 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -238,7 +238,7 @@ private slots: void readDebugeeOutput(const QByteArray &data); void handleAdapterStarted(); - void handleAdapterStartFailed(const QString &msg); + void handleAdapterStartFailed(const QString &msg, const QString &settingsIdHint = QString()); void handleInferiorPrepared(); void handleInferiorPreparationFailed(const QString &msg); diff --git a/src/plugins/debugger/gdb/plaingdbadapter.cpp b/src/plugins/debugger/gdb/plaingdbadapter.cpp index a71039a3011016ac56e86a2bd9fcb4e80e18b747..a45787afffb2a3d95be7782000911fed431ab41f 100644 --- a/src/plugins/debugger/gdb/plaingdbadapter.cpp +++ b/src/plugins/debugger/gdb/plaingdbadapter.cpp @@ -345,7 +345,7 @@ void PlainGdbAdapter::emitAdapterStartFailed(const QString &msg) bool blocked = m_stubProc.blockSignals(true); m_stubProc.stop(); m_stubProc.blockSignals(blocked); - emit adapterStartFailed(msg); + emit adapterStartFailed(msg, QString()); } } // namespace Internal diff --git a/src/plugins/debugger/gdb/trkgdbadapter.cpp b/src/plugins/debugger/gdb/trkgdbadapter.cpp index 85c6419c762bcc14058c8ec4e668cace33952eab..86c7e6f52783d18ba6a24768da52f706726f506c 100644 --- a/src/plugins/debugger/gdb/trkgdbadapter.cpp +++ b/src/plugins/debugger/gdb/trkgdbadapter.cpp @@ -29,6 +29,7 @@ #include "trkgdbadapter.h" #include "trkoptions.h" +#include "trkoptionspage.h" #include "debuggerstringutils.h" #ifndef STANDALONE_RUNNER #include "gdbengine.h" @@ -397,7 +398,7 @@ void TrkGdbAdapter::emitDelayedAdapterStartFailed(const QString &msg) void TrkGdbAdapter::slotEmitDelayedAdapterStartFailed() { - emit adapterStartFailed(m_adapterFailMessage); + emit adapterStartFailed(m_adapterFailMessage, TrkOptionsPage::settingsId()); } void TrkGdbAdapter::startInferiorEarly() @@ -420,7 +421,7 @@ void TrkGdbAdapter::startInferiorEarly() QString msg = _("Failed to connect to %1 after " "%2 attempts").arg(device).arg(m_waitCount); logMessage(msg); - emit adapterStartFailed(msg); + emit adapterStartFailed(msg, TrkOptionsPage::settingsId()); } return; } @@ -1585,16 +1586,28 @@ void TrkGdbAdapter::interruptInferior() void TrkGdbAdapter::handleGdbError(QProcess::ProcessError error) { - logMessage(QString("GDB: Process Error %1: %2") - .arg(error).arg(m_gdbProc.errorString())); + if (error == QProcess::FailedToStart) { + const QString msg = QString::fromLatin1("GDB: Cannot start '%1': %2. Please check the settings.").arg(m_options->gdb).arg(m_gdbProc.errorString()); + emitDelayedAdapterStartFailed(msg); // Emitted from QProcess::start() on Windows + } else { + // Others should trigger handleGdbFinished + const QString msg = QString::fromLatin1("GDB: Process error %1: %2").arg(error).arg(m_gdbProc.errorString()); + logMessage(msg); + } } void TrkGdbAdapter::handleGdbFinished(int exitCode, QProcess::ExitStatus exitStatus) { - logMessage(QString("GDB: ProcessFinished %1 %2") - .arg(exitCode).arg(exitStatus)); - setState(DebuggerNotReady); - emit adapterShutDown(); + const QString msg = exitStatus == QProcess::NormalExit ? + QString::fromLatin1("GDB: Process finished (exit code: %1).").arg(exitCode) : + QString::fromLatin1("GDB: Process crashed: %1").arg(m_gdbProc.errorString()); + if (state() == AdapterStarting) { + emitDelayedAdapterStartFailed(msg);// Potentially emitted from QProcess::start() on Windows + } else { + logMessage(msg); + setState(DebuggerNotReady); + emit adapterShutDown(); + } } void TrkGdbAdapter::handleGdbStarted() @@ -1647,7 +1660,7 @@ void TrkGdbAdapter::startAdapter() "listener %1 on %2: %3\n"); msg = msg.arg(blueToothListener, device, m_rfcommProc.errorString()); msg += QString::fromLocal8Bit(m_rfcommProc.readAllStandardError()); - emit adapterStartFailed(msg); + emit adapterStartFailed(msg, TrkOptionsPage::settingsId()); return; } } @@ -2070,6 +2083,7 @@ void TrkGdbAdapter::shutdown() { switch (state()) { case AdapterStarting: + case AdapterStartFailed: cleanup(); setState(DebuggerNotReady); return;