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.
Disable Gdb debugger engine
Disable Qt Script debugger engine
Disable Tcf debugger engine
- Attach to Process-Id
+ Attach to Process-Id or Core file
Event handle used for attaching to crashed processes
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
-#include
#include
+#include
#include
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;