From 93902e5d0a9fb0ec2ab7790a3aa272c5eaf87910 Mon Sep 17 00:00:00 2001 From: hjk <qtc-committer@nokia.com> Date: Wed, 30 Sep 2009 12:27:03 +0200 Subject: [PATCH] debugger: make 'qtcreator -debug <corefile>' work --- src/plugins/debugger/Debugger.pluginspec | 2 +- src/plugins/debugger/debuggermanager.cpp | 4 +- src/plugins/debugger/debuggeroutputwindow.h | 2 +- src/plugins/debugger/debuggerplugin.cpp | 26 ++++++-- src/plugins/debugger/debuggerplugin.h | 3 + src/plugins/debugger/gdb/coregdbadapter.cpp | 69 ++++++++++++-------- src/plugins/debugger/gdb/coregdbadapter.h | 1 + src/plugins/debugger/gdb/gdbengine.cpp | 11 +++- src/plugins/debugger/gdb/gdbengine.h | 1 + src/plugins/debugger/gdb/plaingdbadapter.cpp | 2 +- src/plugins/debugger/gdb/trkgdbadapter.cpp | 2 +- 11 files changed, 82 insertions(+), 41 deletions(-) diff --git a/src/plugins/debugger/Debugger.pluginspec b/src/plugins/debugger/Debugger.pluginspec index a410898c925..a1f207a13dd 100644 --- a/src/plugins/debugger/Debugger.pluginspec +++ b/src/plugins/debugger/Debugger.pluginspec @@ -29,7 +29,7 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> <argument name="-disable-gdb">Disable Gdb debugger engine</argument> <argument name="-disable-sdb">Disable Qt Script debugger engine</argument> <argument name="-disable-tcf">Disable Tcf debugger engine</argument> - <argument name="-debug" parameter="process-id">Attach to Process-Id</argument> + <argument name="-debug" parameter="pid-or-corefile">Attach to Process-Id or Core file</argument> <argument name="-wincrashevent" parameter="event-handle">Event handle used for attaching to crashed processes</argument> </argumentList> </plugin> diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp index f03afc166e8..76dfff70a4e 100644 --- a/src/plugins/debugger/debuggermanager.cpp +++ b/src/plugins/debugger/debuggermanager.cpp @@ -1698,7 +1698,9 @@ void DebuggerManager::setState(DebuggerState state) //showStatusMessage(QString("stoppable: %1, running: %2") // .arg(stoppable).arg(running)); emit stateChanged(d->m_state); - const bool notbusy = stopped || state == DebuggerNotReady; + const bool notbusy = state == InferiorStopped + || state == DebuggerNotReady + || state == InferiorUnrunnable; setBusyCursor(!notbusy); } diff --git a/src/plugins/debugger/debuggeroutputwindow.h b/src/plugins/debugger/debuggeroutputwindow.h index be87d6d1f15..c67719a4bd9 100644 --- a/src/plugins/debugger/debuggeroutputwindow.h +++ b/src/plugins/debugger/debuggeroutputwindow.h @@ -31,8 +31,8 @@ #define DEBUGGER_OUTPUTWINDOW_H #include <QtGui/QLineEdit> -#include <QtGui/QSplitter> #include <QtGui/QPlainTextEdit> +#include <QtGui/QSplitter> #include <QtGui/QWidget> namespace Debugger { diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index e8a71ee4df5..4efc857d1f1 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -478,8 +478,8 @@ bool DebuggerPlugin::parseArgument(QStringList::const_iterator &it, bool ok; m_cmdLineAttachPid = it->toULongLong(&ok); if (!ok) { - *errorMessage = msgInvalidNumericParameter(option, *it); - return false; + m_cmdLineAttachPid = 0; + m_cmdLineAttachCore = *it; } return true; } @@ -530,7 +530,8 @@ bool DebuggerPlugin::parseArguments(const QStringList &args, QString *errorMessa if (Debugger::Constants::Internal::debug) qDebug().nospace() << args << "engines=0x" << QString::number(m_cmdLineEnabledEngines, 16) - << " pid" << m_cmdLineAttachPid << '\n'; + << " pid" << m_cmdLineAttachPid + << " core" << m_cmdLineAttachCore << '\n'; return true; } @@ -909,6 +910,8 @@ void DebuggerPlugin::extensionsInitialized() m_manager->runTest(QString::fromLocal8Bit(env)); if (m_cmdLineAttachPid) QTimer::singleShot(0, this, SLOT(attachCmdLinePid())); + if (!m_cmdLineAttachCore.isEmpty()) + QTimer::singleShot(0, this, SLOT(attachCmdLineCore())); } void DebuggerPlugin::attachCmdLinePid() @@ -1249,9 +1252,14 @@ void DebuggerPlugin::attachExternalApplication(qint64 pid, const QString &crashP runControl->start(); } +void DebuggerPlugin::attachCmdLineCore() +{ + m_manager->showStatusMessage(tr("Attaching to core %1.").arg(m_cmdLineAttachCore)); + attachCore(m_cmdLineAttachCore, QString()); +} + void DebuggerPlugin::attachCore() { - const DebuggerStartParametersPtr sp(new DebuggerStartParameters); AttachCoreDialog dlg(m_manager->mainWindow()); dlg.setExecutableFile( configValue(_("LastExternalExecutableFile")).toString()); @@ -1263,8 +1271,14 @@ void DebuggerPlugin::attachCore() dlg.executableFile()); setConfigValue(_("LastExternalCoreFile"), dlg.coreFile()); - sp->executable = dlg.executableFile(); - sp->coreFile = dlg.coreFile(); + attachCore(dlg.coreFile(), dlg.executableFile()); +} + +void DebuggerPlugin::attachCore(const QString &core, const QString &exe) +{ + const DebuggerStartParametersPtr sp(new DebuggerStartParameters); + sp->executable = exe; + sp->coreFile = core; sp->startMode = AttachCore; RunConfigurationPtr rc = activeRunConfiguration(); if (rc.isNull()) diff --git a/src/plugins/debugger/debuggerplugin.h b/src/plugins/debugger/debuggerplugin.h index dd5fea2efa7..4ef8b59353f 100644 --- a/src/plugins/debugger/debuggerplugin.h +++ b/src/plugins/debugger/debuggerplugin.h @@ -108,6 +108,7 @@ private slots: void attachCore(); void attachRemoteTcf(); void attachCmdLinePid(); + void attachCmdLineCore(); private: void readSettings(); @@ -117,6 +118,7 @@ private: const QStringList::const_iterator& end, QString *errorMessage); void attachExternalApplication(qint64 pid, const QString &crashParameter = QString()); + void attachCore(const QString &core, const QString &exeFileName); friend class Debugger::DebuggerManager; friend class GdbOptionPage; @@ -132,6 +134,7 @@ private: int m_gdbRunningContext; unsigned m_cmdLineEnabledEngines; quint64 m_cmdLineAttachPid; + QString m_cmdLineAttachCore; // Event handle for attaching to crashed Windows processes. quint64 m_cmdLineWinCrashEvent; QAction *m_toggleLockedAction; diff --git a/src/plugins/debugger/gdb/coregdbadapter.cpp b/src/plugins/debugger/gdb/coregdbadapter.cpp index 106b1b097ae..9c4585791ca 100644 --- a/src/plugins/debugger/gdb/coregdbadapter.cpp +++ b/src/plugins/debugger/gdb/coregdbadapter.cpp @@ -112,36 +112,16 @@ void CoreGdbAdapter::prepareInferior() { QTC_ASSERT(state() == AdapterStarted, qDebug() << state()); setState(InferiorPreparing); - if (!startParameters().processArgs.isEmpty()) - m_engine->postCommand(_("-exec-arguments ") - + startParameters().processArgs.join(_(" "))); - QFileInfo fi(m_engine->startParameters().executable); - m_engine->postCommand(_("-file-exec-and-symbols \"%1\"").arg(fi.absoluteFilePath()), - CB(handleFileExecAndSymbols)); -} - -void CoreGdbAdapter::handleFileExecAndSymbols(const GdbResponse &response) -{ - QTC_ASSERT(state() == InferiorPreparing, qDebug() << state()); - if (response.resultClass == GdbResultDone) { - //m_breakHandler->clearBreakMarkers(); - setState(InferiorPrepared); - emit inferiorPrepared(); - } else if (response.resultClass == GdbResultError) { - QString msg = tr("Starting executable failed:\n") + - __(response.data.findChild("msg").data()); - setState(InferiorPreparationFailed); - emit inferiorPreparationFailed(msg); - } + setState(InferiorPrepared); + emit inferiorPrepared(); } void CoreGdbAdapter::startInferior() { QTC_ASSERT(state() == InferiorStarting, qDebug() << state()); - QFileInfo fi(startParameters().executable); - QString fileName = _c('"') + fi.absoluteFilePath() + _c('"'); QFileInfo fi2(startParameters().coreFile); // quoting core name below fails in gdb 6.8-debian + m_executable.clear(); QString coreName = fi2.absoluteFilePath(); m_engine->postCommand(_("target core ") + coreName, CB(handleTargetCore)); } @@ -150,9 +130,18 @@ void CoreGdbAdapter::handleTargetCore(const GdbResponse &response) { QTC_ASSERT(state() == InferiorStarting, qDebug() << state()); if (response.resultClass == GdbResultDone) { - setState(InferiorUnrunnable); showStatusMessage(tr("Attached to core.")); - m_engine->updateAll(); + m_executable = startParameters().executable; + if (m_executable.isEmpty()) { + GdbMi console = response.data.findChild("consolestreamoutput"); + int pos1 = console.data().indexOf('`'); + int pos2 = console.data().indexOf('\''); + if (pos1 != -1 && pos2 != -1) + m_executable = console.data().mid(pos1 + 1, pos2 - pos1 - 1); + } + QFileInfo fi(m_executable); + m_engine->postCommand(_("-file-exec-and-symbols \"%1\"") + .arg(fi.absoluteFilePath()), CB(handleFileExecAndSymbols)); } else { QTC_ASSERT(response.resultClass == GdbResultError, /**/); const QByteArray &msg = response.data.findChild("msg").data(); @@ -161,6 +150,23 @@ void CoreGdbAdapter::handleTargetCore(const GdbResponse &response) } } +void CoreGdbAdapter::handleFileExecAndSymbols(const GdbResponse &response) +{ + QTC_ASSERT(state() == InferiorStarting, qDebug() << state()); + if (response.resultClass == GdbResultDone) { + showStatusMessage(tr("Symbols found.")); + setState(InferiorUnrunnable); + m_engine->updateAll(); + } else if (response.resultClass == GdbResultError) { + QString msg = tr("Symbols not found in \"%1\" failed:\n%2") + .arg(__(response.data.findChild("msg").data())); + setState(InferiorUnrunnable); + m_engine->updateAll(); + //setState(InferiorStartFailed); + // emit inferiorStartFailed(msg); + } +} + void CoreGdbAdapter::interruptInferior() { // A core should never 'run' @@ -169,12 +175,21 @@ void CoreGdbAdapter::interruptInferior() void CoreGdbAdapter::shutdown() { - if (state() == InferiorUnrunnable || state() == InferiorShutDown) { + switch (state()) { + + case DebuggerNotReady: + return; + + case InferiorUnrunnable: + case InferiorShutDown: + case InferiorPreparationFailed: setState(AdapterShuttingDown); m_engine->postCommand(_("-gdb-exit"), CB(handleExit)); return; + + default: + QTC_ASSERT(false, qDebug() << state()); } - QTC_ASSERT(state() == DebuggerNotReady, qDebug() << state()); } void CoreGdbAdapter::handleExit(const GdbResponse &response) diff --git a/src/plugins/debugger/gdb/coregdbadapter.h b/src/plugins/debugger/gdb/coregdbadapter.h index c432b622751..8cb74db99df 100644 --- a/src/plugins/debugger/gdb/coregdbadapter.h +++ b/src/plugins/debugger/gdb/coregdbadapter.h @@ -76,6 +76,7 @@ private: Q_SLOT void handleGdbFinished(int, QProcess::ExitStatus); QProcess m_gdbProc; + QString m_executable; }; } // namespace Internal diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index fac5fe587a8..ba15808f918 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -881,16 +881,21 @@ void GdbEngine::executeDebuggerCommand(const QString &command) void GdbEngine::updateAll() { QTC_ASSERT(state() == InferiorUnrunnable || state() == InferiorStopped, /**/); - manager()->resetLocation(); tryLoadDebuggingHelpers(); - manager()->stackHandler()->setCurrentIndex(0); updateLocals(); - reloadStack(); + postCommand(_("-stack-list-frames"), WatchUpdate, CB(handleStackListFrames1), false); + manager()->stackHandler()->setCurrentIndex(0); if (supportsThreads()) postCommand(_("-thread-list-ids"), WatchUpdate, CB(handleStackListThreads), 0); manager()->reloadRegisters(); } +void GdbEngine::handleStackListFrames1(const GdbResponse &response) +{ + handleStackListFrames(response); + manager()->gotoLocation(manager()->stackHandler()->currentFrame(), true); +} + void GdbEngine::handleQuerySources(const GdbResponse &response) { if (response.resultClass == GdbResultDone) { diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index 4af8cc644cc..e6775a4d406 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -338,6 +338,7 @@ private: // Stack specific stuff // void handleStackListFrames(const GdbResponse &response); + void handleStackListFrames1(const GdbResponse &response); void handleStackSelectThread(const GdbResponse &response); void handleStackListThreads(const GdbResponse &response); Q_SLOT void reloadStack(); diff --git a/src/plugins/debugger/gdb/plaingdbadapter.cpp b/src/plugins/debugger/gdb/plaingdbadapter.cpp index a7b92ae92a0..5d5e051c83b 100644 --- a/src/plugins/debugger/gdb/plaingdbadapter.cpp +++ b/src/plugins/debugger/gdb/plaingdbadapter.cpp @@ -144,7 +144,7 @@ void PlainGdbAdapter::prepareInferior() if (!startParameters().processArgs.isEmpty()) m_engine->postCommand(_("-exec-arguments ") + startParameters().processArgs.join(_(" "))); - QFileInfo fi(m_engine->startParameters().executable); + QFileInfo fi(startParameters().executable); m_engine->postCommand(_("-file-exec-and-symbols \"%1\"").arg(fi.absoluteFilePath()), CB(handleFileExecAndSymbols)); } diff --git a/src/plugins/debugger/gdb/trkgdbadapter.cpp b/src/plugins/debugger/gdb/trkgdbadapter.cpp index 3aa068362a9..604c4a205ee 100644 --- a/src/plugins/debugger/gdb/trkgdbadapter.cpp +++ b/src/plugins/debugger/gdb/trkgdbadapter.cpp @@ -1411,7 +1411,7 @@ void TrkGdbAdapter::handleGdbStateChanged(QProcess::ProcessState newState) void TrkGdbAdapter::startAdapter() { // Retrieve parameters - const DebuggerStartParameters ¶meters = m_engine->startParameters(); + const DebuggerStartParameters ¶meters = startParameters(); setOverrideTrkDevice(parameters.remoteChannel); m_remoteExecutable = parameters.executable; m_symbolFile = parameters.symbolFileName; -- GitLab