debugger: make 'qtcreator -debug <corefile>' work

This commit is contained in:
hjk
2009-09-30 12:27:03 +02:00
parent 2dff35548a
commit 93902e5d0a
11 changed files with 82 additions and 41 deletions

View File

@@ -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-gdb">Disable Gdb debugger engine</argument>
<argument name="-disable-sdb">Disable Qt Script debugger engine</argument> <argument name="-disable-sdb">Disable Qt Script debugger engine</argument>
<argument name="-disable-tcf">Disable Tcf 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> <argument name="-wincrashevent" parameter="event-handle">Event handle used for attaching to crashed processes</argument>
</argumentList> </argumentList>
</plugin> </plugin>

View File

@@ -1698,7 +1698,9 @@ void DebuggerManager::setState(DebuggerState state)
//showStatusMessage(QString("stoppable: %1, running: %2") //showStatusMessage(QString("stoppable: %1, running: %2")
// .arg(stoppable).arg(running)); // .arg(stoppable).arg(running));
emit stateChanged(d->m_state); emit stateChanged(d->m_state);
const bool notbusy = stopped || state == DebuggerNotReady; const bool notbusy = state == InferiorStopped
|| state == DebuggerNotReady
|| state == InferiorUnrunnable;
setBusyCursor(!notbusy); setBusyCursor(!notbusy);
} }

View File

@@ -31,8 +31,8 @@
#define DEBUGGER_OUTPUTWINDOW_H #define DEBUGGER_OUTPUTWINDOW_H
#include <QtGui/QLineEdit> #include <QtGui/QLineEdit>
#include <QtGui/QSplitter>
#include <QtGui/QPlainTextEdit> #include <QtGui/QPlainTextEdit>
#include <QtGui/QSplitter>
#include <QtGui/QWidget> #include <QtGui/QWidget>
namespace Debugger { namespace Debugger {

View File

@@ -478,8 +478,8 @@ bool DebuggerPlugin::parseArgument(QStringList::const_iterator &it,
bool ok; bool ok;
m_cmdLineAttachPid = it->toULongLong(&ok); m_cmdLineAttachPid = it->toULongLong(&ok);
if (!ok) { if (!ok) {
*errorMessage = msgInvalidNumericParameter(option, *it); m_cmdLineAttachPid = 0;
return false; m_cmdLineAttachCore = *it;
} }
return true; return true;
} }
@@ -530,7 +530,8 @@ bool DebuggerPlugin::parseArguments(const QStringList &args, QString *errorMessa
if (Debugger::Constants::Internal::debug) if (Debugger::Constants::Internal::debug)
qDebug().nospace() << args << "engines=0x" qDebug().nospace() << args << "engines=0x"
<< QString::number(m_cmdLineEnabledEngines, 16) << QString::number(m_cmdLineEnabledEngines, 16)
<< " pid" << m_cmdLineAttachPid << '\n'; << " pid" << m_cmdLineAttachPid
<< " core" << m_cmdLineAttachCore << '\n';
return true; return true;
} }
@@ -909,6 +910,8 @@ void DebuggerPlugin::extensionsInitialized()
m_manager->runTest(QString::fromLocal8Bit(env)); m_manager->runTest(QString::fromLocal8Bit(env));
if (m_cmdLineAttachPid) if (m_cmdLineAttachPid)
QTimer::singleShot(0, this, SLOT(attachCmdLinePid())); QTimer::singleShot(0, this, SLOT(attachCmdLinePid()));
if (!m_cmdLineAttachCore.isEmpty())
QTimer::singleShot(0, this, SLOT(attachCmdLineCore()));
} }
void DebuggerPlugin::attachCmdLinePid() void DebuggerPlugin::attachCmdLinePid()
@@ -1249,9 +1252,14 @@ void DebuggerPlugin::attachExternalApplication(qint64 pid, const QString &crashP
runControl->start(); runControl->start();
} }
void DebuggerPlugin::attachCmdLineCore()
{
m_manager->showStatusMessage(tr("Attaching to core %1.").arg(m_cmdLineAttachCore));
attachCore(m_cmdLineAttachCore, QString());
}
void DebuggerPlugin::attachCore() void DebuggerPlugin::attachCore()
{ {
const DebuggerStartParametersPtr sp(new DebuggerStartParameters);
AttachCoreDialog dlg(m_manager->mainWindow()); AttachCoreDialog dlg(m_manager->mainWindow());
dlg.setExecutableFile( dlg.setExecutableFile(
configValue(_("LastExternalExecutableFile")).toString()); configValue(_("LastExternalExecutableFile")).toString());
@@ -1263,8 +1271,14 @@ void DebuggerPlugin::attachCore()
dlg.executableFile()); dlg.executableFile());
setConfigValue(_("LastExternalCoreFile"), setConfigValue(_("LastExternalCoreFile"),
dlg.coreFile()); dlg.coreFile());
sp->executable = dlg.executableFile(); attachCore(dlg.coreFile(), dlg.executableFile());
sp->coreFile = dlg.coreFile(); }
void DebuggerPlugin::attachCore(const QString &core, const QString &exe)
{
const DebuggerStartParametersPtr sp(new DebuggerStartParameters);
sp->executable = exe;
sp->coreFile = core;
sp->startMode = AttachCore; sp->startMode = AttachCore;
RunConfigurationPtr rc = activeRunConfiguration(); RunConfigurationPtr rc = activeRunConfiguration();
if (rc.isNull()) if (rc.isNull())

View File

@@ -108,6 +108,7 @@ private slots:
void attachCore(); void attachCore();
void attachRemoteTcf(); void attachRemoteTcf();
void attachCmdLinePid(); void attachCmdLinePid();
void attachCmdLineCore();
private: private:
void readSettings(); void readSettings();
@@ -117,6 +118,7 @@ private:
const QStringList::const_iterator& end, const QStringList::const_iterator& end,
QString *errorMessage); QString *errorMessage);
void attachExternalApplication(qint64 pid, const QString &crashParameter = QString()); void attachExternalApplication(qint64 pid, const QString &crashParameter = QString());
void attachCore(const QString &core, const QString &exeFileName);
friend class Debugger::DebuggerManager; friend class Debugger::DebuggerManager;
friend class GdbOptionPage; friend class GdbOptionPage;
@@ -132,6 +134,7 @@ private:
int m_gdbRunningContext; int m_gdbRunningContext;
unsigned m_cmdLineEnabledEngines; unsigned m_cmdLineEnabledEngines;
quint64 m_cmdLineAttachPid; quint64 m_cmdLineAttachPid;
QString m_cmdLineAttachCore;
// Event handle for attaching to crashed Windows processes. // Event handle for attaching to crashed Windows processes.
quint64 m_cmdLineWinCrashEvent; quint64 m_cmdLineWinCrashEvent;
QAction *m_toggleLockedAction; QAction *m_toggleLockedAction;

