Commit 81a8f2f9 authored by Friedemann Kleint's avatar Friedemann Kleint

Debugger: Improve adapter error handling

Correctly reset state on missing Symbian gdb.
Provide "settings" options.
Reviewed-by: default avatarhjk <qtc-committer@nokia.com>
parent 09e72eaa
......@@ -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
......@@ -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
......
......@@ -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;
}
......
......@@ -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);
......
......@@ -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());
......
......@@ -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());
......
......@@ -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();
}
......
......@@ -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);
......
......@@ -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
......
......@@ -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;
......
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