From 063d13e00f7233f89d960973295193bccf26c944 Mon Sep 17 00:00:00 2001 From: hjk <qtc-committer@nokia.com> Date: Thu, 24 Sep 2009 10:08:17 +0200 Subject: [PATCH] debugger: work on general shutdown handling --- src/plugins/debugger/debuggermanager.cpp | 103 ++++++----- src/plugins/debugger/debuggermanager.h | 5 +- src/plugins/debugger/debuggerplugin.cpp | 65 ++++--- src/plugins/debugger/debuggerplugin.h | 1 - src/plugins/debugger/gdb/abstractgdbadapter.h | 12 +- src/plugins/debugger/gdb/attachgdbadapter.h | 1 + src/plugins/debugger/gdb/coregdbadapter.h | 1 + src/plugins/debugger/gdb/gdbengine.cpp | 166 ++++++++++-------- src/plugins/debugger/gdb/gdbengine.h | 4 +- src/plugins/debugger/gdb/plaingdbadapter.h | 1 + src/plugins/debugger/gdb/remotegdbadapter.h | 1 + src/plugins/debugger/gdb/trkgdbadapter.cpp | 28 +-- src/plugins/debugger/gdb/trkgdbadapter.h | 1 + 13 files changed, 203 insertions(+), 186 deletions(-) diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp index 903407750c0..63b50dc4e4b 100644 --- a/src/plugins/debugger/debuggermanager.cpp +++ b/src/plugins/debugger/debuggermanager.cpp @@ -82,6 +82,16 @@ #include <QtGui/QToolButton> #include <QtGui/QToolTip> +#define DEBUG_STATE 1 +#ifdef DEBUG_STATE +// use Q_FUNC_INFO? +# define STATE_DEBUG(s) \ + { QString msg; QTextStream ts(&msg); ts << s; \ + showDebuggerOutput(LogDebug, msg); } +#else +# define STATE_DEBUG(s) +#endif + namespace Debugger { namespace Internal { @@ -458,8 +468,7 @@ QList<Core::IOptionsPage*> DebuggerManager::initializeEngines(unsigned enabledTy } m_engine = 0; - if (Debugger::Constants::Internal::debug) - qDebug() << Q_FUNC_INFO << gdbEngine << winEngine << scriptEngine << rc.size(); + STATE_DEBUG(gdbEngine << winEngine << scriptEngine << rc.size()); return rc; } @@ -526,8 +535,6 @@ void DebuggerManager::clearStatusMessage() void DebuggerManager::showStatusMessage(const QString &msg, int timeout) { Q_UNUSED(timeout) - if (Debugger::Constants::Internal::debug) - qDebug() << "STATUS MSG: " << msg; showDebuggerOutput(LogStatus, msg); m_statusLabel->setText(QLatin1String(" ") + msg); if (timeout > 0) { @@ -572,8 +579,7 @@ void DebuggerManager::notifyInferiorExited() void DebuggerManager::notifyInferiorPidChanged(qint64 pid) { - if (Debugger::Constants::Internal::debug) - qDebug() << Q_FUNC_INFO << m_inferiorPid << pid; + STATE_DEBUG(m_inferiorPid << pid); if (m_inferiorPid != pid) { m_inferiorPid = pid; @@ -588,9 +594,7 @@ void DebuggerManager::showApplicationOutput(const QString &str) void DebuggerManager::shutdown() { - if (Debugger::Constants::Internal::debug) - qDebug() << Q_FUNC_INFO << m_engine; - + STATE_DEBUG(m_engine); if (m_engine) m_engine->shutdown(); m_engine = 0; @@ -643,9 +647,7 @@ void DebuggerManager::toggleBreakpoint() void DebuggerManager::toggleBreakpoint(const QString &fileName, int lineNumber) { - if (Debugger::Constants::Internal::debug) - qDebug() << Q_FUNC_INFO << fileName << lineNumber; - + STATE_DEBUG(fileName << lineNumber); QTC_ASSERT(m_breakHandler, return); if (status() != DebuggerInferiorRunning && status() != DebuggerInferiorStopped @@ -666,9 +668,7 @@ void DebuggerManager::toggleBreakpoint(const QString &fileName, int lineNumber) void DebuggerManager::toggleBreakpointEnabled(const QString &fileName, int lineNumber) { - if (Debugger::Constants::Internal::debug) - qDebug() << Q_FUNC_INFO << fileName << lineNumber; - + STATE_DEBUG(fileName << lineNumber); QTC_ASSERT(m_breakHandler, return); if (status() != DebuggerInferiorRunning && status() != DebuggerInferiorStopped @@ -726,8 +726,6 @@ static IDebuggerEngine *debuggerEngineForToolChain(ProjectExplorer::ToolChain::T default: break; } - if (Debugger::Constants::Internal::debug) - qDebug() << "Toolchain" << tc << rc; return rc; } @@ -819,9 +817,6 @@ static IDebuggerEngine *determineDebuggerEngine(int /* pid */, void DebuggerManager::startNewDebugger(const DebuggerStartParametersPtr &sp) { m_startParameters = sp; - if (Debugger::Constants::Internal::debug) - qDebug() << Q_FUNC_INFO << '\n' << *m_startParameters; - m_inferiorPid = m_startParameters->attachPID > 0 ? m_startParameters->attachPID : 0; const QString toolChainName = ProjectExplorer::ToolChain::toolChainName(static_cast<ProjectExplorer::ToolChain::ToolChainType>(m_startParameters->toolChainType)); @@ -849,7 +844,7 @@ void DebuggerManager::startNewDebugger(const DebuggerStartParametersPtr &sp) } if (!m_engine) { - debuggingFinished(); + emit debuggingFinished(); // Create Message box with possibility to go to settings QAbstractButton *settingsButton = 0; QMessageBox msgBox(QMessageBox::Warning, tr("Warning"), @@ -865,9 +860,7 @@ void DebuggerManager::startNewDebugger(const DebuggerStartParametersPtr &sp) return; } - if (Debugger::Constants::Internal::debug) - qDebug() << m_startParameters->executable << m_engine; - + STATE_DEBUG(m_startParameters->executable << m_engine); setBusyCursor(false); setStatus(DebuggerProcessStartingUp); connect(m_engine, SIGNAL(startFailed()), this, SLOT(startFailed())); @@ -878,7 +871,7 @@ void DebuggerManager::startFailed() { disconnect(m_engine, SIGNAL(startFailed()), this, SLOT(startFailed())); setStatus(DebuggerProcessNotReady); - debuggingFinished(); + emit debuggingFinished(); } void DebuggerManager::cleanupViews() @@ -895,9 +888,7 @@ void DebuggerManager::cleanupViews() void DebuggerManager::exitDebugger() { - if (Debugger::Constants::Internal::debug) - qDebug() << Q_FUNC_INFO; - + STATE_DEBUG(""); if (m_engine) m_engine->exitDebugger(); cleanupViews(); @@ -906,6 +897,14 @@ void DebuggerManager::exitDebugger() emit debuggingFinished(); } +void DebuggerManager::notifyEngineFinished() +{ + cleanupViews(); + setStatus(DebuggerProcessNotReady); + setBusyCursor(false); + emit debuggingFinished(); +} + DebuggerStartParametersPtr DebuggerManager::startParameters() const { return m_startParameters; @@ -1004,9 +1003,7 @@ void DebuggerManager::executeDebuggerCommand() void DebuggerManager::executeDebuggerCommand(const QString &command) { - if (Debugger::Constants::Internal::debug) - qDebug() << Q_FUNC_INFO <<command; - + STATE_DEBUG(command); QTC_ASSERT(m_engine, return); m_engine->executeDebuggerCommand(command); } @@ -1074,9 +1071,7 @@ void DebuggerManager::addToWatchWindow() void DebuggerManager::setBreakpoint(const QString &fileName, int lineNumber) { - if (Debugger::Constants::Internal::debug) - qDebug() << Q_FUNC_INFO << fileName << lineNumber; - + STATE_DEBUG(Q_FUNC_INFO << fileName << lineNumber); QTC_ASSERT(m_breakHandler, return); m_breakHandler->setBreakpoint(fileName, lineNumber); attemptBreakpointSynchronization(); @@ -1114,14 +1109,13 @@ static bool isAllowedTransition(int from, int to) void DebuggerManager::setStatus(int status) { - if (Debugger::Constants::Internal::debug) - qDebug() << Q_FUNC_INFO << "STATUS CHANGE: from" << stateName(m_status) - << "to" << stateName(status); + STATE_DEBUG("STATUS CHANGE: FROM " << stateName(m_status) + << " TO " << stateName(status)); if (status == m_status) return; - if (1 && !isAllowedTransition(m_status, status)) { + if (!isAllowedTransition(m_status, status)) { const QString msg = QString::fromLatin1("%1: UNEXPECTED TRANSITION: %2 -> %3") .arg(_(Q_FUNC_INFO), _(stateName(m_status)), _(stateName(status))); qWarning("%s", qPrintable(msg)); @@ -1138,6 +1132,10 @@ void DebuggerManager::setStatus(int status) const bool ready = status == DebuggerInferiorStopped && m_startParameters->startMode != AttachCore; + + STATE_DEBUG("STARTED: " << started << " RUNNING: " << running + << " READY: " << ready); + if (ready) QApplication::alert(mainWindow(), 3000); @@ -1171,7 +1169,7 @@ void DebuggerManager::setStatus(int status) void DebuggerManager::setBusyCursor(bool busy) { - //qDebug() << "BUSY FROM: " << m_busy << " TO: " << m_busy; + //STATE_DEBUG("BUSY FROM: " << m_busy << " TO: " << m_busy); if (busy == m_busy) return; m_busy = busy; @@ -1209,8 +1207,7 @@ void DebuggerManager::detachDebugger() void DebuggerManager::interruptDebuggingRequest() { - if (Debugger::Constants::Internal::debug) - qDebug() << Q_FUNC_INFO << status(); + STATE_DEBUG(status()); if (!m_engine) return; bool interruptIsExit = (status() != DebuggerInferiorRunning); @@ -1228,8 +1225,7 @@ void DebuggerManager::runToLineExec() int lineNumber = -1; emit currentTextEditorRequested(&fileName, &lineNumber, 0); if (m_engine && !fileName.isEmpty()) { - if (Debugger::Constants::Internal::debug) - qDebug() << Q_FUNC_INFO << fileName << lineNumber; + STATE_DEBUG(fileName << lineNumber); m_engine->runToLineExec(fileName, lineNumber); } } @@ -1261,8 +1257,7 @@ void DebuggerManager::runToFunctionExec() } } } - if (Debugger::Constants::Internal::debug) - qDebug() << Q_FUNC_INFO << functionName; + STATE_DEBUG(functionName); if (m_engine && !functionName.isEmpty()) m_engine->runToFunctionExec(functionName); @@ -1274,8 +1269,7 @@ void DebuggerManager::jumpToLineExec() int lineNumber = -1; emit currentTextEditorRequested(&fileName, &lineNumber, 0); if (m_engine && !fileName.isEmpty()) { - if (Debugger::Constants::Internal::debug) - qDebug() << Q_FUNC_INFO << fileName << lineNumber; + STATE_DEBUG(fileName << lineNumber); m_engine->jumpToLineExec(fileName, lineNumber); } } @@ -1412,8 +1406,10 @@ QString DebuggerManager::qtDumperLibraryName() const QStringList DebuggerManager::qtDumperLibraryLocations() const { if (theDebuggerAction(UseCustomDebuggingHelperLocation)->value().toBool()) { - const QString customLocation = theDebuggerAction(CustomDebuggingHelperLocation)->value().toString(); - const QString location = tr("%1 (explicitly set in the Debugger Options)").arg(customLocation); + const QString customLocation = + theDebuggerAction(CustomDebuggingHelperLocation)->value().toString(); + const QString location = + tr("%1 (explicitly set in the Debugger Options)").arg(customLocation); return QStringList(location); } return m_startParameters->dumperLibraryLocations; @@ -1422,9 +1418,12 @@ QStringList DebuggerManager::qtDumperLibraryLocations() const void DebuggerManager::showQtDumperLibraryWarning(const QString &details) { QMessageBox dialog(mainWindow()); - QPushButton *qtPref = dialog.addButton(tr("Open Qt preferences"), QMessageBox::ActionRole); - QPushButton *helperOff = dialog.addButton(tr("Turn helper usage off"), QMessageBox::ActionRole); - QPushButton *justContinue = dialog.addButton(tr("Continue anyway"), QMessageBox::AcceptRole); + QPushButton *qtPref = dialog.addButton(tr("Open Qt preferences"), + QMessageBox::ActionRole); + QPushButton *helperOff = dialog.addButton(tr("Turn helper usage off"), + QMessageBox::ActionRole); + QPushButton *justContinue = dialog.addButton(tr("Continue anyway"), + QMessageBox::AcceptRole); dialog.setDefaultButton(justContinue); dialog.setWindowTitle(tr("Debugging helper missing")); dialog.setText(tr("The debugger did not find the debugging helper library.")); diff --git a/src/plugins/debugger/debuggermanager.h b/src/plugins/debugger/debuggermanager.h index bf51de7822d..4f68df9c8f9 100644 --- a/src/plugins/debugger/debuggermanager.h +++ b/src/plugins/debugger/debuggermanager.h @@ -227,6 +227,7 @@ private: virtual void notifyInferiorRunning() = 0; virtual void notifyInferiorExited() = 0; virtual void notifyInferiorPidChanged(qint64) = 0; + virtual void notifyEngineFinished() {} // FIXME: make pure virtual ModulesHandler *modulesHandler() = 0; virtual BreakHandler *breakHandler() = 0; @@ -374,6 +375,7 @@ private: void notifyInferiorRunning(); void notifyInferiorExited(); void notifyInferiorPidChanged(qint64); + void notifyEngineFinished(); void cleanupViews(); @@ -395,9 +397,6 @@ public: // stuff in this block should be made private by moving it to // one of the interfaces int status() const { return m_status; } - // FIXME: hide this in the engines? - //DebuggerStartMode startMode() const; - QList<Symbol> moduleSymbols(const QString &moduleName); signals: diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index f01d9b569d0..6864fbccdf0 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -453,19 +453,19 @@ void DebuggerPlugin::shutdown() m_manager = 0; } -static inline QString msgParameterMissing(const QString &a) +static QString msgParameterMissing(const QString &a) { return DebuggerPlugin::tr("Option '%1' is missing the parameter.").arg(a); } -static inline QString msgInvalidNumericParameter(const QString &a, const QString &number) +static QString msgInvalidNumericParameter(const QString &a, const QString &number) { return DebuggerPlugin::tr("The parameter '%1' of option '%2' is not a number.").arg(number, a); } // Parse arguments bool DebuggerPlugin::parseArgument(QStringList::const_iterator &it, - const QStringList::const_iterator& cend, + const QStringList::const_iterator &cend, QString *errorMessage) { const QString &option = *it; @@ -529,7 +529,9 @@ bool DebuggerPlugin::parseArguments(const QStringList &args, QString *errorMessa if (!parseArgument(it, cend, errorMessage)) return false; if (Debugger::Constants::Internal::debug) - qDebug().nospace() << args << "engines=0x" << QString::number(m_cmdLineEnabledEngines, 16) << " pid" << m_cmdLineAttachPid << '\n'; + qDebug().nospace() << args << "engines=0x" + << QString::number(m_cmdLineEnabledEngines, 16) + << " pid" << m_cmdLineAttachPid << '\n'; return true; } @@ -537,13 +539,15 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess { // Do not fail the whole plugin if something goes wrong here if (!parseArguments(arguments, errorMessage)) { - *errorMessage = tr("Error evaluating command line arguments: %1").arg(*errorMessage); + *errorMessage = tr("Error evaluating command line arguments: %1") + .arg(*errorMessage); qWarning("%s\n", qPrintable(*errorMessage)); errorMessage->clear(); } m_manager = new DebuggerManager; - const QList<Core::IOptionsPage *> engineOptionPages = m_manager->initializeEngines(m_cmdLineEnabledEngines); + const QList<Core::IOptionsPage *> engineOptionPages = + m_manager->initializeEngines(m_cmdLineEnabledEngines); ICore *core = ICore::instance(); QTC_ASSERT(core, return false); @@ -889,9 +893,6 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess this, SLOT(activatePreviousMode())); connect(m_manager, SIGNAL(debugModeRequested()), this, SLOT(activateDebugMode())); - connect(m_manager, SIGNAL(statusChanged(int)), - this, SLOT(updateActions(int))); - connect(theDebuggerAction(SettingsDialog), SIGNAL(triggered()), this, SLOT(showSettingsDialog())); @@ -1112,7 +1113,7 @@ void DebuggerPlugin::gotoLocation(const StackFrame &frame, bool setMarker) void DebuggerPlugin::changeStatus(int status) { - bool startIsContinue = (status == DebuggerInferiorStopped); + const bool startIsContinue = (status == DebuggerInferiorStopped); ICore *core = ICore::instance(); if (startIsContinue) { core->addAdditionalContext(m_gdbRunningContext); @@ -1121,6 +1122,27 @@ void DebuggerPlugin::changeStatus(int status) core->removeAdditionalContext(m_gdbRunningContext); core->updateContext(); } + + const bool started = status == DebuggerInferiorRunning + || status == DebuggerInferiorRunningRequested + || status == DebuggerInferiorStopRequested + || status == DebuggerInferiorStopped; + + const bool starting = status == DebuggerProcessStartingUp; + //const bool running = status == DebuggerInferiorRunning; + + const bool ready = status == DebuggerInferiorStopped + && m_manager->startParameters()->startMode != AttachCore; + + m_startExternalAction->setEnabled(!started && !starting); + m_attachExternalAction->setEnabled(!started && !starting); +#ifdef Q_OS_WIN + m_attachCoreAction->setEnabled(false); +#else + m_attachCoreAction->setEnabled(!started && !starting); +#endif + m_startRemoteAction->setEnabled(!started && !starting); + m_detachAction->setEnabled(ready); } void DebuggerPlugin::writeSettings() const @@ -1337,29 +1359,6 @@ void DebuggerPlugin::attachRemoteTcf() runControl->start(); } -void DebuggerPlugin::updateActions(int status) -{ - const bool started = status == DebuggerInferiorRunning - || status == DebuggerInferiorRunningRequested - || status == DebuggerInferiorStopRequested - || status == DebuggerInferiorStopped; - - const bool starting = status == DebuggerProcessStartingUp; - //const bool running = status == DebuggerInferiorRunning; - - const bool ready = status == DebuggerInferiorStopped - && m_manager->startParameters()->startMode != AttachCore; - m_startExternalAction->setEnabled(!started && !starting); - m_attachExternalAction->setEnabled(!started && !starting); -#ifdef Q_OS_WIN - m_attachCoreAction->setEnabled(false); -#else - m_attachCoreAction->setEnabled(!started && !starting); -#endif - m_startRemoteAction->setEnabled(!started && !starting); - m_detachAction->setEnabled(ready); -} - #include "debuggerplugin.moc" Q_EXPORT_PLUGIN(DebuggerPlugin) diff --git a/src/plugins/debugger/debuggerplugin.h b/src/plugins/debugger/debuggerplugin.h index a4cf504412d..1beefb56319 100644 --- a/src/plugins/debugger/debuggerplugin.h +++ b/src/plugins/debugger/debuggerplugin.h @@ -94,7 +94,6 @@ private slots: void setConfigValue(const QString &name, const QVariant &value); void requestContextMenu(TextEditor::ITextEditor *editor, int lineNumber, QMenu *menu); - void updateActions(int status); void resetLocation(); void gotoLocation(const StackFrame &frame, bool setMarker); diff --git a/src/plugins/debugger/gdb/abstractgdbadapter.h b/src/plugins/debugger/gdb/abstractgdbadapter.h index 5f055ddfcf3..9819c4aafc4 100644 --- a/src/plugins/debugger/gdb/abstractgdbadapter.h +++ b/src/plugins/debugger/gdb/abstractgdbadapter.h @@ -87,8 +87,7 @@ public: virtual void interruptInferior() = 0; virtual void shutdown() = 0; - virtual const DebuggerStartParameters &startParameters() const - { return m_engine->startParameters(); } + virtual bool dumpersAvailable() const = 0; signals: void adapterStarted(); @@ -111,9 +110,14 @@ signals: void readyReadStandardError(); public: - virtual GdbAdapterState state() const { return m_state; } + GdbAdapterState state() const { return m_state; } + // Called by GdbEngine::handleAsyncOutput + void notifyInferiorExited(); + protected: - virtual void setState(GdbAdapterState state) { m_state = state; } + void setState(GdbAdapterState state); + const DebuggerStartParameters &startParameters() const + { return m_engine->startParameters(); } GdbEngine * const m_engine; GdbAdapterState m_state; diff --git a/src/plugins/debugger/gdb/attachgdbadapter.h b/src/plugins/debugger/gdb/attachgdbadapter.h index 6bedcbfc002..066473c9bbc 100644 --- a/src/plugins/debugger/gdb/attachgdbadapter.h +++ b/src/plugins/debugger/gdb/attachgdbadapter.h @@ -59,6 +59,7 @@ private: void setWorkingDirectory(const QString &dir) { m_gdbProc.setWorkingDirectory(dir); } void setEnvironment(const QStringList &env) { m_gdbProc.setEnvironment(env); } bool isTrkAdapter() const { return false; } + bool dumpersAvailable() const { return false; } void startAdapter(); void prepareInferior(); diff --git a/src/plugins/debugger/gdb/coregdbadapter.h b/src/plugins/debugger/gdb/coregdbadapter.h index 152c9bebf57..45c623b35ca 100644 --- a/src/plugins/debugger/gdb/coregdbadapter.h +++ b/src/plugins/debugger/gdb/coregdbadapter.h @@ -59,6 +59,7 @@ private: void setWorkingDirectory(const QString &dir) { m_gdbProc.setWorkingDirectory(dir); } void setEnvironment(const QStringList &env) { m_gdbProc.setEnvironment(env); } bool isTrkAdapter() const { return false; } + bool dumpersAvailable() const { return false; } void startAdapter(); void prepareInferior(); diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index ae532e2da69..9116c4d47dc 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -271,45 +271,12 @@ void GdbEngine::connectAdapter() this, SLOT(handleInferiorShutdownFailed(QString))); connect(m_gdbAdapter, SIGNAL(adapterCrashed()), - m_manager, SLOT(exitDebugger())); + this, SLOT(handleAdapterCrashed())); } - void GdbEngine::disconnectAdapter() { - // Gdb Process interaction - disconnect(m_gdbAdapter, SIGNAL(error(QProcess::ProcessError)), - this, SLOT(gdbProcError(QProcess::ProcessError))); - disconnect(m_gdbAdapter, SIGNAL(readyReadStandardOutput()), - this, SLOT(readGdbStandardOutput())); - disconnect(m_gdbAdapter, SIGNAL(readyReadStandardError()), - this, SLOT(readGdbStandardError())); - - disconnect(m_gdbAdapter, SIGNAL(adapterStarted()), - this, SLOT(handleAdapterStarted())); - disconnect(m_gdbAdapter, SIGNAL(adapterStartFailed(QString)), - this, SLOT(handleAdapterStartFailed(QString))); - disconnect(m_gdbAdapter, SIGNAL(adapterShutDown()), - this, SLOT(handleAdapterShutDown())); - disconnect(m_gdbAdapter, SIGNAL(adapterShutdownFailed(QString)), - this, SLOT(handleAdapterShutdownFailed(QString))); - - disconnect(m_gdbAdapter, SIGNAL(inferiorPrepared()), - this, SLOT(handleInferiorPrepared())); - disconnect(m_gdbAdapter, SIGNAL(inferiorPreparationFailed(QString)), - this, SLOT(handleInferiorPreparationFailed(QString))); - - disconnect(m_gdbAdapter, SIGNAL(inferiorStarted()), - this, SLOT(handleInferiorStarted())); - disconnect(m_gdbAdapter, SIGNAL(inferiorStartFailed(QString)), - this, SLOT(handleInferiorStartFailed(QString))); - disconnect(m_gdbAdapter, SIGNAL(inferiorShutDown()), - this, SLOT(handleInferiorShutDown())); - disconnect(m_gdbAdapter, SIGNAL(inferiorShutdownFailed(QString)), - this, SLOT(handleInferiorShutdownFailed(QString))); - - disconnect(m_gdbAdapter, SIGNAL(adapterCrashed()), - m_manager, SLOT(exitDebugger())); + disconnect(m_gdbAdapter, 0, this, 0); } void GdbEngine::initializeVariables() @@ -386,9 +353,7 @@ void GdbEngine::gdbProcError(QProcess::ProcessError error) showStatusMessage(msg); showMessageBox(QMessageBox::Critical, tr("Error"), msg); - // act as if it was closed by the core - //if (kill) - m_manager->exitDebugger(); + shutdown(); } #if 0 @@ -696,7 +661,7 @@ void GdbEngine::interruptInferior() if (m_gdbAdapter->state() == AdapterNotRunning) { debugMessage(_("TRYING TO INTERRUPT INFERIOR WITHOUT RUNNING GDB")); - qq->notifyInferiorExited(); + shutdown(); return; } @@ -833,7 +798,7 @@ void GdbEngine::handleResultRecord(const GdbResultRecord &record) showMessageBox(QMessageBox::Critical, tr("Executable failed"), QString::fromLocal8Bit(msg)); showStatusMessage(tr("Process failed to start.")); - exitDebugger(); + shutdown(); } return; } @@ -1100,7 +1065,7 @@ void GdbEngine::handleAqcuiredInferior() } #endif - // nicer to see a bit of the world we live in + // It's nicer to see a bit of the world we live in. reloadModules(); attemptBreakpointSynchronization(); } @@ -1110,19 +1075,21 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data) const QByteArray reason = data.findChild("reason").data(); if (isExitedReason(reason)) { - qq->notifyInferiorExited(); + // Give adapter a chance to take notice of regular exits. + m_gdbAdapter->notifyInferiorExited(); + QString msg; if (reason == "exited") { - msg = tr("Program exited with exit code %1") + msg = tr("Program exited with exit code %1.") .arg(_(data.findChild("exit-code").toString())); } else if (reason == "exited-signalled" || reason == "signal-received") { - msg = tr("Program exited after receiving signal %1") + msg = tr("Program exited after receiving signal %1.") .arg(_(data.findChild("signal-name").toString())); } else { - msg = tr("Program exited normally"); + msg = tr("Program exited normally."); } showStatusMessage(msg); - postCommand(_("-gdb-exit"), CB(handleExit)); + shutdown(); return; } @@ -1421,7 +1388,7 @@ void GdbEngine::handleFileExecAndSymbols(const GdbResultRecord &response, const showMessageBox(QMessageBox::Critical, tr("Starting executable failed"), msg); QTC_ASSERT(status() == DebuggerInferiorRunning, /**/); //interruptInferior(); - qq->notifyInferiorExited(); + shutdown(); } } @@ -1441,7 +1408,7 @@ void GdbEngine::handleExecContinue(const GdbResultRecord &response, const QVaria showMessageBox(QMessageBox::Critical, tr("Error"), tr("Starting executable failed:\n") + QString::fromLocal8Bit(msg)); QTC_ASSERT(status() == DebuggerInferiorRunning, /**/); - qq->notifyInferiorExited(); + shutdown(); } } } @@ -1484,6 +1451,7 @@ QString GdbEngine::fullName(const QStringList &candidates) void GdbEngine::shutdown() { + debugMessage(_("INITIATE GDBENGINE SHUTDOWN")); m_outputCollector.shutdown(); initializeVariables(); m_gdbAdapter->shutdown(); @@ -1495,7 +1463,7 @@ void GdbEngine::detachDebugger() shutdown(); } -void GdbEngine::exitDebugger() +void GdbEngine::exitDebugger() // called from the manager { disconnectDebuggingHelperActions(); m_outputCollector.shutdown(); @@ -1517,8 +1485,6 @@ void GdbEngine::startDebugger(const DebuggerStartParametersPtr &sp) //QTC_ASSERT(m_gdbAdapter == 0, delete m_gdbAdapter; m_gdbAdapter = 0); m_startParameters = sp; - if (startModeAllowsDumpers()) - connectDebuggingHelperActions(); if (m_gdbAdapter) disconnectAdapter(); @@ -1534,6 +1500,9 @@ void GdbEngine::startDebugger(const DebuggerStartParametersPtr &sp) else m_gdbAdapter = m_plainAdapter; + if (startModeAllowsDumpers()) + connectDebuggingHelperActions(); + initializeVariables(); connectAdapter(); @@ -1620,11 +1589,6 @@ void GdbEngine::handleTargetRemote(const GdbResultRecord &record, const QVariant } #endif -void GdbEngine::handleExit(const GdbResultRecord &, const QVariant &) -{ - showStatusMessage(tr("Debugger exited.")); -} - void GdbEngine::stepExec() { setTokenBarrier(); @@ -2364,7 +2328,10 @@ void GdbEngine::handleStackListFrames(const GdbResultRecord &record, const QVari gotoLocation(frame, true); } } else { - qDebug() << "LISTING STACK FAILED: " << record.toString(); + // That always happens on symbian gdb with + // ^error,data={msg="Previous frame identical to this frame (corrupt stack?)" + // logstreamoutput="Previous frame identical to this frame (corrupt stack?)\n" + //qDebug() << "LISTING STACK FAILED: " << record.toString(); } } @@ -3062,22 +3029,25 @@ void GdbEngine::handleQueryDebuggingHelper(const GdbResultRecord &record, const //qDebug() << "DATA DUMPER TRIAL:" << record.toString(); GdbMi contents; - QTC_ASSERT(parseConsoleStream(record, &contents), /**/); - const bool ok = m_dumperHelper.parseQuery(contents, QtDumperHelper::GdbDebugger) && m_dumperHelper.typeCount(); + QTC_ASSERT(parseConsoleStream(record, &contents), qDebug() << record.toString()); + const bool ok = m_dumperHelper.parseQuery(contents, QtDumperHelper::GdbDebugger) + && m_dumperHelper.typeCount(); if (ok) { // Get version and sizes from dumpers. Expression cache // currently causes errors. const double dumperVersion = getDumperVersion(contents); if (dumperVersion < dumperVersionRequired) { - qq->showQtDumperLibraryWarning(QtDumperHelper::msgDumperOutdated(dumperVersionRequired, dumperVersion)); + qq->showQtDumperLibraryWarning( + QtDumperHelper::msgDumperOutdated(dumperVersionRequired, dumperVersion)); m_debuggingHelperState = DebuggingHelperUnavailable; return; } m_debuggingHelperState = DebuggingHelperAvailable; - const QString successMsg = tr("Dumper version %1, %n custom dumpers found.", 0, m_dumperHelper.typeCount()).arg(dumperVersion); + const QString successMsg = tr("Dumper version %1, %n custom dumpers found.", + 0, m_dumperHelper.typeCount()).arg(dumperVersion); showStatusMessage(successMsg); } else { - if (!m_dumperInjectionLoad) // Retry if thread has not terminated yet. + if (!m_dumperInjectionLoad) // Retry if thread has not terminated yet. m_debuggingHelperState = DebuggingHelperUnavailable; showStatusMessage(tr("Debugging helpers not found.")); } @@ -3816,8 +3786,7 @@ void GdbEngine::recheckDebuggingHelperAvailability() bool GdbEngine::startModeAllowsDumpers() const { - const DebuggerStartMode m = startMode(); - return m == StartInternal || m == StartExternal || m == AttachExternal; + return m_gdbAdapter->dumpersAvailable(); } void GdbEngine::watchPoint(const QPoint &pnt) @@ -4052,8 +4021,7 @@ void GdbEngine::handleAdapterStartFailed(const QString &msg) { debugMessage(_("ADAPTER START FAILED")); showMessageBox(QMessageBox::Critical, tr("Adapter start failed"), msg); - qq->notifyInferiorExited(); - m_manager->exitDebugger(); + shutdown(); } void GdbEngine::handleAdapterStarted() @@ -4069,8 +4037,6 @@ void GdbEngine::handleInferiorPreparationFailed(const QString &msg) showMessageBox(QMessageBox::Critical, tr("Inferior start preparation failed"), msg); shutdown(); - qq->notifyInferiorExited(); - m_manager->exitDebugger(); } void GdbEngine::handleInferiorPrepared() @@ -4203,8 +4169,7 @@ void GdbEngine::handleInferiorStartFailed(const QString &msg) { debugMessage(_("INFERIOR START FAILED")); showMessageBox(QMessageBox::Critical, tr("Inferior start failed"), msg); - qq->notifyInferiorExited(); - m_manager->exitDebugger(); + shutdown(); } void GdbEngine::handleInferiorStarted() @@ -4221,24 +4186,28 @@ void GdbEngine::handleInferiorShutDown() void GdbEngine::handleInferiorShutdownFailed(const QString &msg) { debugMessage(_("INFERIOR SHUTDOWN FAILED")); - showMessageBox(QMessageBox::Critical, - tr("Inferior shutdown failed"), msg); - qq->notifyInferiorExited(); - m_manager->exitDebugger(); + showMessageBox(QMessageBox::Critical, tr("Inferior shutdown failed"), msg); + shutdown(); // continue with adapter shutdown +} + +void GdbEngine::handleAdapterCrashed() +{ + debugMessage(_("ADAPTER CRASHED")); + showMessageBox(QMessageBox::Critical, tr("Adapter crashed"), QString()); + shutdown(); } void GdbEngine::handleAdapterShutDown() { debugMessage(_("ADAPTER SUCCESSFULLY SHUT DOWN")); - qq->notifyInferiorExited(); + qq->notifyEngineFinished(); } void GdbEngine::handleAdapterShutdownFailed(const QString &msg) { debugMessage(_("ADAPTER SHUTDOWN FAILED")); - showMessageBox(QMessageBox::Critical, - tr("Inferior shutdown failed"), msg); - qq->notifyInferiorExited(); + showMessageBox(QMessageBox::Critical, tr("Inferior shutdown failed"), msg); + qq->notifyEngineFinished(); } void GdbEngine::addOptionPages(QList<Core::IOptionsPage*> *opts) const @@ -4253,6 +4222,47 @@ void GdbEngine::showMessageBox(int icon, const QString &title, const QString &te m_manager->showMessageBox(icon, title, text); } +// +// AbstractGdbAdapter +// + +static bool isAllowedTransition(int from, int to) +{ + return (from == -1) + || (from == AdapterNotRunning && to == AdapterNotRunning) + || (from == AdapterNotRunning && to == AdapterStarting) + || (from == AdapterStarting && to == AdapterStarted) + || (from == AdapterStarting && to == AdapterStartFailed) + || (from == AdapterStarted && to == InferiorPreparing) + || (from == InferiorPreparing && to == InferiorPrepared) + || (from == InferiorPreparing && to == InferiorPreparationFailed) + || (from == InferiorPrepared && to == InferiorStarting) + || (from == InferiorStarting && to == InferiorStarted) + || (from == InferiorStarting && to == InferiorStartFailed) + || (from == InferiorStarted && to == InferiorShuttingDown) + || (from == InferiorShuttingDown && to == InferiorShutDown) + || (from == InferiorShuttingDown && to == InferiorShutdownFailed) + || (from == InferiorShutDown && to == AdapterShuttingDown) + || (from == AdapterShuttingDown && to == AdapterNotRunning) + ; +} + +void AbstractGdbAdapter::setState(GdbAdapterState state) +{ + QString msg = _("Adapter state from %1 to state %2.").arg(m_state).arg(state); + if (!isAllowedTransition(m_state, state)) + qDebug() << "UNEXPECTED ADAPTER TRANSITION: " << msg; + m_engine->debugMessage(msg); + m_state = state; +} + +void AbstractGdbAdapter::notifyInferiorExited() +{ + QTC_ASSERT(state() == InferiorStarted, /**/); + setState(InferiorShuttingDown); + setState(InferiorShutDown); +} + // // Factory // diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index d39546f9b81..b24e8dfd5e3 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -247,6 +247,7 @@ private slots: void handleInferiorShutDown(); void handleInferiorShutdownFailed(const QString &msg); + void handleAdapterCrashed(); void handleAdapterShutDown(); void handleAdapterShutdownFailed(const QString &msg); @@ -270,9 +271,6 @@ private: void handleShowVersion(const GdbResultRecord &response, const QVariant &); void handleQueryPwd(const GdbResultRecord &response, const QVariant &); void handleQuerySources(const GdbResultRecord &response, const QVariant &); - void handleExit(const GdbResultRecord &, const QVariant &); - //void handleSetTargetAsync(const GdbResultRecord &, const QVariant &); - //void handleTargetRemote(const GdbResultRecord &, const QVariant &); void handleWatchPoint(const GdbResultRecord &, const QVariant &); bool showToolTip(); diff --git a/src/plugins/debugger/gdb/plaingdbadapter.h b/src/plugins/debugger/gdb/plaingdbadapter.h index f10d822da7f..eff136eaf3d 100644 --- a/src/plugins/debugger/gdb/plaingdbadapter.h +++ b/src/plugins/debugger/gdb/plaingdbadapter.h @@ -60,6 +60,7 @@ public: void setWorkingDirectory(const QString &dir) { m_gdbProc.setWorkingDirectory(dir); } void setEnvironment(const QStringList &env) { m_gdbProc.setEnvironment(env); } bool isTrkAdapter() const { return false; } + bool dumpersAvailable() const { return true; } void startAdapter(); void prepareInferior(); diff --git a/src/plugins/debugger/gdb/remotegdbadapter.h b/src/plugins/debugger/gdb/remotegdbadapter.h index cd15b87e599..613f1fecae6 100644 --- a/src/plugins/debugger/gdb/remotegdbadapter.h +++ b/src/plugins/debugger/gdb/remotegdbadapter.h @@ -59,6 +59,7 @@ private: void setWorkingDirectory(const QString &dir) { m_gdbProc.setWorkingDirectory(dir); } void setEnvironment(const QStringList &env) { m_gdbProc.setEnvironment(env); } bool isTrkAdapter() const { return false; } + bool dumpersAvailable() const { return true; } void startAdapter(); void prepareInferior(); diff --git a/src/plugins/debugger/gdb/trkgdbadapter.cpp b/src/plugins/debugger/gdb/trkgdbadapter.cpp index 05980ba90e5..b2d35ad1b65 100644 --- a/src/plugins/debugger/gdb/trkgdbadapter.cpp +++ b/src/plugins/debugger/gdb/trkgdbadapter.cpp @@ -240,7 +240,7 @@ void TrkGdbAdapter::startInferiorEarly() if (!m_trkDevice.open(device, &errorMessage)) { logMessage(QString::fromLatin1("Waiting on %1 (%2)").arg(device, errorMessage)); // Do not loop forever - if (m_waitCount++ < (m_options->mode == TrkOptions::BlueTooth ? 3 : 5)) { + if (m_waitCount++ < (m_options->mode == TrkOptions::BlueTooth ? 60 : 5)) { QTimer::singleShot(1000, this, SLOT(startInferiorEarly())); } else { QString msg = QString::fromLatin1("Failed to connect to %1 after " @@ -1327,8 +1327,8 @@ void TrkGdbAdapter::handleGdbFinished(int exitCode, QProcess::ExitStatus exitSta { logMessage(QString("GDB: ProcessFinished %1 %2") .arg(exitCode).arg(exitStatus)); - //setState(AdapterNotRunning); - //emit adapterShutDown(); + setState(AdapterNotRunning); + emit adapterShutDown(); } void TrkGdbAdapter::handleGdbStarted() @@ -1395,14 +1395,12 @@ void TrkGdbAdapter::handleTargetRemote(const GdbResultRecord &record, const QVar { QTC_ASSERT(state() == InferiorPreparing, qDebug() << state()); if (record.resultClass == GdbResultDone) { - //postCommand(_("-exec-continue"), CB(handleExecContinue)); setState(InferiorPrepared); emit inferiorPrepared(); } else if (record.resultClass == GdbResultError) { - // 16^error,msg="hd:5555: Connection timed out." - QString msg = __(record.data.findChild("msg").data()); - QString msg1 = tr("Connecting to remote server failed:"); - emit inferiorPreparationFailed(msg1 + _c(' ') + msg); + QString msg = tr("Connecting to trk server adapter failed:\n") + + _(record.data.findChild("msg").data()); + emit inferiorPreparationFailed(msg); } } @@ -1411,14 +1409,17 @@ void TrkGdbAdapter::startInferior() QTC_ASSERT(state() == InferiorPrepared, qDebug() << state()); setState(InferiorStarting); m_engine->postCommand(_("-exec-continue"), CB(handleFirstContinue)); + // FIXME: Is there a way to properly recognize a successful start? + setState(InferiorStarted); + emit inferiorStarted(); } void TrkGdbAdapter::handleFirstContinue(const GdbResultRecord &record, const QVariant &) { - QTC_ASSERT(state() == InferiorStarting, qDebug() << state()); + //QTC_ASSERT(state() == InferiorStarting, qDebug() << state()); + QTC_ASSERT(state() == InferiorStarted, qDebug() << state()); if (record.resultClass == GdbResultDone) { - setState(InferiorStarted); - emit inferiorStarted(); + // inferiorStarted already emitted above, see FIXME } else if (record.resultClass == GdbResultError) { //QString msg = __(record.data.findChild("msg").data()); QString msg1 = tr("Connecting to remote server failed:"); @@ -1589,20 +1590,22 @@ void TrkGdbAdapter::setEnvironment(const QStringList &env) void TrkGdbAdapter::shutdown() { + qDebug() << "ADAPTER SHUTDOWN " << state(); if (state() == InferiorStarted) { setState(InferiorShuttingDown); + qDebug() << "kill"; m_engine->postCommand(_("kill"), CB(handleKill)); return; } if (state() == InferiorShutDown) { setState(AdapterShuttingDown); + qDebug() << "gdb-exit"; m_engine->postCommand(_("-gdb-exit"), CB(handleExit)); return; } QTC_ASSERT(state() == AdapterNotRunning, qDebug() << state()); - emit adapterShutDown(); } void TrkGdbAdapter::handleKill(const GdbResultRecord &response, const QVariant &) @@ -1622,6 +1625,7 @@ void TrkGdbAdapter::handleKill(const GdbResultRecord &response, const QVariant & void TrkGdbAdapter::handleExit(const GdbResultRecord &response, const QVariant &) { if (response.resultClass == GdbResultDone) { + qDebug() << "EXITED, NO MESSAGE..."; // don't set state here, this will be handled in handleGdbFinished() } else if (response.resultClass == GdbResultError) { QString msg = tr("Gdb process could not be stopped:\n") + diff --git a/src/plugins/debugger/gdb/trkgdbadapter.h b/src/plugins/debugger/gdb/trkgdbadapter.h index 7c6ecda322a..80874ddf6ed 100644 --- a/src/plugins/debugger/gdb/trkgdbadapter.h +++ b/src/plugins/debugger/gdb/trkgdbadapter.h @@ -114,6 +114,7 @@ public: void setWorkingDirectory(const QString &dir); void setEnvironment(const QStringList &env); bool isTrkAdapter() const { return true; } + bool dumpersAvailable() const { return false; } void startAdapter(); void prepareInferior(); -- GitLab