forked from qt-creator/qt-creator
Debugger: Improve adapter error handling
Correctly reset state on missing Symbian gdb. Provide "settings" options. Reviewed-by: hjk <qtc-committer@nokia.com>
This commit is contained in:
@@ -28,6 +28,7 @@
|
|||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#include "debuggerdialogs.h"
|
#include "debuggerdialogs.h"
|
||||||
|
#include "debuggerconstants.h"
|
||||||
|
|
||||||
#include "ui_attachcoredialog.h"
|
#include "ui_attachcoredialog.h"
|
||||||
#include "ui_attachexternaldialog.h"
|
#include "ui_attachexternaldialog.h"
|
||||||
@@ -39,6 +40,8 @@
|
|||||||
# include "shared/dbgwinutils.h"
|
# include "shared/dbgwinutils.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
|
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
#include <QtCore/QDir>
|
#include <QtCore/QDir>
|
||||||
#include <QtCore/QFile>
|
#include <QtCore/QFile>
|
||||||
@@ -49,7 +52,7 @@
|
|||||||
#include <QtGui/QPushButton>
|
#include <QtGui/QPushButton>
|
||||||
#include <QtGui/QProxyModel>
|
#include <QtGui/QProxyModel>
|
||||||
#include <QtGui/QSortFilterProxyModel>
|
#include <QtGui/QSortFilterProxyModel>
|
||||||
|
#include <QtGui/QMessageBox>
|
||||||
|
|
||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
@@ -606,5 +609,28 @@ bool AddressDialog::isValid() const
|
|||||||
return ok;
|
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 Internal
|
||||||
} // namespace Debugger
|
} // namespace Debugger
|
||||||
|
|||||||
@@ -63,6 +63,14 @@ struct ProcData
|
|||||||
QString state;
|
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
|
class AttachCoreDialog : public QDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|||||||
@@ -1001,17 +1001,9 @@ void DebuggerManager::startNewDebugger(const DebuggerStartParametersPtr &sp)
|
|||||||
if (!d->m_engine) {
|
if (!d->m_engine) {
|
||||||
emit debuggingFinished();
|
emit debuggingFinished();
|
||||||
// Create Message box with possibility to go to settings
|
// Create Message box with possibility to go to settings
|
||||||
QAbstractButton *settingsButton = 0;
|
const QString msg = tr("Cannot debug '%1' (tool chain: '%2'): %3").
|
||||||
QMessageBox msgBox(QMessageBox::Warning, tr("Warning"),
|
arg(d->m_startParameters->executable, toolChainName, errorMessage);
|
||||||
tr("Cannot debug '%1' (tool chain: '%2'): %3").
|
warningWithSettings(tr("Warning"), msg, QString(), settingsIdHint);
|
||||||
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);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ public:
|
|||||||
|
|
||||||
signals:
|
signals:
|
||||||
void adapterStarted();
|
void adapterStarted();
|
||||||
void adapterStartFailed(const QString &msg);
|
void adapterStartFailed(const QString &msg, const QString &settingsIdHint);
|
||||||
void adapterShutDown();
|
void adapterShutDown();
|
||||||
void adapterShutdownFailed(const QString &msg);
|
void adapterShutdownFailed(const QString &msg);
|
||||||
void adapterCrashed(const QString &msg);
|
void adapterCrashed(const QString &msg);
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ void AttachGdbAdapter::startAdapter()
|
|||||||
|
|
||||||
if (!m_engine->m_outputCollector.listen()) {
|
if (!m_engine->m_outputCollector.listen()) {
|
||||||
emit adapterStartFailed(tr("Cannot set up communication with child process: %1")
|
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;
|
return;
|
||||||
}
|
}
|
||||||
gdbArgs.prepend(_("--tty=") + m_engine->m_outputCollector.serverName());
|
gdbArgs.prepend(_("--tty=") + m_engine->m_outputCollector.serverName());
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ void CoreGdbAdapter::startAdapter()
|
|||||||
|
|
||||||
if (!m_engine->m_outputCollector.listen()) {
|
if (!m_engine->m_outputCollector.listen()) {
|
||||||
emit adapterStartFailed(tr("Cannot set up communication with child process: %1")
|
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;
|
return;
|
||||||
}
|
}
|
||||||
gdbArgs.prepend(_("--tty=") + m_engine->m_outputCollector.serverName());
|
gdbArgs.prepend(_("--tty=") + m_engine->m_outputCollector.serverName());
|
||||||
|
|||||||
@@ -261,8 +261,8 @@ void GdbEngine::connectAdapter()
|
|||||||
|
|
||||||
connect(m_gdbAdapter, SIGNAL(adapterStarted()),
|
connect(m_gdbAdapter, SIGNAL(adapterStarted()),
|
||||||
this, SLOT(handleAdapterStarted()));
|
this, SLOT(handleAdapterStarted()));
|
||||||
connect(m_gdbAdapter, SIGNAL(adapterStartFailed(QString)),
|
connect(m_gdbAdapter, SIGNAL(adapterStartFailed(QString,QString)),
|
||||||
this, SLOT(handleAdapterStartFailed(QString)));
|
this, SLOT(handleAdapterStartFailed(QString,QString)));
|
||||||
connect(m_gdbAdapter, SIGNAL(adapterShutDown()),
|
connect(m_gdbAdapter, SIGNAL(adapterShutDown()),
|
||||||
this, SLOT(handleAdapterShutDown()));
|
this, SLOT(handleAdapterShutDown()));
|
||||||
connect(m_gdbAdapter, SIGNAL(adapterShutdownFailed(QString)),
|
connect(m_gdbAdapter, SIGNAL(adapterShutdownFailed(QString)),
|
||||||
@@ -4051,10 +4051,11 @@ void GdbEngine::gotoLocation(const StackFrame &frame, bool setMarker)
|
|||||||
// Starting up & shutting down
|
// 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"));
|
debugMessage(_("ADAPTER START FAILED"));
|
||||||
showMessageBox(QMessageBox::Critical, tr("Adapter start failed"), msg);
|
warningWithSettings(tr("Adapter start failed"), msg, QString(), settingsIdHint);
|
||||||
shutdown();
|
shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -238,7 +238,7 @@ private slots:
|
|||||||
void readDebugeeOutput(const QByteArray &data);
|
void readDebugeeOutput(const QByteArray &data);
|
||||||
|
|
||||||
void handleAdapterStarted();
|
void handleAdapterStarted();
|
||||||
void handleAdapterStartFailed(const QString &msg);
|
void handleAdapterStartFailed(const QString &msg, const QString &settingsIdHint = QString());
|
||||||
|
|
||||||
void handleInferiorPrepared();
|
void handleInferiorPrepared();
|
||||||
void handleInferiorPreparationFailed(const QString &msg);
|
void handleInferiorPreparationFailed(const QString &msg);
|
||||||
|
|||||||
@@ -345,7 +345,7 @@ void PlainGdbAdapter::emitAdapterStartFailed(const QString &msg)
|
|||||||
bool blocked = m_stubProc.blockSignals(true);
|
bool blocked = m_stubProc.blockSignals(true);
|
||||||
m_stubProc.stop();
|
m_stubProc.stop();
|
||||||
m_stubProc.blockSignals(blocked);
|
m_stubProc.blockSignals(blocked);
|
||||||
emit adapterStartFailed(msg);
|
emit adapterStartFailed(msg, QString());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
#include "trkgdbadapter.h"
|
#include "trkgdbadapter.h"
|
||||||
#include "trkoptions.h"
|
#include "trkoptions.h"
|
||||||
|
#include "trkoptionspage.h"
|
||||||
#include "debuggerstringutils.h"
|
#include "debuggerstringutils.h"
|
||||||
#ifndef STANDALONE_RUNNER
|
#ifndef STANDALONE_RUNNER
|
||||||
#include "gdbengine.h"
|
#include "gdbengine.h"
|
||||||
@@ -397,7 +398,7 @@ void TrkGdbAdapter::emitDelayedAdapterStartFailed(const QString &msg)
|
|||||||
|
|
||||||
void TrkGdbAdapter::slotEmitDelayedAdapterStartFailed()
|
void TrkGdbAdapter::slotEmitDelayedAdapterStartFailed()
|
||||||
{
|
{
|
||||||
emit adapterStartFailed(m_adapterFailMessage);
|
emit adapterStartFailed(m_adapterFailMessage, TrkOptionsPage::settingsId());
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrkGdbAdapter::startInferiorEarly()
|
void TrkGdbAdapter::startInferiorEarly()
|
||||||
@@ -420,7 +421,7 @@ void TrkGdbAdapter::startInferiorEarly()
|
|||||||
QString msg = _("Failed to connect to %1 after "
|
QString msg = _("Failed to connect to %1 after "
|
||||||
"%2 attempts").arg(device).arg(m_waitCount);
|
"%2 attempts").arg(device).arg(m_waitCount);
|
||||||
logMessage(msg);
|
logMessage(msg);
|
||||||
emit adapterStartFailed(msg);
|
emit adapterStartFailed(msg, TrkOptionsPage::settingsId());
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1585,16 +1586,28 @@ void TrkGdbAdapter::interruptInferior()
|
|||||||
|
|
||||||
void TrkGdbAdapter::handleGdbError(QProcess::ProcessError error)
|
void TrkGdbAdapter::handleGdbError(QProcess::ProcessError error)
|
||||||
{
|
{
|
||||||
logMessage(QString("GDB: Process Error %1: %2")
|
if (error == QProcess::FailedToStart) {
|
||||||
.arg(error).arg(m_gdbProc.errorString()));
|
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)
|
void TrkGdbAdapter::handleGdbFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
||||||
{
|
{
|
||||||
logMessage(QString("GDB: ProcessFinished %1 %2")
|
const QString msg = exitStatus == QProcess::NormalExit ?
|
||||||
.arg(exitCode).arg(exitStatus));
|
QString::fromLatin1("GDB: Process finished (exit code: %1).").arg(exitCode) :
|
||||||
setState(DebuggerNotReady);
|
QString::fromLatin1("GDB: Process crashed: %1").arg(m_gdbProc.errorString());
|
||||||
emit adapterShutDown();
|
if (state() == AdapterStarting) {
|
||||||
|
emitDelayedAdapterStartFailed(msg);// Potentially emitted from QProcess::start() on Windows
|
||||||
|
} else {
|
||||||
|
logMessage(msg);
|
||||||
|
setState(DebuggerNotReady);
|
||||||
|
emit adapterShutDown();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrkGdbAdapter::handleGdbStarted()
|
void TrkGdbAdapter::handleGdbStarted()
|
||||||
@@ -1647,7 +1660,7 @@ void TrkGdbAdapter::startAdapter()
|
|||||||
"listener %1 on %2: %3\n");
|
"listener %1 on %2: %3\n");
|
||||||
msg = msg.arg(blueToothListener, device, m_rfcommProc.errorString());
|
msg = msg.arg(blueToothListener, device, m_rfcommProc.errorString());
|
||||||
msg += QString::fromLocal8Bit(m_rfcommProc.readAllStandardError());
|
msg += QString::fromLocal8Bit(m_rfcommProc.readAllStandardError());
|
||||||
emit adapterStartFailed(msg);
|
emit adapterStartFailed(msg, TrkOptionsPage::settingsId());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2070,6 +2083,7 @@ void TrkGdbAdapter::shutdown()
|
|||||||
{
|
{
|
||||||
switch (state()) {
|
switch (state()) {
|
||||||
case AdapterStarting:
|
case AdapterStarting:
|
||||||
|
case AdapterStartFailed:
|
||||||
cleanup();
|
cleanup();
|
||||||
setState(DebuggerNotReady);
|
setState(DebuggerNotReady);
|
||||||
return;
|
return;
|
||||||
|
|||||||
Reference in New Issue
Block a user