View File

@@ -112,36 +112,16 @@ void CoreGdbAdapter::prepareInferior()
{ {
QTC_ASSERT(state() == AdapterStarted, qDebug() << state()); QTC_ASSERT(state() == AdapterStarted, qDebug() << state());
setState(InferiorPreparing); setState(InferiorPreparing);
if (!startParameters().processArgs.isEmpty()) setState(InferiorPrepared);
m_engine->postCommand(_("-exec-arguments ") emit inferiorPrepared();
+ 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);
}
} }
void CoreGdbAdapter::startInferior() void CoreGdbAdapter::startInferior()
{ {
QTC_ASSERT(state() == InferiorStarting, qDebug() << state()); QTC_ASSERT(state() == InferiorStarting, qDebug() << state());
QFileInfo fi(startParameters().executable);
QString fileName = _c('"') + fi.absoluteFilePath() + _c('"');
QFileInfo fi2(startParameters().coreFile); QFileInfo fi2(startParameters().coreFile);
// quoting core name below fails in gdb 6.8-debian // quoting core name below fails in gdb 6.8-debian
m_executable.clear();
QString coreName = fi2.absoluteFilePath(); QString coreName = fi2.absoluteFilePath();
m_engine->postCommand(_("target core ") + coreName, CB(handleTargetCore)); m_engine->postCommand(_("target core ") + coreName, CB(handleTargetCore));
} }
@@ -150,9 +130,18 @@ void CoreGdbAdapter::handleTargetCore(const GdbResponse &response)
{ {
QTC_ASSERT(state() == InferiorStarting, qDebug() << state()); QTC_ASSERT(state() == InferiorStarting, qDebug() << state());
if (response.resultClass == GdbResultDone) { if (response.resultClass == GdbResultDone) {
setState(InferiorUnrunnable);
showStatusMessage(tr("Attached to core.")); 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 { } else {
QTC_ASSERT(response.resultClass == GdbResultError, /**/); QTC_ASSERT(response.resultClass == GdbResultError, /**/);
const QByteArray &msg = response.data.findChild("msg").data(); 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() void CoreGdbAdapter::interruptInferior()
{ {
// A core should never 'run' // A core should never 'run'
@@ -169,12 +175,21 @@ void CoreGdbAdapter::interruptInferior()
void CoreGdbAdapter::shutdown() void CoreGdbAdapter::shutdown()
{ {
if (state() == InferiorUnrunnable || state() == InferiorShutDown) { switch (state()) {
case DebuggerNotReady:
return;
case InferiorUnrunnable:
case InferiorShutDown:
case InferiorPreparationFailed:
setState(AdapterShuttingDown); setState(AdapterShuttingDown);
m_engine->postCommand(_("-gdb-exit"), CB(handleExit)); m_engine->postCommand(_("-gdb-exit"), CB(handleExit));
return; return;
default:
QTC_ASSERT(false, qDebug() << state());
} }
QTC_ASSERT(state() == DebuggerNotReady, qDebug() << state());
} }
void CoreGdbAdapter::handleExit(const GdbResponse &response) void CoreGdbAdapter::handleExit(const GdbResponse &response)

View File

@@ -76,6 +76,7 @@ private:
Q_SLOT void handleGdbFinished(int, QProcess::ExitStatus); Q_SLOT void handleGdbFinished(int, QProcess::ExitStatus);
QProcess m_gdbProc; QProcess m_gdbProc;
QString m_executable;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -881,16 +881,21 @@ void GdbEngine::executeDebuggerCommand(const QString &command)
void GdbEngine::updateAll() void GdbEngine::updateAll()
{ {
QTC_ASSERT(state() == InferiorUnrunnable || state() == InferiorStopped, /**/); QTC_ASSERT(state() == InferiorUnrunnable || state() == InferiorStopped, /**/);
manager()->resetLocation();
tryLoadDebuggingHelpers(); tryLoadDebuggingHelpers();
manager()->stackHandler()->setCurrentIndex(0);
updateLocals(); updateLocals();
reloadStack(); postCommand(_("-stack-list-frames"), WatchUpdate, CB(handleStackListFrames1), false);
manager()->stackHandler()->setCurrentIndex(0);
if (supportsThreads()) if (supportsThreads())
postCommand(_("-thread-list-ids"), WatchUpdate, CB(handleStackListThreads), 0); postCommand(_("-thread-list-ids"), WatchUpdate, CB(handleStackListThreads), 0);
manager()->reloadRegisters(); manager()->reloadRegisters();
} }
void GdbEngine::handleStackListFrames1(const GdbResponse &response)
{
handleStackListFrames(response);
manager()->gotoLocation(manager()->stackHandler()->currentFrame(), true);
}
void GdbEngine::handleQuerySources(const GdbResponse &response) void GdbEngine::handleQuerySources(const GdbResponse &response)
{ {
if (response.resultClass == GdbResultDone) { if (response.resultClass == GdbResultDone) {

View File

@@ -338,6 +338,7 @@ private:
// Stack specific stuff // Stack specific stuff
// //
void handleStackListFrames(const GdbResponse &response); void handleStackListFrames(const GdbResponse &response);
void handleStackListFrames1(const GdbResponse &response);
void handleStackSelectThread(const GdbResponse &response); void handleStackSelectThread(const GdbResponse &response);
void handleStackListThreads(const GdbResponse &response); void handleStackListThreads(const GdbResponse &response);
Q_SLOT void reloadStack(); Q_SLOT void reloadStack();

View File

@@ -144,7 +144,7 @@ void PlainGdbAdapter::prepareInferior()
if (!startParameters().processArgs.isEmpty()) if (!startParameters().processArgs.isEmpty())
m_engine->postCommand(_("-exec-arguments ") m_engine->postCommand(_("-exec-arguments ")
+ startParameters().processArgs.join(_(" "))); + startParameters().processArgs.join(_(" ")));
QFileInfo fi(m_engine->startParameters().executable); QFileInfo fi(startParameters().executable);
m_engine->postCommand(_("-file-exec-and-symbols \"%1\"").arg(fi.absoluteFilePath()), m_engine->postCommand(_("-file-exec-and-symbols \"%1\"").arg(fi.absoluteFilePath()),
CB(handleFileExecAndSymbols)); CB(handleFileExecAndSymbols));
} }

View File

@@ -1411,7 +1411,7 @@ void TrkGdbAdapter::handleGdbStateChanged(QProcess::ProcessState newState)
void TrkGdbAdapter::startAdapter() void TrkGdbAdapter::startAdapter()
{ {
// Retrieve parameters // Retrieve parameters
const DebuggerStartParameters &parameters = m_engine->startParameters(); const DebuggerStartParameters &parameters = startParameters();
setOverrideTrkDevice(parameters.remoteChannel); setOverrideTrkDevice(parameters.remoteChannel);
m_remoteExecutable = parameters.executable; m_remoteExecutable = parameters.executable;
m_symbolFile = parameters.symbolFileName; m_symbolFile = parameters.symbolFileName;