From 81a8f2f927403796efe4cc5c91301ac22df91f1a Mon Sep 17 00:00:00 2001 From: Friedemann Kleint <Friedemann.Kleint@nokia.com> Date: Thu, 8 Oct 2009 11:43:26 +0200 Subject: [PATCH] Debugger: Improve adapter error handling Correctly reset state on missing Symbian gdb. Provide "settings" options. Reviewed-by: hjk <qtc-committer@nokia.com> --- src/plugins/debugger/debuggerdialogs.cpp | 28 +++++++++++++++- src/plugins/debugger/debuggerdialogs.h | 8 +++++ src/plugins/debugger/debuggermanager.cpp | 14 ++------ src/plugins/debugger/gdb/abstractgdbadapter.h | 2 +- src/plugins/debugger/gdb/attachgdbadapter.cpp | 2 +- src/plugins/debugger/gdb/coregdbadapter.cpp | 2 +- src/plugins/debugger/gdb/gdbengine.cpp | 9 +++--- src/plugins/debugger/gdb/gdbengine.h | 2 +- src/plugins/debugger/gdb/plaingdbadapter.cpp | 2 +- src/plugins/debugger/gdb/trkgdbadapter.cpp | 32 +++++++++++++------ 10 files changed, 71 insertions(+), 30 deletions(-) diff --git a/src/plugins/debugger/debuggerdialogs.cpp b/src/plugins/debugger/debuggerdialogs.cpp index 199a6f52180..dedee2a22de 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 d20f7e7c249..974844e4fdc 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 660340bb4c4..b658dddeea9 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 e471f4fcd88..53d49770fad 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 6cf12996345..0918bf866c0 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 5fa80055c5e..92edb42e68d 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 b92e8e7b548..a45e3208645 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 a3135449f52..1bc2d60e430 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 a71039a3011..a45787afffb 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 85c6419c762..86c7e6f5278 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; -- GitLab