debugger: Replace adapter classes by GdbEngine subclasses

Change-Id: Iee6195b1eed5251545b9d688221ac2edf19325c1
Reviewed-by: Christian Kandeler <christian.kandeler@nokia.com>
This commit is contained in:
hjk
2012-06-13 10:15:56 +02:00
committed by hjk
parent c68cf6dcd9
commit 5d782df33f
27 changed files with 605 additions and 986 deletions
-2
View File
@@ -166,8 +166,6 @@ QtcPlugin {
"cdb/cdbparsehelpers.cpp",
"cdb/cdbparsehelpers.h",
"gdb/gdb.qrc",
"gdb/abstractgdbadapter.cpp",
"gdb/abstractgdbadapter.h",
"gdb/abstractgdbprocess.cpp",
"gdb/abstractgdbprocess.h",
"gdb/abstractplaingdbadapter.cpp",
+3
View File
@@ -1357,6 +1357,7 @@ bool DebuggerPluginPrivate::parseArgument(QStringList::const_iterator &it,
sp.remoteArchitecture = val;
else if (key == QLatin1String("core")) {
sp.startMode = AttachCore;
sp.closeMode = DetachAtClose;
sp.coreFile = val;
sp.displayName = tr("Core file \"%1\"").arg(sp.coreFile);
sp.startMessage = tr("Attaching to core file %1.").arg(sp.coreFile);
@@ -1590,6 +1591,7 @@ void DebuggerPluginPrivate::attachCore()
sp.coreFile = dlg.coreFile();
sp.displayName = tr("Core file \"%1\"").arg(dlg.coreFile());
sp.startMode = AttachCore;
sp.closeMode = DetachAtClose;
sp.debuggerCommand = dlg.debuggerCommand();
sp.toolChainAbi = dlg.abi();
sp.sysroot = dlg.sysroot();
@@ -1701,6 +1703,7 @@ void DebuggerPluginPrivate::loadRemoteCoreFile()
return;
sp.displayName = tr("Core file \"%1\"").arg(sp.coreFile);
sp.startMode = AttachCore;
sp.closeMode = DetachAtClose;
//sp.debuggerCommand = dlg.debuggerCommand();
//sp.toolChainAbi = dlg.abi();
sp.sysroot = dlg.sysroot();
@@ -1,179 +0,0 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/
#include "abstractgdbadapter.h"
#include "gdbengine.h"
#include "debuggerstartparameters.h"
#include "abstractgdbprocess.h"
#include "procinterrupt.h"
#include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
#include <QProcess>
namespace Debugger {
namespace Internal {
AbstractGdbAdapter::AbstractGdbAdapter(GdbEngine *engine)
: m_engine(engine)
{
}
AbstractGdbAdapter::~AbstractGdbAdapter()
{
disconnect();
}
//void AbstractGdbAdapter::shutdown()
//{
//}
//void AbstractGdbAdapter::runEngine()
//{
// QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
//}
/*
const char *AbstractGdbAdapter::inferiorShutdownCommand() const
{
return "kill";
}
*/
void AbstractGdbAdapter::write(const QByteArray &data)
{
gdbProc()->write(data);
}
bool AbstractGdbAdapter::isCodaAdapter() const
{
return false;
}
bool AbstractGdbAdapter::prepareCommand()
{
#ifdef Q_OS_WIN
Utils::QtcProcess::SplitError perr;
startParameters().processArgs = Utils::QtcProcess::prepareArgs(
startParameters().processArgs, &perr,
&startParameters().environment, &startParameters().workingDirectory);
if (perr != Utils::QtcProcess::SplitOk) {
// perr == BadQuoting is never returned on Windows
// FIXME? QTCREATORBUG-2809
m_engine->handleAdapterStartFailed(QCoreApplication::translate("DebuggerEngine", // Same message in CdbEngine
"Debugging complex command lines is currently not supported on Windows."), QString());
return false;
}
#endif
return true;
}
QString AbstractGdbAdapter::msgGdbStopFailed(const QString &why)
{
return tr("The gdb process could not be stopped:\n%1").arg(why);
}
QString AbstractGdbAdapter::msgInferiorStopFailed(const QString &why)
{
return tr("Application process could not be stopped:\n%1").arg(why);
}
QString AbstractGdbAdapter::msgInferiorSetupOk()
{
return tr("Application started");
}
QString AbstractGdbAdapter::msgInferiorRunOk()
{
return tr("Application running");
}
QString AbstractGdbAdapter::msgAttachedToStoppedInferior()
{
return tr("Attached to stopped application");
}
QString AbstractGdbAdapter::msgConnectRemoteServerFailed(const QString &why)
{
return tr("Connecting to remote server failed:\n%1").arg(why);
}
DebuggerState AbstractGdbAdapter::state() const
{
return m_engine->state();
}
const DebuggerStartParameters &AbstractGdbAdapter::startParameters() const
{
return m_engine->startParameters();
}
DebuggerStartParameters &AbstractGdbAdapter::startParameters()
{
return m_engine->startParameters();
}
void AbstractGdbAdapter::showMessage(const QString &msg, int channel, int timeout)
{
m_engine->showMessage(msg, channel, timeout);
}
void AbstractGdbAdapter::handleRemoteSetupDone(int gdbServerPort, int qmlPort)
{
Q_UNUSED(gdbServerPort);
Q_UNUSED(qmlPort);
}
void AbstractGdbAdapter::handleRemoteSetupFailed(const QString &reason)
{
Q_UNUSED(reason);
}
void AbstractGdbAdapter::interruptLocalInferior(qint64 pid)
{
QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state(); return);
if (pid <= 0) {
showMessage(QLatin1String("TRYING TO INTERRUPT INFERIOR BEFORE PID WAS OBTAINED"), LogError);
return;
}
QString errorMessage;
if (interruptProcess(pid, GdbEngineType, &errorMessage)) {
showMessage(QLatin1String("Interrupted ") + QString::number(pid));
} else {
showMessage(errorMessage, LogError);
m_engine->notifyInferiorStopFailed();
}
}
} // namespace Internal
} // namespace Debugger
@@ -1,116 +0,0 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/
#ifndef DEBUGGER_ABSTRACT_GDB_ADAPTER
#define DEBUGGER_ABSTRACT_GDB_ADAPTER
#include "debuggerconstants.h"
// Need to include gdbengine.h as otherwise MSVC crashes
// on invoking the first adapter callback in a *derived* adapter class.
#include "gdbengine.h"
#include <QObject>
namespace Debugger {
class DebuggerStartParameters;
namespace Internal {
class AbstractGdbProcess;
class GdbResponse;
// AbstractGdbAdapter is inherited by PlainGdbAdapter used for local
// debugging and CodaGdbAdapter used for on-device debugging.
// In the PlainGdbAdapter case it's just a wrapper around a QProcess running
// gdb, in the CodaGdbAdapter case it's the interface to the gdb process in
// the whole rfcomm/gdb/gdbserver combo.
class AbstractGdbAdapter : public QObject
{
Q_OBJECT
public:
enum DumperHandling
{
DumperNotAvailable,
DumperLoadedByAdapter,
DumperLoadedByGdbPreload,
DumperLoadedByGdb
};
explicit AbstractGdbAdapter(GdbEngine *engine);
virtual ~AbstractGdbAdapter();
virtual void write(const QByteArray &data);
virtual void startAdapter() = 0;
virtual void handleGdbStartDone() = 0;
virtual void handleGdbStartFailed() = 0;
virtual void setupInferior() = 0;
virtual void runEngine() = 0;
virtual void interruptInferior() = 0;
virtual void shutdownAdapter() = 0;
virtual AbstractGdbProcess *gdbProc() = 0;
virtual DumperHandling dumperHandling() const = 0;
static QString msgGdbStopFailed(const QString &why);
static QString msgInferiorStopFailed(const QString &why);
static QString msgAttachedToStoppedInferior();
static QString msgInferiorSetupOk();
static QString msgInferiorRunOk();
static QString msgConnectRemoteServerFailed(const QString &why);
// CODA specific stuff
virtual bool isCodaAdapter() const;
virtual void codaReloadRegisters() {}
virtual void codaReloadThreads() {}
virtual void handleRemoteSetupDone(int gdbServerPort, int qmlPort);
virtual void handleRemoteSetupFailed(const QString &reason);
protected:
DebuggerState state() const;
GdbEngine *engine() const { return m_engine; }
const DebuggerStartParameters &startParameters() const;
DebuggerStartParameters &startParameters();
void showMessage(const QString &msg, int channel = LogDebug, int timeout = 1);
bool prepareCommand();
void interruptLocalInferior(qint64 pid);
GdbEngine * const m_engine;
};
} // namespace Internal
} // namespace Debugger
#endif // DEBUGGER_ABSTRACT_GDB_ADAPTER
@@ -48,62 +48,62 @@ namespace Debugger {
namespace Internal {
#define CB(callback) \
static_cast<GdbEngine::AdapterCallback>(&AbstractPlainGdbAdapter::callback), \
static_cast<GdbEngine::GdbCommandCallback>(&GdbAbstractPlainEngine::callback), \
STRINGIFY(callback)
AbstractPlainGdbAdapter::AbstractPlainGdbAdapter(GdbEngine *engine)
: AbstractGdbAdapter(engine)
{
}
GdbAbstractPlainEngine::GdbAbstractPlainEngine(const DebuggerStartParameters &startParameters,
DebuggerEngine *masterEngine)
: GdbEngine(startParameters, masterEngine)
{}
void AbstractPlainGdbAdapter::setupInferior()
void GdbAbstractPlainEngine::setupInferior()
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
if (!startParameters().processArgs.isEmpty()) {
QString args = startParameters().processArgs;
m_engine->postCommand("-exec-arguments " + toLocalEncoding(args));
postCommand("-exec-arguments " + toLocalEncoding(args));
}
m_engine->postCommand("-file-exec-and-symbols \"" + execFilePath() + '"',
postCommand("-file-exec-and-symbols \"" + execFilePath() + '"',
CB(handleFileExecAndSymbols));
}
void AbstractPlainGdbAdapter::handleFileExecAndSymbols(const GdbResponse &response)
void GdbAbstractPlainEngine::handleFileExecAndSymbols(const GdbResponse &response)
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
if (response.resultClass == GdbResultDone) {
m_engine->handleInferiorPrepared();
handleInferiorPrepared();
} else {
QByteArray ba = response.data.findChild("msg").data();
QString msg = fromLocalEncoding(ba);
// Extend the message a bit in unknown cases.
if (!ba.endsWith("File format not recognized"))
msg = tr("Starting executable failed:\n") + msg;
m_engine->notifyInferiorSetupFailed(msg);
notifyInferiorSetupFailed(msg);
}
}
void AbstractPlainGdbAdapter::runEngine()
void GdbAbstractPlainEngine::runEngine()
{
m_engine->postCommand("-exec-run", GdbEngine::RunRequest, CB(handleExecRun));
postCommand("-exec-run", GdbEngine::RunRequest, CB(handleExecRun));
}
void AbstractPlainGdbAdapter::handleExecRun(const GdbResponse &response)
void GdbAbstractPlainEngine::handleExecRun(const GdbResponse &response)
{
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
if (response.resultClass == GdbResultRunning) {
m_engine->notifyEngineRunAndInferiorRunOk();
notifyEngineRunAndInferiorRunOk();
//showStatusMessage(tr("Running..."));
showMessage(_("INFERIOR STARTED"));
showMessage(msgInferiorSetupOk(), StatusBar);
// FIXME: That's the wrong place for it.
if (debuggerCore()->boolSetting(EnableReverseDebugging))
m_engine->postCommand("target record");
postCommand("target record");
} else {
QString msg = fromLocalEncoding(response.data.findChild("msg").data());
//QTC_CHECK(status() == InferiorRunOk);
//interruptInferior();
showMessage(msg);
m_engine->notifyEngineRunFailed();
notifyEngineRunFailed();
}
}
@@ -33,20 +33,21 @@
#ifndef ABSTRACTPLAINGDBADAPTER_H
#define ABSTRACTPLAINGDBADAPTER_H
#include "abstractgdbadapter.h"
#include "gdbengine.h"
namespace Debugger {
namespace Internal {
class AbstractPlainGdbAdapter : public AbstractGdbAdapter
class GdbAbstractPlainEngine : public GdbEngine
{
// Needs tr - context
Q_OBJECT
public:
explicit AbstractPlainGdbAdapter(GdbEngine *engine);
GdbAbstractPlainEngine(const DebuggerStartParameters &startParameters,
DebuggerEngine *masterEngine);
virtual void setupInferior();
void setupInferior();
void runEngine();
private:
+19 -29
View File
@@ -45,7 +45,7 @@ namespace Debugger {
namespace Internal {
#define CB(callback) \
static_cast<GdbEngine::AdapterCallback>(&AttachGdbAdapter::callback), \
static_cast<GdbEngine::GdbCommandCallback>(&GdbAttachEngine::callback), \
STRINGIFY(callback)
///////////////////////////////////////////////////////////////////////
@@ -54,47 +54,37 @@ namespace Internal {
//
///////////////////////////////////////////////////////////////////////
AttachGdbAdapter::AttachGdbAdapter(GdbEngine *engine)
: AbstractGdbAdapter(engine)
GdbAttachEngine::GdbAttachEngine(const DebuggerStartParameters &startParameters,
DebuggerEngine *masterEngine)
: GdbEngine(startParameters, masterEngine)
{
}
void AttachGdbAdapter::startAdapter()
void GdbAttachEngine::setupEngine()
{
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
showMessage(_("TRYING TO START ADAPTER"));
m_engine->startGdb();
startGdb();
}
void AttachGdbAdapter::handleGdbStartDone()
{
m_engine->handleAdapterStarted();
}
void AttachGdbAdapter::handleGdbStartFailed()
{
}
void AttachGdbAdapter::setupInferior()
void GdbAttachEngine::setupInferior()
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
const qint64 pid = startParameters().attachPID;
m_engine->postCommand("attach " + QByteArray::number(pid), CB(handleAttach));
postCommand("attach " + QByteArray::number(pid), CB(handleAttach));
// Task 254674 does not want to remove them
//qq->breakHandler()->removeAllBreakpoints();
}
void AttachGdbAdapter::runEngine()
void GdbAttachEngine::runEngine()
{
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
m_engine->showStatusMessage(tr("Attached to process %1.")
.arg(m_engine->inferiorPid()));
m_engine->notifyEngineRunAndInferiorStopOk();
GdbMi data;
m_engine->handleStop1(data);
showStatusMessage(tr("Attached to process %1.").arg(inferiorPid()));
notifyEngineRunAndInferiorStopOk();
handleStop1(GdbMi());
}
void AttachGdbAdapter::handleAttach(const GdbResponse &response)
void GdbAttachEngine::handleAttach(const GdbResponse &response)
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
switch (response.resultClass) {
@@ -102,28 +92,28 @@ void AttachGdbAdapter::handleAttach(const GdbResponse &response)
case GdbResultRunning:
showMessage(_("INFERIOR ATTACHED"));
showMessage(msgAttachedToStoppedInferior(), StatusBar);
m_engine->handleInferiorPrepared();
handleInferiorPrepared();
break;
case GdbResultError:
if (response.data.findChild("msg").data() == "ptrace: Operation not permitted.") {
m_engine->notifyInferiorSetupFailed(DumperHelper::msgPtraceError(startParameters().startMode));
notifyInferiorSetupFailed(DumperHelper::msgPtraceError(startParameters().startMode));
break;
}
// if msg != "ptrace: ..." fall through
default:
QString msg = QString::fromLocal8Bit(response.data.findChild("msg").data());
m_engine->notifyInferiorSetupFailed(msg);
notifyInferiorSetupFailed(msg);
}
}
void AttachGdbAdapter::interruptInferior()
void GdbAttachEngine::interruptInferior2()
{
interruptLocalInferior(startParameters().attachPID);
}
void AttachGdbAdapter::shutdownAdapter()
void GdbAttachEngine::shutdownEngine()
{
m_engine->notifyAdapterShutdownOk();
notifyAdapterShutdownOk();
}
} // namespace Internal
+7 -8
View File
@@ -33,7 +33,7 @@
#ifndef DEBUGGER_ATTACHGDBADAPTER_H
#define DEBUGGER_ATTACHGDBADAPTER_H
#include "abstractgdbadapter.h"
#include "gdbengine.h"
#include "localgdbprocess.h"
namespace Debugger {
@@ -45,23 +45,22 @@ namespace Internal {
//
///////////////////////////////////////////////////////////////////////
class AttachGdbAdapter : public AbstractGdbAdapter
class GdbAttachEngine : public GdbEngine
{
Q_OBJECT
public:
explicit AttachGdbAdapter(GdbEngine *engine);
GdbAttachEngine(const DebuggerStartParameters &startParameters,
DebuggerEngine *masterEngine);
private:
DumperHandling dumperHandling() const { return DumperLoadedByGdb; }
void startAdapter();
void handleGdbStartDone();
void handleGdbStartFailed();
void setupEngine();
void setupInferior();
void runEngine();
void interruptInferior();
void shutdownAdapter();
void interruptInferior2();
void shutdownEngine();
AbstractGdbProcess *gdbProc() { return &m_gdbProc; }
void handleAttach(const GdbResponse &response);
@@ -34,7 +34,6 @@
#include "gdbmi.h"
#include "debuggerstartparameters.h"
#include "abstractgdbadapter.h"
#include "debuggeractions.h"
#include "debuggercore.h"
#include "debuggerstringutils.h"
@@ -1107,7 +1106,7 @@ void GdbEngine::tryLoadDebuggingHelpersClassic()
return;
PRECONDITION;
if (m_gdbAdapter->dumperHandling() == AbstractGdbAdapter::DumperNotAvailable) {
if (dumperHandling() == GdbEngine::DumperNotAvailable) {
// Load at least gdb macro based dumpers.
m_debuggingHelperState = DebuggingHelperLoadTried;
postCommand(Utils::FileReader::fetchQrc(_(":/gdb/gdbmacros.txt")));
+95 -104
View File
@@ -65,7 +65,7 @@
#endif
#define CB(callback) \
static_cast<GdbEngine::AdapterCallback>(&CodaGdbAdapter::callback), \
static_cast<GdbEngine::GdbCommandCallback>(&GdbCodaEngine::callback), \
STRINGIFY(callback)
enum { debug = 0 };
@@ -91,7 +91,7 @@ using namespace Coda;
static inline QString startMsg(const Coda::Session &session)
{
return CodaGdbAdapter::tr("Process started, PID: 0x%1, thread id: 0x%2, "
return GdbCodaEngine::tr("Process started, PID: 0x%1, thread id: 0x%2, "
"code segment: 0x%3, data segment: 0x%4.")
.arg(session.pid, 0, 16).arg(session.tid, 0, 16)
.arg(session.codeseg, 0, 16).arg(session.dataseg, 0, 16);
@@ -118,8 +118,9 @@ static inline QString startMsg(const Coda::Session &session)
* - Stop all threads once one stops?
* - Breakpoints do not trigger in threads other than the main thread. */
CodaGdbAdapter::CodaGdbAdapter(GdbEngine *engine) :
AbstractGdbAdapter(engine),
GdbCodaEngine:: GdbCodaEngine(const DebuggerStartParameters &startParameters,
DebuggerEngine *masterEngine)
: GdbEngine(startParameters, masterEngine),
m_running(false),
m_stopReason(0),
m_gdbAckMode(true),
@@ -149,7 +150,7 @@ CodaGdbAdapter::CodaGdbAdapter(GdbEngine *engine) :
this, SLOT(setVerbose(QVariant)));
}
void CodaGdbAdapter::setupDeviceSignals()
void GdbCodaEngine::setupDeviceSignals()
{
connect(m_codaDevice.data(), SIGNAL(error(QString)),
this, SLOT(codaDeviceError(QString)));
@@ -161,7 +162,7 @@ void CodaGdbAdapter::setupDeviceSignals()
this, SLOT(codaDeviceRemoved(SymbianUtils::SymbianDevice)));
}
CodaGdbAdapter::~CodaGdbAdapter()
GdbCodaEngine::~GdbCodaEngine()
{
if (m_codaDevice)
SymbianUtils::SymbianDeviceManager::instance()->releaseCodaDevice(m_codaDevice);
@@ -170,12 +171,12 @@ CodaGdbAdapter::~CodaGdbAdapter()
logMessage(QLatin1String("Shutting down.\n"));
}
void CodaGdbAdapter::setVerbose(const QVariant &value)
void GdbCodaEngine::setVerbose(const QVariant &value)
{
setVerbose(value.toInt());
}
void CodaGdbAdapter::setVerbose(int verbose)
void GdbCodaEngine::setVerbose(int verbose)
{
if (debug)
qDebug("CodaGdbAdapter::setVerbose %d", verbose);
@@ -184,12 +185,12 @@ void CodaGdbAdapter::setVerbose(int verbose)
m_codaDevice->setVerbose(m_verbose);
}
void CodaGdbAdapter::codaLogMessage(const QString &msg)
void GdbCodaEngine::codaLogMessage(const QString &msg)
{
logMessage(_("CODA ") + msg);
}
void CodaGdbAdapter::setGdbServerName(const QString &name)
void GdbCodaEngine::setGdbServerName(const QString &name)
{
m_gdbServerName = name;
}
@@ -210,7 +211,7 @@ static QPair<QString, unsigned short> splitIpAddressSpec(const QString &addressS
return QPair<QString, unsigned short>(address, port);
}
void CodaGdbAdapter::handleCodaRunControlModuleLoadContextSuspendedEvent(const CodaRunControlModuleLoadContextSuspendedEvent &se)
void GdbCodaEngine::handleCodaRunControlModuleLoadContextSuspendedEvent(const CodaRunControlModuleLoadContextSuspendedEvent &se)
{
m_snapshot.resetMemory();
const ModuleLoadEventInfo &minfo = se.info();
@@ -234,7 +235,7 @@ void CodaGdbAdapter::handleCodaRunControlModuleLoadContextSuspendedEvent(const C
if (!localSymFileName.isEmpty()) {
showMessage(msgLoadLocalSymFile(localSymFileName,
library.name, library.codeseg), LogMisc);
m_engine->postCommand(symFileLoadCommand(
postCommand(symFileLoadCommand(
localSymFileName, library.codeseg, library.dataseg));
} // has local sym
} // code seg
@@ -271,11 +272,11 @@ void CodaGdbAdapter::handleCodaRunControlModuleLoadContextSuspendedEvent(const C
// have to wait for the CODA startup to learn the load address.
//m_engine->postCommand("add-symbol-file \"" + symbolFile + "\" "
// + QByteArray::number(m_session.codeseg));
m_engine->postCommand("symbol-file \"" + symbolFile + "\"");
postCommand("symbol-file \"" + symbolFile + "\"");
}
foreach (const QByteArray &s, Symbian::gdbStartupSequence())
m_engine->postCommand(s);
m_engine->postCommand("target remote " + gdbServerName().toLatin1(),
postCommand(s);
postCommand("target remote " + gdbServerName().toLatin1(),
CB(handleTargetRemote));
if (debug)
qDebug() << "Initial module load suspended: " << m_session.toString();
@@ -286,32 +287,32 @@ void CodaGdbAdapter::handleCodaRunControlModuleLoadContextSuspendedEvent(const C
}
}
void CodaGdbAdapter::handleTargetRemote(const GdbResponse &record)
void GdbCodaEngine::handleTargetRemote(const GdbResponse &record)
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
if (record.resultClass == GdbResultDone) {
m_engine->handleInferiorPrepared();
handleInferiorPrepared();
if (debug)
qDebug() << "handleTargetRemote" << m_session.toString();
} else {
QString msg = tr("Connecting to CODA server adapter failed:\n")
+ QString::fromLocal8Bit(record.data.findChild("msg").data());
m_engine->notifyInferiorSetupFailed(msg);
notifyInferiorSetupFailed(msg);
}
}
void CodaGdbAdapter::codaDeviceRemoved(const SymbianUtils::SymbianDevice &dev)
void GdbCodaEngine::codaDeviceRemoved(const SymbianUtils::SymbianDevice &dev)
{
const DebuggerStartParameters &parameters = startParameters();
if (state() != DebuggerNotReady && !m_codaDevice.isNull() && parameters.remoteChannel == dev.portName()) {
const QString message = QString::fromLatin1("Device '%1' has been disconnected.").arg(dev.friendlyName());
logMessage(message);
m_engine->handleAdapterCrashed(message);
handleAdapterCrashed(message);
cleanup();
}
}
void CodaGdbAdapter::codaEvent(const CodaEvent &e)
void GdbCodaEngine::codaEvent(const CodaEvent &e)
{
if (debug)
qDebug() << e.toString() << m_session.toString() << m_snapshot.toString();
@@ -322,7 +323,9 @@ void CodaGdbAdapter::codaEvent(const CodaEvent &e)
if (state() == EngineSetupRequested && m_firstHelloEvent) {
m_firstHelloEvent = false;
m_codaDevice->sendLoggingAddListenerCommand(CodaCallback());
startGdb(); // Commands are only accepted after hello
QStringList gdbArgs;
gdbArgs.append(_("--nx")); // Do not read .gdbinit file
startGdb(gdbArgs); // Commands are only accepted after hello
}
break;
case CodaEvent::RunControlModuleLoadSuspended: // A module was loaded
@@ -369,7 +372,7 @@ void CodaGdbAdapter::codaEvent(const CodaEvent &e)
|| reason.contains(_("panic"), Qt::CaseInsensitive) ?
gdbServerSignalSegfault : gdbServerSignalTrap;
m_codaDevice->sendRegistersGetMRangeCommand(
CodaCallback(this, &CodaGdbAdapter::handleAndReportReadRegistersAfterStop),
CodaCallback(this, &GdbCodaEngine::handleAndReportReadRegistersAfterStop),
currentThreadContextId(), 0,
Symbian::RegisterCount);
}
@@ -382,34 +385,22 @@ void CodaGdbAdapter::codaEvent(const CodaEvent &e)
}
}
void CodaGdbAdapter::startGdb()
{
QStringList gdbArgs;
gdbArgs.append(_("--nx")); // Do not read .gdbinit file
m_engine->startGdb(gdbArgs);
}
void CodaGdbAdapter::handleGdbStartDone()
{
m_engine->handleAdapterStarted();
}
void CodaGdbAdapter::handleGdbStartFailed()
void GdbCodaEngine::handleGdbStartFailed()
{
cleanup();
}
void CodaGdbAdapter::codaDeviceError(const QString &errorString)
void GdbCodaEngine::codaDeviceError(const QString &errorString)
{
logMessage(errorString);
if (state() == EngineSetupRequested) {
m_engine->handleAdapterStartFailed(errorString);
handleAdapterStartFailed(errorString);
} else {
m_engine->handleAdapterCrashed(errorString);
handleAdapterCrashed(errorString);
}
}
void CodaGdbAdapter::logMessage(const QString &msg, int channel)
void GdbCodaEngine::logMessage(const QString &msg, int channel)
{
if (m_verbose || channel != LogDebug)
showMessage(msg, channel);
@@ -420,7 +411,7 @@ void CodaGdbAdapter::logMessage(const QString &msg, int channel)
//
// Gdb
//
void CodaGdbAdapter::handleGdbConnection()
void GdbCodaEngine::handleGdbConnection()
{
logMessage(QLatin1String("HANDLING GDB CONNECTION"));
QTC_CHECK(m_gdbConnection == 0);
@@ -437,7 +428,7 @@ static inline QString msgGdbPacket(const QString &p)
return _("gdb: ") + p;
}
void CodaGdbAdapter::readGdbServerCommand()
void GdbCodaEngine::readGdbServerCommand()
{
QTC_ASSERT(m_gdbConnection, return);
QByteArray packet = m_gdbConnection->readAll();
@@ -508,7 +499,7 @@ void CodaGdbAdapter::readGdbServerCommand()
}
}
bool CodaGdbAdapter::sendGdbServerPacket(const QByteArray &packet, bool doFlush)
bool GdbCodaEngine::sendGdbServerPacket(const QByteArray &packet, bool doFlush)
{
if (!m_gdbConnection) {
logMessage(_("Cannot write to gdb: No connection (%1)")
@@ -530,7 +521,7 @@ bool CodaGdbAdapter::sendGdbServerPacket(const QByteArray &packet, bool doFlush)
return true;
}
void CodaGdbAdapter::sendGdbServerAck()
void GdbCodaEngine::sendGdbServerAck()
{
if (!m_gdbAckMode)
return;
@@ -538,7 +529,7 @@ void CodaGdbAdapter::sendGdbServerAck()
sendGdbServerPacket(QByteArray(1, '+'), false);
}
void CodaGdbAdapter::sendGdbServerMessage(const QByteArray &msg, const QByteArray &logNote)
void GdbCodaEngine::sendGdbServerMessage(const QByteArray &msg, const QByteArray &logNote)
{
Coda::byte sum = 0;
for (int i = 0; i != msg.size(); ++i)
@@ -573,7 +564,7 @@ static QByteArray msgStepRangeReceived(unsigned from, unsigned to, bool over)
return rc;
}
void CodaGdbAdapter::handleGdbServerCommand(const QByteArray &cmd)
void GdbCodaEngine::handleGdbServerCommand(const QByteArray &cmd)
{
if (debug)
qDebug("handleGdbServerCommand: %s", cmd.constData());
@@ -720,7 +711,7 @@ void CodaGdbAdapter::handleGdbServerCommand(const QByteArray &cmd)
arg(addrLength.second).arg(addrLength.first, 0, 16).
arg(QString::fromLatin1(data.toHex())));
m_codaDevice->sendMemorySetCommand(
CodaCallback(this, &CodaGdbAdapter::handleWriteMemory),
CodaCallback(this, &GdbCodaEngine::handleWriteMemory),
m_codaProcessId, addrLength.first, data);
}
@@ -740,7 +731,7 @@ void CodaGdbAdapter::handleGdbServerCommand(const QByteArray &cmd)
} else {
//qDebug() << "Fetching single register";
m_codaDevice->sendRegistersGetMRangeCommand(
CodaCallback(this, &CodaGdbAdapter::handleAndReportReadRegister),
CodaCallback(this, &GdbCodaEngine::handleAndReportReadRegister),
currentThreadContextId(), registerNumber, 1);
}
}
@@ -757,7 +748,7 @@ void CodaGdbAdapter::handleGdbServerCommand(const QByteArray &cmd)
QByteArray registerValue;
Coda::appendInt(&registerValue, Coda::BigEndian); // Registers are big endian
m_codaDevice->sendRegistersSetCommand(
CodaCallback(this, &CodaGdbAdapter::handleWriteRegister),
CodaCallback(this, &GdbCodaEngine::handleWriteRegister),
currentThreadContextId(), regnumValue.first, registerValue,
QVariant(regnumValue.first));
// Note that App CODA refuses to write registers 13 and 14
@@ -938,7 +929,7 @@ void CodaGdbAdapter::handleGdbServerCommand(const QByteArray &cmd)
// We use the automatic ids calculated from the location
// address instead of the map in snapshot.
m_codaDevice->sendBreakpointsAddCommand(
CodaCallback(this, &CodaGdbAdapter::handleAndReportSetBreakpoint),
CodaCallback(this, &GdbCodaEngine::handleAndReportSetBreakpoint),
bp);
} else {
logMessage(_("MISPARSED BREAKPOINT '") + QLatin1String(cmd)
@@ -954,7 +945,7 @@ void CodaGdbAdapter::handleGdbServerCommand(const QByteArray &cmd)
const int pos = cmd.lastIndexOf(',');
const uint addr = cmd.mid(3, pos - 3).toUInt(0, 16);
m_codaDevice->sendBreakpointsRemoveCommand(
CodaCallback(this, &CodaGdbAdapter::handleClearBreakpoint),
CodaCallback(this, &GdbCodaEngine::handleClearBreakpoint),
Coda::Breakpoint::idFromLocation(addr));
}
@@ -994,17 +985,17 @@ void CodaGdbAdapter::handleGdbServerCommand(const QByteArray &cmd)
}
}
void CodaGdbAdapter::sendRunControlTerminateCommand()
void GdbCodaEngine::sendRunControlTerminateCommand()
{
// Requires id of main thread to terminate.
// Note that calling 'Settings|set|removeExecutable' crashes CODA,
// so, it is apparently not required.
m_codaDevice->sendRunControlTerminateCommand(
CodaCallback(this, &CodaGdbAdapter::handleRunControlTerminate),
CodaCallback(this, &GdbCodaEngine::handleRunControlTerminate),
mainThreadContextId());
}
void CodaGdbAdapter::handleRunControlTerminate(const CodaCommandResult &)
void GdbCodaEngine::handleRunControlTerminate(const CodaCommandResult &)
{
QString msg = QString::fromLatin1("CODA disconnected");
const bool emergencyShutdown = m_gdbProc.state() != QProcess::Running
@@ -1014,11 +1005,11 @@ void CodaGdbAdapter::handleRunControlTerminate(const CodaCommandResult &)
logMessage(msg, LogMisc);
if (emergencyShutdown) {
cleanup();
m_engine->notifyAdapterShutdownOk();
notifyAdapterShutdownOk();
}
}
void CodaGdbAdapter::gdbSetCurrentThread(const QByteArray &cmd, const char *why)
void GdbCodaEngine::gdbSetCurrentThread(const QByteArray &cmd, const char *why)
{
// Thread ID from Hg/Hc commands: '-1': All, '0': arbitrary, else hex thread id.
const QByteArray id = cmd.mid(2);
@@ -1032,12 +1023,12 @@ void CodaGdbAdapter::gdbSetCurrentThread(const QByteArray &cmd, const char *why)
sendGdbServerMessage("OK", message);
}
void CodaGdbAdapter::interruptInferior()
void GdbCodaEngine::interruptInferior2()
{
m_codaDevice->sendRunControlSuspendCommand(CodaCallback(), m_codaProcessId);
}
void CodaGdbAdapter::startAdapter()
void GdbCodaEngine::setupEngine()
{
m_snapshot.fullReset();
m_session.reset();
@@ -1072,7 +1063,7 @@ void CodaGdbAdapter::startAdapter()
const QString msg = QString::fromLatin1("Could not open serial device '%1': %2")
.arg(parameters.remoteChannel, reason);
logMessage(msg, LogError);
m_engine->handleAdapterStartFailed(msg);
handleAdapterStartFailed(msg);
return;
}
setupDeviceSignals();
@@ -1104,7 +1095,7 @@ void CodaGdbAdapter::startAdapter()
QString msg = QString::fromLatin1("Unable to start the gdb server at %1: %2.")
.arg(m_gdbServerName).arg(m_gdbServer->errorString());
logMessage(msg, LogError);
m_engine->handleAdapterStartFailed(msg);
handleAdapterStartFailed(msg);
return;
}
@@ -1124,7 +1115,7 @@ void CodaGdbAdapter::startAdapter()
}
}
void CodaGdbAdapter::setupInferior()
void GdbCodaEngine::setupInferior()
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
@@ -1135,12 +1126,12 @@ void CodaGdbAdapter::setupInferior()
libraries.push_back(QString::fromLatin1(librariesC[i]));
m_codaDevice->sendProcessStartCommand(
CodaCallback(this, &CodaGdbAdapter::handleCreateProcess),
CodaCallback(this, &GdbCodaEngine::handleCreateProcess),
m_remoteExecutable, m_uid, m_remoteArguments,
QString(), true, libraries);
}
void CodaGdbAdapter::addThread(unsigned id)
void GdbCodaEngine::addThread(unsigned id)
{
showMessage(QString::fromLatin1("Thread %1 reported").arg(id), LogMisc);
// Make thread known, register as main if it is the first one.
@@ -1155,19 +1146,19 @@ void CodaGdbAdapter::addThread(unsigned id)
// thread have been retrieved (CODA oddity).
const QByteArray contextId = RunControlContext::codaId(m_session.pid, id);
m_codaDevice->sendRegistersGetChildrenCommand(
CodaCallback(this, &CodaGdbAdapter::handleRegisterChildren),
CodaCallback(this, &GdbCodaEngine::handleRegisterChildren),
contextId, QVariant(contextId));
}
}
void CodaGdbAdapter::handleCreateProcess(const CodaCommandResult &result)
void GdbCodaEngine::handleCreateProcess(const CodaCommandResult &result)
{
if (debug)
qDebug() << "ProcessCreated: " << result.toString();
if (!result) {
const QString errorMessage = result.errorString();
logMessage(_("Failed to start process: %1").arg(errorMessage), LogError);
m_engine->notifyInferiorSetupFailed(result.errorString());
notifyInferiorSetupFailed(result.errorString());
return;
}
QTC_ASSERT(!result.values.isEmpty(), return);
@@ -1185,19 +1176,19 @@ void CodaGdbAdapter::handleCreateProcess(const CodaCommandResult &result)
m_session.dataseg = 0;
}
void CodaGdbAdapter::runEngine()
void GdbCodaEngine::runEngine()
{
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
m_engine->notifyEngineRunAndInferiorStopOk();
notifyEngineRunAndInferiorStopOk();
// Trigger the initial "continue" manually.
m_engine->continueInferiorInternal();
continueInferiorInternal();
}
//
// AbstractGdbAdapter interface implementation
//
void CodaGdbAdapter::write(const QByteArray &data)
void GdbCodaEngine::write(const QByteArray &data)
{
// Write magic packets directly to TRK.
if (data.startsWith("@#")) {
@@ -1229,7 +1220,7 @@ void CodaGdbAdapter::write(const QByteArray &data)
m_gdbProc.write(data);
}
void CodaGdbAdapter::cleanup()
void GdbCodaEngine::cleanup()
{
delete m_gdbServer;
m_gdbServer = 0;
@@ -1243,11 +1234,11 @@ void CodaGdbAdapter::cleanup()
}
}
void CodaGdbAdapter::shutdownAdapter()
void GdbCodaEngine::shutdownEngine()
{
if (m_gdbProc.state() == QProcess::Running) {
cleanup();
m_engine->notifyAdapterShutdownOk();
notifyAdapterShutdownOk();
} else {
// Something is wrong, gdb crashed. Kill debuggee (see handleDeleteProcess2)
if (m_codaDevice && m_codaDevice->device()->isOpen()) {
@@ -1257,18 +1248,18 @@ void CodaGdbAdapter::shutdownAdapter()
}
}
void CodaGdbAdapter::codaReloadRegisters()
void GdbCodaEngine::codaReloadRegisters()
{
// Take advantage of direct access to cached register values.
m_snapshot.syncRegisters(m_session.tid, m_engine->registerHandler());
m_snapshot.syncRegisters(m_session.tid, registerHandler());
}
void CodaGdbAdapter::codaReloadThreads()
void GdbCodaEngine::codaReloadThreads()
{
m_snapshot.syncThreads(m_engine->threadsHandler());
m_snapshot.syncThreads(threadsHandler());
}
void CodaGdbAdapter::handleWriteRegister(const CodaCommandResult &result)
void GdbCodaEngine::handleWriteRegister(const CodaCommandResult &result)
{
const int registerNumber = result.cookie.toInt();
if (result) {
@@ -1280,18 +1271,18 @@ void CodaGdbAdapter::handleWriteRegister(const CodaCommandResult &result)
}
}
void CodaGdbAdapter::sendRegistersGetMCommand()
void GdbCodaEngine::sendRegistersGetMCommand()
{
// Send off a register command, which requires the names to be present.
QTC_ASSERT(!m_codaDevice->registerNames().isEmpty(), return);
m_codaDevice->sendRegistersGetMRangeCommand(
CodaCallback(this, &CodaGdbAdapter::handleAndReportReadRegisters),
CodaCallback(this, &GdbCodaEngine::handleAndReportReadRegisters),
currentThreadContextId(), 0,
Symbian::RegisterCount);
}
void CodaGdbAdapter::reportRegisters()
void GdbCodaEngine::reportRegisters()
{
const int threadIndex = m_snapshot.indexOfThread(m_session.tid);
QTC_ASSERT(threadIndex != -1, return);
@@ -1300,7 +1291,7 @@ void CodaGdbAdapter::reportRegisters()
thread.gdbRegisterLogMessage(m_verbose));
}
void CodaGdbAdapter::handleRegisterChildren(const CodaCommandResult &result)
void GdbCodaEngine::handleRegisterChildren(const CodaCommandResult &result)
{
QTC_ASSERT(m_codaDevice, return);
const QByteArray contextId = result.cookie.toByteArray();
@@ -1317,7 +1308,7 @@ void CodaGdbAdapter::handleRegisterChildren(const CodaCommandResult &result)
QVector<QByteArray> registerNames = CodaDevice::parseRegisterGetChildren(result);
if (registerNames.size() == 1) {
m_codaDevice->sendRegistersGetChildrenCommand(
CodaCallback(this, &CodaGdbAdapter::handleRegisterChildren),
CodaCallback(this, &GdbCodaEngine::handleRegisterChildren),
registerNames.front(), result.cookie);
return;
}
@@ -1348,7 +1339,7 @@ void CodaGdbAdapter::handleRegisterChildren(const CodaCommandResult &result)
}
}
void CodaGdbAdapter::handleReadRegisters(const CodaCommandResult &result)
void GdbCodaEngine::handleReadRegisters(const CodaCommandResult &result)
{
// Check for errors.
if (!result) {
@@ -1382,13 +1373,13 @@ void CodaGdbAdapter::handleReadRegisters(const CodaCommandResult &result)
qDebug() << "handleReadRegisters: " << m_snapshot.toString();
}
void CodaGdbAdapter::handleAndReportReadRegisters(const CodaCommandResult &result)
void GdbCodaEngine::handleAndReportReadRegisters(const CodaCommandResult &result)
{
handleReadRegisters(result);
reportRegisters();
}
void CodaGdbAdapter::handleAndReportReadRegister(const CodaCommandResult &result)
void GdbCodaEngine::handleAndReportReadRegister(const CodaCommandResult &result)
{
handleReadRegisters(result);
const uint registerNumber = result.cookie.toUInt();
@@ -1399,7 +1390,7 @@ void CodaGdbAdapter::handleAndReportReadRegister(const CodaCommandResult &result
thread.gdbSingleRegisterLogMessage(registerNumber));
}
QByteArray CodaGdbAdapter::stopMessage() const
QByteArray GdbCodaEngine::stopMessage() const
{
QByteArray logMsg = "Stopped with registers in thread 0x";
logMsg += QByteArray::number(m_session.tid, 16);
@@ -1420,7 +1411,7 @@ QByteArray CodaGdbAdapter::stopMessage() const
return logMsg;
}
void CodaGdbAdapter::handleAndReportReadRegistersAfterStop(const CodaCommandResult &result)
void GdbCodaEngine::handleAndReportReadRegistersAfterStop(const CodaCommandResult &result)
{
handleReadRegisters(result);
handleReadRegisters(result);
@@ -1429,7 +1420,7 @@ void CodaGdbAdapter::handleAndReportReadRegistersAfterStop(const CodaCommandResu
m_stopReason, reportThread), stopMessage());
}
void CodaGdbAdapter::handleAndReportSetBreakpoint(const CodaCommandResult &result)
void GdbCodaEngine::handleAndReportSetBreakpoint(const CodaCommandResult &result)
{
if (result) {
sendGdbServerMessage("OK");
@@ -1439,7 +1430,7 @@ void CodaGdbAdapter::handleAndReportSetBreakpoint(const CodaCommandResult &resul
}
}
void CodaGdbAdapter::handleClearBreakpoint(const CodaCommandResult &result)
void GdbCodaEngine::handleClearBreakpoint(const CodaCommandResult &result)
{
logMessage(QLatin1String("CLEAR BREAKPOINT "));
if (!result)
@@ -1448,7 +1439,7 @@ void CodaGdbAdapter::handleClearBreakpoint(const CodaCommandResult &result)
sendGdbServerMessage("OK");
}
void CodaGdbAdapter::readMemory(uint addr, uint len, bool buffered)
void GdbCodaEngine::readMemory(uint addr, uint len, bool buffered)
{
Q_ASSERT(len < (2 << 16));
@@ -1467,16 +1458,16 @@ static QString msgMemoryReadError(uint addr, uint len = 0)
return _("Memory read error at: 0x%1 %2").arg(addr, 0, 16).arg(lenS);
}
void CodaGdbAdapter::sendMemoryGetCommand(const MemoryRange &range, bool buffered)
void GdbCodaEngine::sendMemoryGetCommand(const MemoryRange &range, bool buffered)
{
const QVariant cookie = QVariant::fromValue(range);
const CodaCallback cb = buffered ?
CodaCallback(this, &CodaGdbAdapter::handleReadMemoryBuffered) :
CodaCallback(this, &CodaGdbAdapter::handleReadMemoryUnbuffered);
CodaCallback(this, &GdbCodaEngine::handleReadMemoryBuffered) :
CodaCallback(this, &GdbCodaEngine::handleReadMemoryUnbuffered);
m_codaDevice->sendMemoryGetCommand(cb, currentThreadContextId(), range.from, range.size(), cookie);
}
void CodaGdbAdapter::handleReadMemoryBuffered(const CodaCommandResult &result)
void GdbCodaEngine::handleReadMemoryBuffered(const CodaCommandResult &result)
{
QTC_ASSERT(qVariantCanConvert<MemoryRange>(result.cookie), return);
@@ -1502,7 +1493,7 @@ void CodaGdbAdapter::handleReadMemoryBuffered(const CodaCommandResult &result)
tryAnswerGdbMemoryRequest(true);
}
void CodaGdbAdapter::handleReadMemoryUnbuffered(const CodaCommandResult &result)
void GdbCodaEngine::handleReadMemoryUnbuffered(const CodaCommandResult &result)
{
QTC_ASSERT(qVariantCanConvert<MemoryRange>(result.cookie), return);
@@ -1526,7 +1517,7 @@ void CodaGdbAdapter::handleReadMemoryUnbuffered(const CodaCommandResult &result)
tryAnswerGdbMemoryRequest(false);
}
void CodaGdbAdapter::tryAnswerGdbMemoryRequest(bool buffered)
void GdbCodaEngine::tryAnswerGdbMemoryRequest(bool buffered)
{
//logMessage("TRYING TO ANSWER MEMORY REQUEST ");
MemoryRange wanted = m_snapshot.wantedMemory;
@@ -1588,7 +1579,7 @@ void CodaGdbAdapter::tryAnswerGdbMemoryRequest(bool buffered)
}
}
void CodaGdbAdapter::handleWriteMemory(const CodaCommandResult &result)
void GdbCodaEngine::handleWriteMemory(const CodaCommandResult &result)
{
if (result) {
sendGdbServerMessage("OK", "Write memory");
@@ -1598,17 +1589,17 @@ void CodaGdbAdapter::handleWriteMemory(const CodaCommandResult &result)
}
}
QByteArray CodaGdbAdapter::mainThreadContextId() const
QByteArray GdbCodaEngine::mainThreadContextId() const
{
return RunControlContext::codaId(m_session.pid, m_session.mainTid);
}
QByteArray CodaGdbAdapter::currentThreadContextId() const
QByteArray GdbCodaEngine::currentThreadContextId() const
{
return RunControlContext::codaId(m_session.pid, m_session.tid);
}
void CodaGdbAdapter::sendContinue()
void GdbCodaEngine::sendContinue()
{
// Remove all but main thread as we do not know whether they will exist
// at the next stop.
@@ -1617,7 +1608,7 @@ void CodaGdbAdapter::sendContinue()
m_codaDevice->sendRunControlResumeCommand(CodaCallback(), m_codaProcessId);
}
void CodaGdbAdapter::sendStepRange()
void GdbCodaEngine::sendStepRange()
{
uint from = m_snapshot.lineFromAddress;
uint to = m_snapshot.lineToAddress;
@@ -1638,12 +1629,12 @@ void CodaGdbAdapter::sendStepRange()
logMessage(_("Stepping from 0x%1 to 0x%2 (current PC=0x%3), mode %4").
arg(from, 0, 16).arg(to, 0, 16).arg(pc).arg(int(mode)));
m_codaDevice->sendRunControlResumeCommand(
CodaCallback(this, &CodaGdbAdapter::handleStep),
CodaCallback(this, &GdbCodaEngine::handleStep),
currentThreadContextId(),
mode, 1, from, to);
}
void CodaGdbAdapter::handleStep(const CodaCommandResult &result)
void GdbCodaEngine::handleStep(const CodaCommandResult &result)
{
if (!result) { // Try fallback with Continue.
logMessage(QString::fromLatin1("Error while stepping: %1 (fallback to 'continue')").
+9 -10
View File
@@ -33,7 +33,7 @@
#ifndef DEBUGGER_CODAGDBADAPTER_H
#define DEBUGGER_CODAGDBADAPTER_H
#include "abstractgdbadapter.h"
#include "gdbengine.h"
#include "localgdbprocess.h"
#include "callback.h"
#include "codautils.h"
@@ -73,7 +73,7 @@ struct GdbResult;
//
///////////////////////////////////////////////////////////////////////
class CodaGdbAdapter : public AbstractGdbAdapter
class GdbCodaEngine : public GdbEngine
{
Q_OBJECT
@@ -82,8 +82,10 @@ public:
typedef Coda::Callback<const Coda::CodaCommandResult &> CodaCallback;
typedef Coda::Callback<const GdbResponse &> GdbCallback;
explicit CodaGdbAdapter(GdbEngine *engine);
~CodaGdbAdapter();
GdbCodaEngine(const DebuggerStartParameters &startParameters,
DebuggerEngine *masterEngine);
~GdbCodaEngine();
void setGdbServerName(const QString &name);
QString gdbServerName() const { return m_gdbServerName; }
@@ -110,13 +112,12 @@ public:
private:
void setupDeviceSignals();
void startAdapter();
void handleGdbStartDone();
void setupEngine();
void handleGdbStartFailed();
void setupInferior();
void runEngine();
void interruptInferior();
void shutdownAdapter();
void interruptInferior2();
void shutdownEngine();
void sendRunControlTerminateCommand();
void handleRunControlTerminate(const Coda::CodaCommandResult &);
void sendRegistersGetMCommand();
@@ -159,8 +160,6 @@ private:
Q_SLOT void readGdbServerCommand();
Q_SLOT void codaDeviceError(const QString &);
Q_SLOT void codaDeviceRemoved(const SymbianUtils::SymbianDevice &dev);
void startGdb();
Q_SLOT void codaEvent(const Coda::CodaEvent &knownEvent);
void handleCodaRunControlModuleLoadContextSuspendedEvent(const Coda::CodaRunControlModuleLoadContextSuspendedEvent &e);
inline void sendContinue();
+34 -58
View File
@@ -56,7 +56,7 @@ namespace Debugger {
namespace Internal {
#define CB(callback) \
static_cast<GdbEngine::AdapterCallback>(&CoreGdbAdapter::callback), \
static_cast<GdbEngine::GdbCommandCallback>(&GdbCoreEngine::callback), \
STRINGIFY(callback)
///////////////////////////////////////////////////////////////////////
@@ -65,11 +65,12 @@ namespace Internal {
//
///////////////////////////////////////////////////////////////////////
CoreGdbAdapter::CoreGdbAdapter(GdbEngine *engine)
: AbstractGdbAdapter(engine)
GdbCoreEngine::GdbCoreEngine(const DebuggerStartParameters &startParameters,
DebuggerEngine *masterEngine)
: GdbEngine(startParameters, masterEngine)
{}
CoreGdbAdapter::~CoreGdbAdapter()
GdbCoreEngine::~GdbCoreEngine()
{
if (false && !m_tempCoreName.isEmpty()) {
QFile tmpFile(m_tempCoreName);
@@ -77,7 +78,7 @@ CoreGdbAdapter::~CoreGdbAdapter()
}
}
void CoreGdbAdapter::startAdapter()
void GdbCoreEngine::setupEngine()
{
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
showMessage(_("TRYING TO START ADAPTER"));
@@ -90,7 +91,7 @@ void CoreGdbAdapter::startAdapter()
unpackCoreIfNeeded();
}
void CoreGdbAdapter::continueAdapterStart()
void GdbCoreEngine::continueSetupEngine()
{
if (m_executable.isEmpty()) {
// Read executable from core.
@@ -102,7 +103,7 @@ void CoreGdbAdapter::continueAdapterStart()
showMessageBox(QMessageBox::Warning,
tr("Error Loading Core File"),
tr("The specified file does not appear to be a core file."));
m_engine->notifyEngineSetupFailed();
notifyEngineSetupFailed();
return;
}
@@ -114,46 +115,30 @@ void CoreGdbAdapter::continueAdapterStart()
showMessageBox(QMessageBox::Warning,
tr("Error Loading Symbols"),
tr("No executable to load symbols from specified core."));
m_engine->notifyEngineSetupFailed();
notifyEngineSetupFailed();
return;
}
}
m_engine->startGdb();
startGdb();
}
void CoreGdbAdapter::handleGdbStartFailed()
{
}
void CoreGdbAdapter::handleGdbStartDone()
{
m_engine->handleAdapterStarted();
}
void CoreGdbAdapter::setupInferior()
void GdbCoreEngine::setupInferior()
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
// Do that first, otherwise no symbols are loaded.
QFileInfo fi(m_executable);
const QByteArray sysroot = startParameters().sysroot.toLocal8Bit();
QByteArray path = fi.absoluteFilePath().toLocal8Bit();
if (!sysroot.isEmpty()) {
m_engine->postCommand("set sysroot " + sysroot);
// sysroot is not enough to correctly locate the sources, so explicitly
// relocate the most likely place for the debug source
m_engine->postCommand("set substitute-path /usr/src " + sysroot + "/usr/src");
}
m_engine->postCommand("-file-exec-and-symbols \"" + path + '"',
postCommand("-file-exec-and-symbols \"" + path + '"',
CB(handleFileExecAndSymbols));
}
void CoreGdbAdapter::handleFileExecAndSymbols(const GdbResponse &response)
void GdbCoreEngine::handleFileExecAndSymbols(const GdbResponse &response)
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
QString core = coreFileName();
if (response.resultClass == GdbResultDone) {
showMessage(tr("Symbols found."), StatusBar);
m_engine->postCommand("target core " + core.toLocal8Bit(),
postCommand("target core " + core.toLocal8Bit(),
CB(handleTargetCore));
return;
}
@@ -165,68 +150,59 @@ void CoreGdbAdapter::handleFileExecAndSymbols(const GdbResponse &response)
msg += _(" ");
msg += tr("Try to specify the binary using the "
"<i>Debug->Start Debugging->Attach to Core</i> dialog.");
m_engine->notifyInferiorSetupFailed(msg);
notifyInferiorSetupFailed(msg);
}
void CoreGdbAdapter::handleTargetCore(const GdbResponse &response)
void GdbCoreEngine::handleTargetCore(const GdbResponse &response)
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
if (response.resultClass == GdbResultDone) {
// HACK: The namespace is not accessible in the initial run.
m_engine->loadPythonDumpers();
loadPythonDumpers();
showMessage(tr("Attached to core."), StatusBar);
m_engine->handleInferiorPrepared();
handleInferiorPrepared();
// Due to the auto-solib-add off setting, we don't have any
// symbols yet. Load them in order of importance.
m_engine->reloadStack(true);
m_engine->postCommand("info shared", CB(handleModulesList));
reloadStack(true);
reloadModulesInternal();
postCommand("p 5", CB(handleRoundTrip));
return;
}
QString msg = tr("Attach to core \"%1\" failed:\n")
.arg(startParameters().coreFile)
+ QString::fromLocal8Bit(response.data.findChild("msg").data());
m_engine->notifyInferiorSetupFailed(msg);
notifyInferiorSetupFailed(msg);
}
void CoreGdbAdapter::handleModulesList(const GdbResponse &response)
void GdbCoreEngine::handleRoundTrip(const GdbResponse &response)
{
m_engine->handleModulesList(response);
Q_UNUSED(response);
loadSymbolsForStack();
}
void CoreGdbAdapter::loadSymbolsForStack()
{
m_engine->loadSymbolsForStack();
QTimer::singleShot(1000, this, SLOT(loadAllSymbols()));
}
void CoreGdbAdapter::loadAllSymbols()
{
m_engine->loadAllSymbols();
}
void CoreGdbAdapter::runEngine()
void GdbCoreEngine::runEngine()
{
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
m_engine->notifyInferiorUnrunnable();
m_engine->updateAll();
notifyInferiorUnrunnable();
updateAll();
}
void CoreGdbAdapter::interruptInferior()
void GdbCoreEngine::interruptInferior()
{
// A core never runs, so this cannot be called.
QTC_CHECK(false);
}
void CoreGdbAdapter::shutdownAdapter()
void GdbCoreEngine::shutdownEngine()
{
m_engine->notifyAdapterShutdownOk();
notifyAdapterShutdownOk();
}
void CoreGdbAdapter::unpackCoreIfNeeded()
void GdbCoreEngine::unpackCoreIfNeeded()
{
if (!m_coreName.endsWith(QLatin1String(".lzo"))) {
continueAdapterStart();
continueSetupEngine();
return;
}
@@ -240,10 +216,10 @@ void CoreGdbAdapter::unpackCoreIfNeeded()
QProcess *process = new QProcess(this);
process->setWorkingDirectory(QDir::tempPath());
process->start("/usr/bin/lzop", QStringList() << "-o" << m_tempCoreName << "-x" << m_coreName);
connect(process, SIGNAL(finished(int)), SLOT(continueAdapterStart()));
connect(process, SIGNAL(finished(int)), SLOT(continueSetupEngine()));
}
QString CoreGdbAdapter::coreFileName() const
QString GdbCoreEngine::coreFileName() const
{
return m_tempCoreName.isEmpty() ? m_coreName : m_tempCoreName;
}
+9 -13
View File
@@ -33,7 +33,7 @@
#ifndef DEBUGGER_COREGDBADAPTER_H
#define DEBUGGER_COREGDBADAPTER_H
#include "abstractgdbadapter.h"
#include "gdbengine.h"
#include "localgdbprocess.h"
namespace Debugger {
@@ -45,36 +45,32 @@ namespace Internal {
//
///////////////////////////////////////////////////////////////////////
class CoreGdbAdapter : public AbstractGdbAdapter
class GdbCoreEngine : public GdbEngine
{
Q_OBJECT
public:
explicit CoreGdbAdapter(GdbEngine *engine);
~CoreGdbAdapter();
GdbCoreEngine(const DebuggerStartParameters &startParameters,
DebuggerEngine *masterEngine);
~GdbCoreEngine();
private:
DumperHandling dumperHandling() const { return DumperNotAvailable; }
void startAdapter();
void handleGdbStartDone();
void handleGdbStartFailed();
void setupEngine();
void setupInferior();
void runEngine();
void interruptInferior();
void shutdownAdapter();
Q_SLOT void loadSymbolsForStack();
Q_SLOT void loadAllSymbols();
void shutdownEngine();
AbstractGdbProcess *gdbProc() { return &m_gdbProc; }
void handleFileExecAndSymbols(const GdbResponse &response);
void handleTargetCore(const GdbResponse &response);
void handleModulesList(const GdbResponse &response);
void handleRoundTrip(const GdbResponse &response);
void unpackCoreIfNeeded();
QString coreFileName() const;
Q_SLOT void continueAdapterStart();
Q_SLOT void continueSetupEngine();
QString coreName() const;
QString m_executable;
-2
View File
@@ -2,7 +2,6 @@ HEADERS += \
$$PWD/gdbmi.h \
$$PWD/gdbengine.h \
$$PWD/gdboptionspage.h \
$$PWD/abstractgdbadapter.h \
$$PWD/attachgdbadapter.h \
$$PWD/coregdbadapter.h \
$$PWD/localplaingdbadapter.h \
@@ -22,7 +21,6 @@ SOURCES += \
$$PWD/classicgdbengine.cpp \
$$PWD/pythongdbengine.cpp \
$$PWD/gdboptionspage.cpp \
$$PWD/abstractgdbadapter.cpp \
$$PWD/attachgdbadapter.cpp \
$$PWD/coregdbadapter.cpp \
$$PWD/localplaingdbadapter.cpp \
+186 -174
View File
@@ -69,6 +69,7 @@
#include "debuggersourcepathmappingwidget.h"
#include "hostutils.h"
#include "logwindow.h"
#include "procinterrupt.h"
#include <coreplugin/icore.h>
#include <coreplugin/idocument.h>
@@ -78,8 +79,9 @@
#include <projectexplorer/taskhub.h>
#include <projectexplorer/itaskhandler.h>
#include <texteditor/itexteditor.h>
#include <utils/qtcassert.h>
#include <utils/elfreader.h>
#include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
#include <QCoreApplication>
#include <QDebug>
@@ -243,7 +245,6 @@ GdbEngine::GdbEngine(const DebuggerStartParameters &startParameters,
setObjectName(_("GdbEngine"));
m_busy = false;
m_gdbAdapter = 0;
m_debuggingHelperState = DebuggingHelperUninitialized;
m_gdbVersion = 100;
m_gdbBuildVersion = -1;
@@ -268,8 +269,6 @@ GdbEngine::GdbEngine(const DebuggerStartParameters &startParameters,
invalidateSourcesList();
m_gdbAdapter = createAdapter();
m_debugInfoTaskHandler = new DebugInfoTaskHandler(this);
ExtensionSystem::PluginManager::instance()->addObject(m_debugInfoTaskHandler);
@@ -280,16 +279,10 @@ GdbEngine::GdbEngine(const DebuggerStartParameters &startParameters,
SLOT(reloadLocals()));
connect(debuggerCore()->action(CreateFullBacktrace), SIGNAL(triggered()),
SLOT(createFullBacktrace()));
}
DebuggerStartMode GdbEngine::startMode() const
{
return startParameters().startMode;
}
AbstractGdbProcess *GdbEngine::gdbProc() const
{
return m_gdbAdapter->gdbProc();
connect(debuggerCore()->action(UseDebuggingHelpers), SIGNAL(valueChanged(QVariant)),
SLOT(reloadLocals()));
connect(debuggerCore()->action(UseDynamicType), SIGNAL(valueChanged(QVariant)),
SLOT(reloadLocals()));
}
GdbEngine::~GdbEngine()
@@ -299,10 +292,12 @@ GdbEngine::~GdbEngine()
m_debugInfoTaskHandler = 0;
// Prevent sending error messages afterwards.
if (m_gdbAdapter)
disconnect(gdbProc(), 0, this, 0);
delete m_gdbAdapter;
m_gdbAdapter = 0;
disconnect();
}
DebuggerStartMode GdbEngine::startMode() const
{
return startParameters().startMode;
}
QString GdbEngine::errorMessage(QProcess::ProcessError error)
@@ -396,11 +391,9 @@ static bool contains(const QByteArray &message, const char *pattern, int size)
const int pos = message.indexOf(pattern);
if (pos == -1)
return false;
if (pos != 0 && message.at(pos - 1) != '\n')
return false;
if (pos + size != s && message.at(pos + size + 1) != '\n')
return false;
return true;
const bool beginFits = pos == 0 || message.at(pos - 1) == '\n';
const bool endFits = pos + size == s || message.at(pos + size) == '\n';
return beginFits && endFits;
}
static bool isGdbConnectionError(const QByteArray &message)
@@ -856,7 +849,7 @@ void GdbEngine::interruptInferior()
} else {
showStatusMessage(tr("Stop requested..."), 5000);
showMessage(_("TRYING TO INTERRUPT INFERIOR"));
m_gdbAdapter->interruptInferior();
interruptInferior2();
}
}
@@ -885,25 +878,6 @@ void GdbEngine::maybeHandleInferiorPidChanged(const QString &pid0)
notifyInferiorPid(pid);
}
void GdbEngine::postCommand(const QByteArray &command, AdapterCallback callback,
const char *callbackName, const QVariant &cookie)
{
postCommand(command, NoFlags, callback, callbackName, cookie);
}
void GdbEngine::postCommand(const QByteArray &command, GdbCommandFlags flags,
AdapterCallback callback,
const char *callbackName, const QVariant &cookie)
{
GdbCommand cmd;
cmd.command = command;
cmd.flags = flags;
cmd.adapterCallback = callback;
cmd.callbackName = callbackName;
cmd.cookie = cookie;
postCommandHelper(cmd);
}
void GdbEngine::postCommand(const QByteArray &command, GdbCommandCallback callback,
const char *callbackName, const QVariant &cookie)
{
@@ -1021,7 +995,7 @@ void GdbEngine::flushCommand(const GdbCommand &cmd0)
QMetaObject::invokeMethod(this, "handleResponse",
Q_ARG(QByteArray, buffer));
} else {
m_gdbAdapter->write(cmd.command + "\r\n");
write(cmd.command + "\r\n");
// Start Watchdog.
if (m_commandTimer.interval() <= 20000)
@@ -1226,8 +1200,6 @@ void GdbEngine::handleResultRecord(GdbResponse *response)
if (cmd.callback)
(this->*cmd.callback)(*response);
else if (cmd.adapterCallback)
(m_gdbAdapter->*cmd.adapterCallback)(*response);
if (cmd.flags & RebuildBreakpointModel) {
--m_pendingBreakpointRequests;
@@ -1595,7 +1567,7 @@ void GdbEngine::handleStop1(const GdbMi &data)
// Don't load helpers on stops triggered by signals unless it's
// an intentional trap.
if (initHelpers
&& m_gdbAdapter->dumperHandling() != AbstractGdbAdapter::DumperLoadedByGdbPreload
&& dumperHandling() != DumperLoadedByGdbPreload
&& reason == "signal-received") {
const QByteArray name = data.findChild("signal-name").data();
const DebuggerStartParameters &sp = startParameters();
@@ -1775,8 +1747,8 @@ void GdbEngine::handleStop2()
reloadStack(false); // Will trigger register reload.
if (supportsThreads()) {
if (m_gdbAdapter->isCodaAdapter()) {
m_gdbAdapter->codaReloadThreads();
if (isCodaAdapter()) {
codaReloadThreads();
} else if (m_isMacGdb || m_gdbVersion < 70100) {
postCommand("-thread-list-ids", Discardable, CB(handleThreadListIds));
} else {
@@ -1875,8 +1847,7 @@ void GdbEngine::pythonDumpersFailed()
{
m_hasPython = false;
const DebuggerStartParameters &sp = startParameters();
if (m_gdbAdapter->dumperHandling() == AbstractGdbAdapter::DumperLoadedByGdbPreload
&& checkDebuggingHelpersClassic()) {
if (dumperHandling() == DumperLoadedByGdbPreload && checkDebuggingHelpersClassic()) {
QByteArray cmd = "set environment ";
if (sp.toolChainAbi.os() == Abi::MacOS)
cmd += "DYLD_INSERT_LIBRARIES";
@@ -2031,15 +2002,10 @@ void GdbEngine::handleInferiorShutdown(const GdbResponse &response)
}
showMessageBox(QMessageBox::Critical,
tr("Failed to shut down application"),
AbstractGdbAdapter::msgInferiorStopFailed(QString::fromLocal8Bit(ba)));
msgInferiorStopFailed(QString::fromLocal8Bit(ba)));
notifyInferiorShutdownFailed();
}
void GdbEngine::shutdownEngine()
{
m_gdbAdapter->shutdownAdapter();
}
void GdbEngine::notifyAdapterShutdownFailed()
{
showMessage(_("ADAPTER SHUTDOWN FAILED"));
@@ -2076,7 +2042,7 @@ void GdbEngine::handleGdbExit(const GdbResponse &response)
// Don't set state here, this will be handled in handleGdbFinished()
//notifyEngineShutdownOk();
} else {
QString msg = m_gdbAdapter->msgGdbStopFailed(
QString msg = msgGdbStopFailed(
QString::fromLocal8Bit(response.data.findChild("msg").data()));
qDebug() << (_("GDB WON'T EXIT (%1); KILLING IT").arg(msg));
showMessage(_("GDB WON'T EXIT (%1); KILLING IT").arg(msg));
@@ -2121,50 +2087,6 @@ QString msgNoGdbBinaryForToolChain(const Abi &tc)
.arg(tc.toString());
}
AbstractGdbAdapter *GdbEngine::createAdapter()
{
const DebuggerStartParameters &sp = startParameters();
if (sp.toolChainAbi.os() == Abi::SymbianOS) {
// FIXME: 1 of 3 testing hacks.
return new CodaGdbAdapter(this);
}
switch (sp.startMode) {
case AttachCore:
return new CoreGdbAdapter(this);
case AttachToRemoteServer:
return new RemoteGdbServerAdapter(this);
case StartRemoteGdb:
return new RemotePlainGdbAdapter(this);
case AttachExternal:
return new AttachGdbAdapter(this);
default:
if (sp.useTerminal)
return new TermGdbAdapter(this);
return new LocalPlainGdbAdapter(this);
}
}
void GdbEngine::setupEngine()
{
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
QTC_CHECK(m_debuggingHelperState == DebuggingHelperUninitialized);
if (m_gdbAdapter->dumperHandling() != AbstractGdbAdapter::DumperNotAvailable) {
connect(debuggerCore()->action(UseDebuggingHelpers),
SIGNAL(valueChanged(QVariant)),
SLOT(reloadLocals()));
connect(debuggerCore()->action(UseDynamicType),
SIGNAL(valueChanged(QVariant)),
SLOT(reloadLocals()));
}
QTC_CHECK(state() == EngineSetupRequested);
if (debuggerCore()->boolSetting(WarnOnReleaseBuilds))
checkForReleaseBuild();
m_gdbAdapter->startAdapter();
}
bool GdbEngine::hasCapability(unsigned cap) const
{
if (cap & (ReverseSteppingCapability
@@ -2237,7 +2159,7 @@ void GdbEngine::executeStep()
setTokenBarrier();
notifyInferiorRunRequested();
showStatusMessage(tr("Step requested..."), 5000);
if (m_gdbAdapter->isCodaAdapter() && stackHandler()->stackSize() > 0)
if (isCodaAdapter() && stackHandler()->stackSize() > 0)
postCommand("sal step,0x" + QByteArray::number(stackHandler()->topAddress(), 16));
if (isReverseDebugging()) {
postCommand("reverse-step", RunRequest, CB(handleExecuteStep));
@@ -2311,7 +2233,7 @@ void GdbEngine::executeNext()
setTokenBarrier();
notifyInferiorRunRequested();
showStatusMessage(tr("Step next requested..."), 5000);
if (m_gdbAdapter->isCodaAdapter() && stackHandler()->stackSize() > 0)
if (isCodaAdapter() && stackHandler()->stackSize() > 0)
postCommand("sal next,0x" + QByteArray::number(stackHandler()->topAddress(), 16));
if (isReverseDebugging()) {
postCommand("reverse-next", RunRequest, CB(handleExecuteNext));
@@ -3206,7 +3128,7 @@ void GdbEngine::insertBreakpoint(BreakpointModelId id)
cmd = "-break-insert -a -f ";
} else if (m_isMacGdb) {
cmd = "-break-insert -l -1 -f ";
} else if (m_gdbAdapter->isCodaAdapter()) {
} else if (isCodaAdapter()) {
cmd = "-break-insert -h -f ";
} else if (m_gdbVersion >= 70000) {
int spec = handler->threadSpec(id);
@@ -3591,7 +3513,7 @@ void GdbEngine::reloadStack(bool forceGotoLocation)
PENDING_DEBUG("RELOAD STACK");
QByteArray cmd = "-stack-list-frames";
int stackDepth = debuggerCore()->action(MaximalStackDepth)->value().toInt();
if (stackDepth && !m_gdbAdapter->isCodaAdapter())
if (stackDepth && !isCodaAdapter())
cmd += " 0 " + QByteArray::number(stackDepth);
postCommand(cmd, Discardable, CB(handleStackListFrames),
QVariant::fromValue<StackCookie>(StackCookie(false, forceGotoLocation)));
@@ -3832,12 +3754,12 @@ void GdbEngine::reloadRegisters()
postCommand("-data-list-register-names", CB(handleRegisterListNames));
m_registerNamesListed = true;
// FIXME: Maybe better completely re-do this logic in CODA adapter.
if (m_gdbAdapter->isCodaAdapter())
if (isCodaAdapter())
return;
}
if (m_gdbAdapter->isCodaAdapter()) {
m_gdbAdapter->codaReloadRegisters();
if (isCodaAdapter()) {
codaReloadRegisters();
} else {
postCommand("-data-list-register-values r",
Discardable, CB(handleRegisterListValues));
@@ -3865,8 +3787,8 @@ void GdbEngine::handleRegisterListNames(const GdbResponse &response)
registerHandler()->setRegisters(registers);
if (m_gdbAdapter->isCodaAdapter())
m_gdbAdapter->codaReloadRegisters();
if (isCodaAdapter())
codaReloadRegisters();
}
void GdbEngine::handleRegisterListValues(const GdbResponse &response)
@@ -4047,7 +3969,7 @@ bool GdbEngine::hasDebuggingHelperForType(const QByteArray &type) const
if (!debuggerCore()->boolSetting(UseDebuggingHelpers))
return false;
if (m_gdbAdapter->dumperHandling() == AbstractGdbAdapter::DumperNotAvailable) {
if (dumperHandling() == DumperNotAvailable) {
// Inferior calls are not possible in gdb when looking at core files.
return type == "QString" || type.endsWith("::QString")
|| type == "QStringList" || type.endsWith("::QStringList");
@@ -4760,7 +4682,7 @@ void GdbEngine::startGdb(const QStringList &args)
const DebuggerStartParameters &sp = startParameters();
m_gdb = gdbBinary(sp);
if (m_gdb.isEmpty()) {
m_gdbAdapter->handleGdbStartFailed();
handleGdbStartFailed();
handleAdapterStartFailed(
msgNoGdbBinaryForToolChain(sp.toolChainAbi),
_(Constants::DEBUGGER_COMMON_SETTINGS_ID));
@@ -4786,7 +4708,7 @@ void GdbEngine::startGdb(const QStringList &args)
gdbProc()->start(m_gdb, gdbArgs);
if (!gdbProc()->waitForStarted()) {
m_gdbAdapter->handleGdbStartFailed();
handleGdbStartFailed();
const QString msg = errorMessage(QProcess::FailedToStart);
handleAdapterStartFailed(msg);
return;
@@ -4866,6 +4788,47 @@ void GdbEngine::startGdb(const QStringList &args)
"AN ERROR IS EXPECTED."));
postCommand("disassemble 0 0", ConsoleCommand, CB(handleDisassemblerCheck));
typedef GlobalDebuggerOptions::SourcePathMap SourcePathMap;
typedef SourcePathMap::const_iterator SourcePathMapIterator;
if (debuggerCore()->boolSetting(WarnOnReleaseBuilds))
checkForReleaseBuild();
showStatusMessage(tr("Setting up inferior..."));
// Addint executable to modules list.
Module module;
module.startAddress = 0;
module.endAddress = 0;
module.modulePath = sp.executable;
module.moduleName = QLatin1String("<executable>");
modulesHandler()->updateModule(module);
// Apply source path mappings from global options.
const SourcePathMap sourcePathMap =
DebuggerSourcePathMappingWidget::mergePlatformQtPath(sp.qtInstallPath,
debuggerCore()->globalDebuggerOptions()->sourcePathMap);
const SourcePathMapIterator cend = sourcePathMap.constEnd();
SourcePathMapIterator it = sourcePathMap.constBegin();
for ( ; it != cend; ++it)
postCommand("set substitute-path " + it.key().toLocal8Bit()
+ " " + it.value().toLocal8Bit());
// Spaces just will not work.
foreach (const QString &src, sp.debugSourceLocation)
postCommand("directory " + src.toLocal8Bit());
const QByteArray sysroot = sp.sysroot.toLocal8Bit();
if (!sysroot.isEmpty()) {
postCommand("set sysroot " + sysroot);
// sysroot is not enough to correctly locate the sources, so explicitly
// relocate the most likely place for the debug source
postCommand("set substitute-path /usr/src " + sysroot + "/usr/src");
}
//QByteArray ba = QFileInfo(sp.dumperLibrary).path().toLocal8Bit();
//if (!ba.isEmpty())
// postCommand("set solib-search-path " + ba);
if (attemptQuickStart()) {
postCommand("set auto-solib-add off", ConsoleCommand);
} else {
@@ -4875,15 +4838,22 @@ void GdbEngine::startGdb(const QStringList &args)
}
// Dummy command to guarantee a roundtrip before the adapter proceed.
postCommand("pwd", ConsoleCommand, CB(handleGdbStart));
postCommand("pwd", ConsoleCommand, CB(reportEngineSetupOk));
}
void GdbEngine::handleGdbStart(const GdbResponse &response)
void GdbEngine::reportEngineSetupOk(const GdbResponse &response)
{
Q_UNUSED(response);
m_gdbAdapter->handleGdbStartDone();
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
showMessage(_("ENGINE SUCCESSFULLY STARTED"));
notifyEngineSetupOk();
}
void GdbEngine::handleGdbStartFailed()
{
}
void GdbEngine::loadInitScript()
{
const QString script = startParameters().overrideStartScript;
@@ -4982,9 +4952,8 @@ void GdbEngine::abortDebugger()
if (targetState() == DebuggerFinished) {
// We already tried. Try harder.
showMessage(_("ABORTING DEBUGGER. SECOND TIME."));
QTC_ASSERT(m_gdbAdapter, return);
QTC_ASSERT(m_gdbAdapter->gdbProc(), return);
m_gdbAdapter->gdbProc()->kill();
QTC_ASSERT(gdbProc(), return);
gdbProc()->kill();
} else {
// Be friendly the first time. This will change targetState().
showMessage(_("ABORTING DEBUGGER. FIRST TIME."));
@@ -5009,50 +4978,6 @@ void GdbEngine::handleAdapterStartFailed(const QString &msg,
notifyEngineSetupFailed();
}
void GdbEngine::handleAdapterStarted()
{
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
showMessage(_("ADAPTER SUCCESSFULLY STARTED"));
notifyEngineSetupOk();
Module module;
module.startAddress = 0;
module.endAddress = 0;
module.modulePath = startParameters().executable;
module.moduleName = QLatin1String("<executable>");
modulesHandler()->updateModule(module);
}
void GdbEngine::setupInferior()
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
typedef GlobalDebuggerOptions::SourcePathMap SourcePathMap;
typedef SourcePathMap::const_iterator SourcePathMapIterator;
showStatusMessage(tr("Setting up inferior..."));
const DebuggerStartParameters &sp = startParameters();
// Apply source path mappings from global options.
const SourcePathMap sourcePathMap =
DebuggerSourcePathMappingWidget::mergePlatformQtPath(sp.qtInstallPath,
debuggerCore()->globalDebuggerOptions()->sourcePathMap);
const SourcePathMapIterator cend = sourcePathMap.constEnd();
SourcePathMapIterator it = sourcePathMap.constBegin();
for ( ; it != cend; ++it)
postCommand("set substitute-path " + it.key().toLocal8Bit()
+ " " + it.value().toLocal8Bit());
// Spaces just will not work.
foreach (const QString &src, sp.debugSourceLocation)
postCommand("directory " + src.toLocal8Bit());
//QByteArray ba = QFileInfo(sp.dumperLibrary).path().toLocal8Bit();
//if (!ba.isEmpty())
// postCommand("set solib-search-path " + ba);
m_gdbAdapter->setupInferior();
}
void GdbEngine::notifyInferiorSetupFailed()
{
// FIXME: that's not enough to stop gdb from getting confused
@@ -5172,12 +5097,6 @@ void GdbEngine::handleBreakOnQFatal(const GdbResponse &response)
notifyInferiorSetupOk();
}
void GdbEngine::runEngine()
{
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
m_gdbAdapter->runEngine();
}
void GdbEngine::notifyInferiorSetupFailed(const QString &msg)
{
showStatusMessage(tr("Failed to start application: ") + msg);
@@ -5246,14 +5165,15 @@ void GdbEngine::resetCommandQueue()
void GdbEngine::handleRemoteSetupDone(int gdbServerPort, int qmlPort)
{
Q_UNUSED(gdbServerPort);
Q_UNUSED(qmlPort);
notifyEngineRemoteSetupDone();
m_gdbAdapter->handleRemoteSetupDone(gdbServerPort, qmlPort);
}
void GdbEngine::handleRemoteSetupFailed(const QString &message)
{
Q_UNUSED(message);
notifyEngineRemoteSetupFailed();
m_gdbAdapter->handleRemoteSetupFailed(message);
}
bool GdbEngine::setupQmlStep(bool on)
@@ -5421,14 +5341,106 @@ void GdbEngine::checkForReleaseBuild()
showMessageBox(QMessageBox::Information, tr("Warning"), warning);
}
void GdbEngine::write(const QByteArray &data)
{
gdbProc()->write(data);
}
bool GdbEngine::isCodaAdapter() const
{
return false;
}
bool GdbEngine::prepareCommand()
{
#ifdef Q_OS_WIN
Utils::QtcProcess::SplitError perr;
startParameters().processArgs = Utils::QtcProcess::prepareArgs(
startParameters().processArgs, &perr,
&startParameters().environment, &startParameters().workingDirectory);
if (perr != Utils::QtcProcess::SplitOk) {
// perr == BadQuoting is never returned on Windows
// FIXME? QTCREATORBUG-2809
handleAdapterStartFailed(QCoreApplication::translate("DebuggerEngine", // Same message in CdbEngine
"Debugging complex command lines is currently not supported on Windows."), QString());
return false;
}
#endif
return true;
}
QString GdbEngine::msgGdbStopFailed(const QString &why)
{
return tr("The gdb process could not be stopped:\n%1").arg(why);
}
QString GdbEngine::msgInferiorStopFailed(const QString &why)
{
return tr("Application process could not be stopped:\n%1").arg(why);
}
QString GdbEngine::msgInferiorSetupOk()
{
return tr("Application started");
}
QString GdbEngine::msgInferiorRunOk()
{
return tr("Application running");
}
QString GdbEngine::msgAttachedToStoppedInferior()
{
return tr("Attached to stopped application");
}
QString GdbEngine::msgConnectRemoteServerFailed(const QString &why)
{
return tr("Connecting to remote server failed:\n%1").arg(why);
}
void GdbEngine::interruptLocalInferior(qint64 pid)
{
QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state(); return);
if (pid <= 0) {
showMessage(QLatin1String("TRYING TO INTERRUPT INFERIOR BEFORE PID WAS OBTAINED"), LogError);
return;
}
QString errorMessage;
if (interruptProcess(pid, GdbEngineType, &errorMessage)) {
showMessage(QLatin1String("Interrupted ") + QString::number(pid));
} else {
showMessage(errorMessage, LogError);
notifyInferiorStopFailed();
}
}
//
// Factory
//
DebuggerEngine *createGdbEngine(const DebuggerStartParameters &startParameters,
DebuggerEngine *createGdbEngine(const DebuggerStartParameters &sp,
DebuggerEngine *masterEngine)
{
return new GdbEngine(startParameters, masterEngine);
if (sp.toolChainAbi.os() == Abi::SymbianOS) {
// FIXME: 1 of 3 testing hacks.
return new GdbCodaEngine(sp, masterEngine);
}
switch (sp.startMode) {
case AttachCore:
return new GdbCoreEngine(sp, masterEngine);
case AttachToRemoteServer:
return new GdbRemoteServerEngine(sp, masterEngine);
case StartRemoteGdb:
return new GdbRemotePlainEngine(sp, masterEngine);
case AttachExternal:
return new GdbAttachEngine(sp, masterEngine);
default:
if (sp.useTerminal)
return new GdbTermEngine(sp, masterEngine);
return new GdbLocalPlainEngine(sp, masterEngine);
}
}
void addGdbOptionPages(QList<Core::IOptionsPage *> *opts)
+49 -48
View File
@@ -56,24 +56,17 @@
namespace Debugger {
namespace Internal {
class AbstractGdbAdapter;
class AbstractGdbProcess;
class DebugInfoTask;
class DebugInfoTaskHandler;
class GdbResponse;
class GdbMi;
class GdbToolTipContext;
class Module;
class WatchData;
class DisassemblerAgentCookie;
class DisassemblerLines;
class AttachGdbAdapter;
class CoreGdbAdapter;
class LocalPlainGdbAdapter;
class RemoteGdbServerAdapter;
enum DebuggingHelperState
{
DebuggingHelperUninitialized,
@@ -207,30 +200,18 @@ public:
GdbEngine(const DebuggerStartParameters &startParameters,
DebuggerEngine *masterEngine);
~GdbEngine();
AbstractGdbAdapter *gdbAdapter() const { return m_gdbAdapter; }
private:
friend class AbstractGdbAdapter;
friend class AbstractPlainGdbAdapter;
friend class AttachGdbAdapter;
friend class CoreGdbAdapter;
friend class LocalPlainGdbAdapter;
friend class TermGdbAdapter;
friend class RemoteGdbServerAdapter;
friend class RemotePlainGdbAdapter;
friend class CodaGdbAdapter;
private: ////////// General Interface //////////
virtual void setupEngine();
virtual void setupInferior();
virtual void runEngine();
virtual void setupEngine() = 0;
virtual void handleGdbStartFailed();
virtual void setupInferior() = 0;
virtual void notifyInferiorSetupFailed();
virtual bool hasCapability(unsigned) const;
virtual void detachDebugger();
virtual void shutdownEngine();
virtual void shutdownInferior();
virtual void notifyInferiorSetupFailed();
virtual void shutdownEngine() = 0;
virtual void abortDebugger();
virtual bool acceptsDebuggerCommands() const;
@@ -246,18 +227,16 @@ private: ////////// General State //////////
bool m_registerNamesListed;
private: ////////// Gdb Process Management //////////
protected: ////////// Gdb Process Management //////////
AbstractGdbAdapter *createAdapter();
void startGdb(const QStringList &args = QStringList());
void handleGdbStart(const GdbResponse &response);
void reportEngineSetupOk(const GdbResponse &response);
void handleInferiorShutdown(const GdbResponse &response);
void handleGdbExit(const GdbResponse &response);
void handleRemoteSetupDone(int gdbServerPort, int qmlPort);
void handleRemoteSetupFailed(const QString &message);
void handleNamespaceExtraction(const GdbResponse &response);
void handleAdapterStarted();
void loadInitScript();
void loadPythonDumpers();
void pythonDumpersFailed();
@@ -299,8 +278,6 @@ private:
QByteArray m_inbuffer;
bool m_busy;
AbstractGdbAdapter *m_gdbAdapter;
// Name of the convenience variable containing the last
// known function return value.
QByteArray m_resultVarName;
@@ -330,22 +307,18 @@ private: ////////// Gdb Command Management //////////
ConsoleCommand = 512
};
Q_DECLARE_FLAGS(GdbCommandFlags, GdbCommandFlag)
private:
typedef void (GdbEngine::*GdbCommandCallback)
(const GdbResponse &response);
typedef void (AbstractGdbAdapter::*AdapterCallback)
(const GdbResponse &response);
protected:
typedef void (GdbEngine::*GdbCommandCallback)(const GdbResponse &response);
struct GdbCommand
{
GdbCommand()
: flags(0), callback(0), adapterCallback(0), callbackName(0)
: flags(0), callback(0), callbackName(0)
{}
int flags;
GdbCommandCallback callback;
AdapterCallback adapterCallback;
const char *callbackName;
QByteArray command;
QVariant cookie;
@@ -357,6 +330,7 @@ private: ////////// Gdb Command Management //////////
// send and decrements on receipt, effectively preventing
// watch model updates before everything is finished.
void flushCommand(const GdbCommand &cmd);
protected:
void postCommand(const QByteArray &command,
GdbCommandFlags flags,
GdbCommandCallback callback = 0,
@@ -366,15 +340,7 @@ private: ////////// Gdb Command Management //////////
GdbCommandCallback callback = 0,
const char *callbackName = 0,
const QVariant &cookie = QVariant());
void postCommand(const QByteArray &command,
AdapterCallback callback,
const char *callbackName,
const QVariant &cookie = QVariant());
void postCommand(const QByteArray &command,
GdbCommandFlags flags,
AdapterCallback callback,
const char *callbackName,
const QVariant &cookie = QVariant());
private:
void postCommandHelper(const GdbCommand &cmd);
void flushQueuedCommands();
Q_SLOT void commandTimeout();
@@ -407,7 +373,7 @@ private: ////////// Gdb Command Management //////////
void checkForReleaseBuild();
private: ////////// Gdb Output, State & Capability Handling //////////
protected:
Q_SLOT void handleResponse(const QByteArray &buff);
void handleStopResponse(const GdbMi &data);
void handleResultRecord(GdbResponse *response);
@@ -451,11 +417,13 @@ private: ////////// Inferior Management //////////
void executeStepI();
void executeNextI();
protected:
void continueInferiorInternal();
void doNotifyInferiorRunOk();
void autoContinueInferior();
void continueInferior();
void interruptInferior();
virtual void interruptInferior2() {}
void interruptInferiorTemporarily();
void executeRunToLine(const ContextData &data);
@@ -474,6 +442,7 @@ private: ////////// Inferior Management //////////
void handleInfoProc(const GdbResponse &response);
private: ////////// View & Data Stuff //////////
protected:
void selectThread(int index);
void activateFrame(int index);
@@ -509,7 +478,7 @@ private: ////////// View & Data Stuff //////////
// Modules specific stuff
//
void loadSymbols(const QString &moduleName);
void loadAllSymbols();
Q_SLOT void loadAllSymbols();
void loadSymbolsForStack();
void requestModuleSymbols(const QString &moduleName);
void reloadModules();
@@ -584,6 +553,7 @@ private: ////////// View & Data Stuff //////////
//
// Stack specific stuff
//
protected:
void updateAll();
void updateAllClassic();
void updateAllPython();
@@ -743,8 +713,39 @@ private: ////////// View & Data Stuff //////////
bool m_forceAsyncModel;
QList<WatchData> m_completed;
QSet<QByteArray> m_uncompleted;
static QString msgGdbStopFailed(const QString &why);
static QString msgInferiorStopFailed(const QString &why);
static QString msgAttachedToStoppedInferior();
static QString msgInferiorSetupOk();
static QString msgInferiorRunOk();
static QString msgConnectRemoteServerFailed(const QString &why);
protected:
enum DumperHandling
{
DumperNotAvailable,
DumperLoadedByAdapter,
DumperLoadedByGdbPreload,
DumperLoadedByGdb
};
virtual void write(const QByteArray &data);
virtual AbstractGdbProcess *gdbProc() = 0;
virtual DumperHandling dumperHandling() const = 0;
// CODA specific stuff
virtual bool isCodaAdapter() const;
virtual void codaReloadRegisters() {}
virtual void codaReloadThreads() {}
protected:
bool prepareCommand();
void interruptLocalInferior(qint64 pid);
};
} // namespace Internal
} // namespace Debugger
@@ -53,15 +53,16 @@ namespace Internal {
//
///////////////////////////////////////////////////////////////////////
LocalPlainGdbAdapter::LocalPlainGdbAdapter(GdbEngine *engine)
: AbstractPlainGdbAdapter(engine)
GdbLocalPlainEngine::GdbLocalPlainEngine(const DebuggerStartParameters &startParameters,
DebuggerEngine *masterEngine)
: GdbAbstractPlainEngine(startParameters, masterEngine)
{
// Output
connect(&m_outputCollector, SIGNAL(byteDelivery(QByteArray)),
engine, SLOT(readDebugeeOutput(QByteArray)));
this, SLOT(readDebugeeOutput(QByteArray)));
}
AbstractGdbAdapter::DumperHandling LocalPlainGdbAdapter::dumperHandling() const
GdbEngine::DumperHandling GdbLocalPlainEngine::dumperHandling() const
{
// LD_PRELOAD fails for System-Qt on Mac.
#if defined(Q_OS_WIN) || defined(Q_OS_MAC)
@@ -71,7 +72,7 @@ AbstractGdbAdapter::DumperHandling LocalPlainGdbAdapter::dumperHandling() const
#endif
}
void LocalPlainGdbAdapter::startAdapter()
void GdbLocalPlainEngine::setupEngine()
{
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
showMessage(_("TRYING TO START ADAPTER"));
@@ -82,7 +83,7 @@ void LocalPlainGdbAdapter::startAdapter()
QStringList gdbArgs;
if (!m_outputCollector.listen()) {
m_engine->handleAdapterStartFailed(tr("Cannot set up communication with child process: %1")
handleAdapterStartFailed(tr("Cannot set up communication with child process: %1")
.arg(m_outputCollector.errorString()));
return;
}
@@ -93,53 +94,38 @@ void LocalPlainGdbAdapter::startAdapter()
if (startParameters().environment.size())
m_gdbProc.setEnvironment(startParameters().environment.toStringList());
m_engine->startGdb(gdbArgs);
startGdb(gdbArgs);
}
void LocalPlainGdbAdapter::handleGdbStartDone()
{
m_engine->handleAdapterStarted();
}
void LocalPlainGdbAdapter::handleGdbStartFailed()
void GdbLocalPlainEngine::handleGdbStartFailed()
{
m_outputCollector.shutdown();
}
void LocalPlainGdbAdapter::setupInferior()
{
AbstractPlainGdbAdapter::setupInferior();
}
void LocalPlainGdbAdapter::runEngine()
{
AbstractPlainGdbAdapter::runEngine();
}
void LocalPlainGdbAdapter::shutdownAdapter()
void GdbLocalPlainEngine::shutdownEngine()
{
showMessage(_("PLAIN ADAPTER SHUTDOWN %1").arg(state()));
m_outputCollector.shutdown();
m_engine->notifyAdapterShutdownOk();
notifyAdapterShutdownOk();
}
void LocalPlainGdbAdapter::interruptInferior()
void GdbLocalPlainEngine::interruptInferior2()
{
interruptLocalInferior(m_engine->inferiorPid());
interruptLocalInferior(inferiorPid());
}
QByteArray LocalPlainGdbAdapter::execFilePath() const
QByteArray GdbLocalPlainEngine::execFilePath() const
{
return QFileInfo(startParameters().executable)
.absoluteFilePath().toLocal8Bit();
}
QByteArray LocalPlainGdbAdapter::toLocalEncoding(const QString &s) const
QByteArray GdbLocalPlainEngine::toLocalEncoding(const QString &s) const
{
return s.toLocal8Bit();
}
QString LocalPlainGdbAdapter::fromLocalEncoding(const QByteArray &b) const
QString GdbLocalPlainEngine::fromLocalEncoding(const QByteArray &b) const
{
return QString::fromLocal8Bit(b);
}
@@ -46,21 +46,19 @@ namespace Internal {
//
///////////////////////////////////////////////////////////////////////
class LocalPlainGdbAdapter : public AbstractPlainGdbAdapter
class GdbLocalPlainEngine : public GdbAbstractPlainEngine
{
Q_OBJECT
public:
explicit LocalPlainGdbAdapter(GdbEngine *engine);
GdbLocalPlainEngine(const DebuggerStartParameters &startParameters,
DebuggerEngine *masterEngine);
private:
void startAdapter();
void handleGdbStartDone();
void setupEngine();
void handleGdbStartFailed();
void setupInferior();
void runEngine();
void interruptInferior();
void shutdownAdapter();
void interruptInferior2();
void shutdownEngine();
DumperHandling dumperHandling() const;
AbstractGdbProcess *gdbProc() { return &m_gdbProc; }
+2 -3
View File
@@ -32,7 +32,6 @@
#include "gdbengine.h"
#include "gdbmi.h"
#include "abstractgdbadapter.h"
#include "debuggeractions.h"
#include "debuggercore.h"
#include "debuggerstringutils.h"
@@ -202,8 +201,8 @@ void GdbEngine::updateAllPython()
postCommand("-stack-list-frames", CB(handleStackListFrames),
QVariant::fromValue<StackCookie>(StackCookie(false, true)));
stackHandler()->setCurrentIndex(0);
if (m_gdbAdapter->isCodaAdapter())
m_gdbAdapter->codaReloadThreads();
if (isCodaAdapter())
codaReloadThreads();
else
postCommand("-thread-info", CB(handleThreadInfo), 0);
reloadRegisters();
@@ -49,7 +49,7 @@ namespace Debugger {
namespace Internal {
RemoteGdbProcess::RemoteGdbProcess(const QSsh::SshConnectionParameters &connParams,
RemotePlainGdbAdapter *adapter, QObject *parent)
GdbRemotePlainEngine *adapter, QObject *parent)
: AbstractGdbProcess(parent), m_connParams(connParams), m_conn(0),
m_state(Inactive), m_adapter(adapter)
{
+3 -3
View File
@@ -44,14 +44,14 @@
namespace Debugger {
namespace Internal {
class RemotePlainGdbAdapter;
class GdbRemotePlainEngine;
class RemoteGdbProcess : public AbstractGdbProcess
{
Q_OBJECT
public:
RemoteGdbProcess(const QSsh::SshConnectionParameters &server,
RemotePlainGdbAdapter *adapter, QObject *parent = 0);
GdbRemotePlainEngine *adapter, QObject *parent = 0);
virtual QByteArray readAllStandardOutput();
virtual QByteArray readAllStandardError();
@@ -123,7 +123,7 @@ private:
QByteArray m_appOutputFileName;
State m_state;
RemotePlainGdbAdapter *m_adapter;
GdbRemotePlainEngine *m_adapter;
};
} // namespace Internal
@@ -50,7 +50,7 @@ namespace Debugger {
namespace Internal {
#define CB(callback) \
static_cast<GdbEngine::AdapterCallback>(&RemoteGdbServerAdapter::callback), \
static_cast<GdbEngine::GdbCommandCallback>(&GdbRemoteServerEngine::callback), \
STRINGIFY(callback)
///////////////////////////////////////////////////////////////////////
@@ -59,8 +59,9 @@ namespace Internal {
//
///////////////////////////////////////////////////////////////////////
RemoteGdbServerAdapter::RemoteGdbServerAdapter(GdbEngine *engine)
: AbstractGdbAdapter(engine)
GdbRemoteServerEngine::GdbRemoteServerEngine(const DebuggerStartParameters &startParameters,
DebuggerEngine *masterEngine)
: GdbEngine(startParameters, masterEngine)
{
connect(&m_uploadProc, SIGNAL(error(QProcess::ProcessError)),
SLOT(uploadProcError(QProcess::ProcessError)));
@@ -72,7 +73,7 @@ RemoteGdbServerAdapter::RemoteGdbServerAdapter(GdbEngine *engine)
SLOT(uploadProcFinished()));
}
AbstractGdbAdapter::DumperHandling RemoteGdbServerAdapter::dumperHandling() const
GdbEngine::DumperHandling GdbRemoteServerEngine::dumperHandling() const
{
using namespace ProjectExplorer;
const Abi abi = startParameters().toolChainAbi;
@@ -83,7 +84,7 @@ AbstractGdbAdapter::DumperHandling RemoteGdbServerAdapter::dumperHandling() cons
return DumperLoadedByGdbPreload;
}
void RemoteGdbServerAdapter::startAdapter()
void GdbRemoteServerEngine::setupEngine()
{
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
showMessage(_("TRYING TO START ADAPTER"));
@@ -96,12 +97,12 @@ void RemoteGdbServerAdapter::startAdapter()
}
}
if (startParameters().requestRemoteSetup)
m_engine->notifyEngineRequestRemoteSetup();
notifyEngineRequestRemoteSetup();
else
m_engine->startGdb();
startGdb();
}
void RemoteGdbServerAdapter::uploadProcError(QProcess::ProcessError error)
void GdbRemoteServerEngine::uploadProcError(QProcess::ProcessError error)
{
QString msg;
switch (error) {
@@ -135,7 +136,7 @@ void RemoteGdbServerAdapter::uploadProcError(QProcess::ProcessError error)
showMessageBox(QMessageBox::Critical, tr("Error"), msg);
}
void RemoteGdbServerAdapter::readUploadStandardOutput()
void GdbRemoteServerEngine::readUploadStandardOutput()
{
const QByteArray ba = m_uploadProc.readAllStandardOutput();
const QString msg = QString::fromLocal8Bit(ba, ba.length());
@@ -143,7 +144,7 @@ void RemoteGdbServerAdapter::readUploadStandardOutput()
showMessage(msg, AppOutput);
}
void RemoteGdbServerAdapter::readUploadStandardError()
void GdbRemoteServerEngine::readUploadStandardError()
{
const QByteArray ba = m_uploadProc.readAllStandardError();
const QString msg = QString::fromLocal8Bit(ba, ba.length());
@@ -151,16 +152,16 @@ void RemoteGdbServerAdapter::readUploadStandardError()
showMessage(msg, AppError);
}
void RemoteGdbServerAdapter::uploadProcFinished()
void GdbRemoteServerEngine::uploadProcFinished()
{
if (m_uploadProc.exitStatus() == QProcess::NormalExit
&& m_uploadProc.exitCode() == 0)
m_engine->startGdb();
startGdb();
else
handleRemoteSetupFailed(m_uploadProc.errorString());
}
void RemoteGdbServerAdapter::setupInferior()
void GdbRemoteServerEngine::setupInferior()
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
const DebuggerStartParameters &sp = startParameters();
@@ -174,28 +175,21 @@ void RemoteGdbServerAdapter::setupInferior()
QFileInfo fi(sp.executable);
fileName = fi.absoluteFilePath();
}
const QByteArray sysroot = sp.sysroot.toLocal8Bit();
const QByteArray remoteArch = sp.remoteArchitecture.toLatin1();
const QByteArray gnuTarget = sp.gnuTarget.toLatin1();
const QByteArray searchPath = startParameters().searchPath.toLocal8Bit();
//const QByteArray sysroot = sp.sysroot.toLocal8Bit();
//const QByteArray remoteArch = sp.remoteArchitecture.toLatin1();
//const QByteArray gnuTarget = sp.gnuTarget.toLatin1();
const QString args = sp.processArgs;
const QString solibSearchPath = startParameters().solibSearchPath.join(QLatin1String(PATHSEP));
if (!remoteArch.isEmpty())
m_engine->postCommand("set architecture " + remoteArch);
if (!gnuTarget.isEmpty())
m_engine->postCommand("set gnutarget " + gnuTarget);
if (!sysroot.isEmpty()) {
m_engine->postCommand("set sysroot " + sysroot);
// sysroot is not enough to correctly locate the sources, so explicitly
// relocate the most likely place for the debug source
m_engine->postCommand("set substitute-path /usr/src " + sysroot + "/usr/src");
}
// if (!remoteArch.isEmpty())
// postCommand("set architecture " + remoteArch);
// if (!gnuTarget.isEmpty())
// postCommand("set gnutarget " + gnuTarget);
const QString solibSearchPath = sp.solibSearchPath.join(QLatin1String(PATHSEP));
if (!solibSearchPath.isEmpty())
m_engine->postCommand("set solib-search-path " + solibSearchPath.toLocal8Bit());
postCommand("set solib-search-path " + solibSearchPath.toLocal8Bit());
if (!args.isEmpty())
m_engine->postCommand("-exec-arguments " + args.toLocal8Bit());
postCommand("-exec-arguments " + args.toLocal8Bit());
// This has to be issued before 'target remote'. On pre-7.0 the
// command is not present and will result in ' No symbol table is
@@ -217,7 +211,7 @@ void RemoteGdbServerAdapter::setupInferior()
// mi_execute_async_cli_command: Assertion `is_running (inferior_ptid)'
// failed.\nA problem internal to GDB has been detected,[...]
if (debuggerCore()->boolSetting(TargetAsync))
m_engine->postCommand("set target-async on", CB(handleSetTargetAsync));
postCommand("set target-async on", CB(handleSetTargetAsync));
if (fileName.isEmpty()) {
showMessage(tr("No symbol file given."), StatusBar);
@@ -225,19 +219,18 @@ void RemoteGdbServerAdapter::setupInferior()
return;
}
m_engine->postCommand("-file-exec-and-symbols \""
+ fileName.toLocal8Bit() + '"',
postCommand("-file-exec-and-symbols \"" + fileName.toLocal8Bit() + '"',
CB(handleFileExecAndSymbols));
}
void RemoteGdbServerAdapter::handleSetTargetAsync(const GdbResponse &response)
void GdbRemoteServerEngine::handleSetTargetAsync(const GdbResponse &response)
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
if (response.resultClass == GdbResultError)
qDebug() << "Adapter too old: does not support asynchronous mode.";
}
void RemoteGdbServerAdapter::handleFileExecAndSymbols(const GdbResponse &response)
void GdbRemoteServerEngine::handleFileExecAndSymbols(const GdbResponse &response)
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
if (response.resultClass == GdbResultDone) {
@@ -251,12 +244,12 @@ void RemoteGdbServerAdapter::handleFileExecAndSymbols(const GdbResponse &respons
showMessage(msg, StatusBar);
callTargetRemote(); // Proceed nevertheless.
} else {
m_engine->notifyInferiorSetupFailed(msg);
notifyInferiorSetupFailed(msg);
}
}
}
void RemoteGdbServerAdapter::callTargetRemote()
void GdbRemoteServerEngine::callTargetRemote()
{
//m_breakHandler->clearBreakMarkers();
@@ -278,31 +271,31 @@ void RemoteGdbServerAdapter::callTargetRemote()
channel = "tcp:" + channel;
}
if (m_engine->m_isQnxGdb)
m_engine->postCommand("target qnx " + channel, CB(handleTargetQnx));
if (m_isQnxGdb)
postCommand("target qnx " + channel, CB(handleTargetQnx));
else
m_engine->postCommand("target remote " + channel, CB(handleTargetRemote));
postCommand("target remote " + channel, CB(handleTargetRemote));
}
void RemoteGdbServerAdapter::handleTargetRemote(const GdbResponse &record)
void GdbRemoteServerEngine::handleTargetRemote(const GdbResponse &record)
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
if (record.resultClass == GdbResultDone) {
// gdb server will stop the remote application itself.
showMessage(_("INFERIOR STARTED"));
showMessage(msgAttachedToStoppedInferior(), StatusBar);
m_engine->handleInferiorPrepared();
handleInferiorPrepared();
} else {
// 16^error,msg="hd:5555: Connection timed out."
QString msg = msgConnectRemoteServerFailed(
QString::fromLocal8Bit(record.data.findChild("msg").data()));
m_engine->notifyInferiorSetupFailed(msg);
notifyInferiorSetupFailed(msg);
}
}
void RemoteGdbServerAdapter::handleTargetQnx(const GdbResponse &response)
void GdbRemoteServerEngine::handleTargetQnx(const GdbResponse &response)
{
QTC_ASSERT(m_engine->m_isQnxGdb, qDebug() << m_engine->m_isQnxGdb);
QTC_ASSERT(m_isQnxGdb, qDebug() << m_isQnxGdb);
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
if (response.resultClass == GdbResultDone) {
// gdb server will stop the remote application itself.
@@ -311,19 +304,19 @@ void RemoteGdbServerAdapter::handleTargetQnx(const GdbResponse &response)
const qint64 pid = startParameters().attachPID;
if (pid > -1) {
m_engine->postCommand("attach " + QByteArray::number(pid), CB(handleAttach));
postCommand("attach " + QByteArray::number(pid), CB(handleAttach));
} else {
m_engine->handleInferiorPrepared();
handleInferiorPrepared();
}
} else {
// 16^error,msg="hd:5555: Connection timed out."
QString msg = msgConnectRemoteServerFailed(
QString::fromLocal8Bit(response.data.findChild("msg").data()));
m_engine->notifyInferiorSetupFailed(msg);
notifyInferiorSetupFailed(msg);
}
}
void RemoteGdbServerAdapter::handleAttach(const GdbResponse &response)
void GdbRemoteServerEngine::handleAttach(const GdbResponse &response)
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
switch (response.resultClass) {
@@ -331,46 +324,46 @@ void RemoteGdbServerAdapter::handleAttach(const GdbResponse &response)
case GdbResultRunning: {
showMessage(_("INFERIOR ATTACHED"));
showMessage(msgAttachedToStoppedInferior(), StatusBar);
m_engine->handleInferiorPrepared();
handleInferiorPrepared();
break;
}
case GdbResultError:
if (response.data.findChild("msg").data() == "ptrace: Operation not permitted.") {
m_engine->notifyInferiorSetupFailed(DumperHelper::msgPtraceError(startParameters().startMode));
notifyInferiorSetupFailed(DumperHelper::msgPtraceError(startParameters().startMode));
break;
}
// if msg != "ptrace: ..." fall through
default:
QString msg = QString::fromLocal8Bit(response.data.findChild("msg").data());
m_engine->notifyInferiorSetupFailed(msg);
notifyInferiorSetupFailed(msg);
}
}
void RemoteGdbServerAdapter::runEngine()
void GdbRemoteServerEngine::runEngine()
{
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
m_engine->notifyEngineRunAndInferiorStopOk();
m_engine->continueInferiorInternal();
notifyEngineRunAndInferiorStopOk();
continueInferiorInternal();
}
void RemoteGdbServerAdapter::interruptInferior()
void GdbRemoteServerEngine::interruptInferior2()
{
QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state());
if (debuggerCore()->boolSetting(TargetAsync)) {
m_engine->postCommand("-exec-interrupt", GdbEngine::Immediate,
postCommand("-exec-interrupt", GdbEngine::Immediate,
CB(handleInterruptInferior));
} else {
bool ok = m_gdbProc.interrupt();
if (!ok) {
// FIXME: Extra state needed?
m_engine->showMessage(_("NOTE: INFERIOR STOP NOT POSSIBLE"));
m_engine->showStatusMessage(tr("Interrupting not possible"));
m_engine->notifyInferiorRunOk();
showMessage(_("NOTE: INFERIOR STOP NOT POSSIBLE"));
showStatusMessage(tr("Interrupting not possible"));
notifyInferiorRunOk();
}
}
}
void RemoteGdbServerAdapter::handleInterruptInferior(const GdbResponse &response)
void GdbRemoteServerEngine::handleInterruptInferior(const GdbResponse &response)
{
if (response.resultClass == GdbResultDone) {
// The gdb server will trigger extra output that we will pick up
@@ -378,17 +371,18 @@ void RemoteGdbServerAdapter::handleInterruptInferior(const GdbResponse &response
} else {
// FIXME: On some gdb versions like git 170ffa5d7dd this produces
// >810^error,msg="mi_cmd_exec_interrupt: Inferior not executing."
m_engine->notifyInferiorStopOk();
notifyInferiorStopOk();
}
}
void RemoteGdbServerAdapter::shutdownAdapter()
void GdbRemoteServerEngine::shutdownEngine()
{
m_engine->notifyAdapterShutdownOk();
notifyAdapterShutdownOk();
}
void RemoteGdbServerAdapter::handleRemoteSetupDone(int gdbServerPort, int qmlPort)
void GdbRemoteServerEngine::handleRemoteSetupDone(int gdbServerPort, int qmlPort)
{
notifyEngineRemoteSetupDone();
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
if (qmlPort != -1)
@@ -401,23 +395,13 @@ void RemoteGdbServerAdapter::handleRemoteSetupDone(int gdbServerPort, int qmlPor
QString::number(gdbServerPort));
}
}
m_engine->startGdb();
startGdb();
}
void RemoteGdbServerAdapter::handleGdbStartDone()
{
m_engine->handleAdapterStarted();
}
void RemoteGdbServerAdapter::handleGdbStartFailed()
{
}
void RemoteGdbServerAdapter::handleRemoteSetupFailed(const QString &reason)
void GdbRemoteServerEngine::handleRemoteSetupFailed(const QString &reason)
{
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
m_engine->handleAdapterStartFailed(reason);
handleAdapterStartFailed(reason);
}
} // namespace Internal
@@ -33,7 +33,7 @@
#ifndef DEBUGGER_REMOTEGDBADAPTER_H
#define DEBUGGER_REMOTEGDBADAPTER_H
#include "abstractgdbadapter.h"
#include "gdbengine.h"
#include "localgdbprocess.h"
namespace Debugger {
@@ -45,23 +45,22 @@ namespace Internal {
//
///////////////////////////////////////////////////////////////////////
class RemoteGdbServerAdapter : public AbstractGdbAdapter
class GdbRemoteServerEngine : public GdbEngine
{
Q_OBJECT
public:
RemoteGdbServerAdapter(GdbEngine *engine);
GdbRemoteServerEngine(const DebuggerStartParameters &startParameters,
DebuggerEngine *masterEngine);
private:
DumperHandling dumperHandling() const;
void startAdapter();
void handleGdbStartDone();
void handleGdbStartFailed();
void setupEngine();
void setupInferior();
void runEngine();
void interruptInferior();
void shutdownAdapter();
void interruptInferior2();
void shutdownEngine();
AbstractGdbProcess *gdbProc() { return &m_gdbProc; }
@@ -41,16 +41,17 @@
namespace Debugger {
namespace Internal {
RemotePlainGdbAdapter::RemotePlainGdbAdapter(GdbEngine *engine)
: AbstractPlainGdbAdapter(engine),
m_gdbProc(engine->startParameters().connParams, this)
GdbRemotePlainEngine::GdbRemotePlainEngine(const DebuggerStartParameters &startParameters,
DebuggerEngine *masterEngine)
: GdbAbstractPlainEngine(startParameters, masterEngine),
m_gdbProc(startParameters.connParams, this)
{
connect(&m_gdbProc, SIGNAL(started()), this, SLOT(handleGdbStarted()));
connect(&m_gdbProc, SIGNAL(startFailed()), this,
SLOT(handleGdbStartFailed1()));
}
void RemotePlainGdbAdapter::startAdapter()
void GdbRemotePlainEngine::setupEngine()
{
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
showMessage(QLatin1String("TRYING TO START ADAPTER"));
@@ -63,79 +64,68 @@ void RemotePlainGdbAdapter::startAdapter()
handleRemoteSetupDone(startParameters().connParams.port, startParameters().qmlServerPort);
}
void RemotePlainGdbAdapter::setupInferior()
void GdbRemotePlainEngine::setupInferior()
{
AbstractPlainGdbAdapter::setupInferior();
m_engine->postCommand("directory "
+ m_engine->startParameters().remoteSourcesDir);
GdbAbstractPlainEngine::setupInferior();
postCommand("directory " + startParameters().remoteSourcesDir);
}
void RemotePlainGdbAdapter::interruptInferior()
void GdbRemotePlainEngine::interruptInferior2()
{
m_gdbProc.interruptInferior();
}
QByteArray RemotePlainGdbAdapter::execFilePath() const
QByteArray GdbRemotePlainEngine::execFilePath() const
{
return startParameters().executable.toUtf8();
}
QByteArray RemotePlainGdbAdapter::toLocalEncoding(const QString &s) const
QByteArray GdbRemotePlainEngine::toLocalEncoding(const QString &s) const
{
return s.toUtf8();
}
QString RemotePlainGdbAdapter::fromLocalEncoding(const QByteArray &b) const
QString GdbRemotePlainEngine::fromLocalEncoding(const QByteArray &b) const
{
return QString::fromUtf8(b);
}
void RemotePlainGdbAdapter::handleApplicationOutput(const QByteArray &output)
void GdbRemotePlainEngine::handleApplicationOutput(const QByteArray &output)
{
showMessage(QString::fromUtf8(output), AppOutput);
}
void RemotePlainGdbAdapter::shutdownAdapter()
void GdbRemotePlainEngine::shutdownEngine()
{
m_engine->notifyAdapterShutdownOk();
notifyAdapterShutdownOk();
}
void RemotePlainGdbAdapter::handleRemoteSetupDone(int gdbServerPort, int qmlPort)
void GdbRemotePlainEngine::handleRemoteSetupDone(int gdbServerPort, int qmlPort)
{
Q_UNUSED(gdbServerPort);
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
if (qmlPort != -1)
startParameters().qmlServerPort = qmlPort;
m_gdbProc.realStart(m_engine->startParameters().debuggerCommand,
m_gdbProc.realStart(startParameters().debuggerCommand,
QStringList() << QLatin1String("-i") << QLatin1String("mi"),
m_engine->startParameters().executable);
startParameters().executable);
}
void RemotePlainGdbAdapter::handleGdbStarted()
void GdbRemotePlainEngine::handleGdbStarted()
{
m_engine->startGdb();
startGdb();
}
void RemotePlainGdbAdapter::handleGdbStartDone()
void GdbRemotePlainEngine::handleGdbStartFailed1()
{
m_engine->handleAdapterStarted();
handleAdapterStartFailed(m_gdbProc.errorString());
}
void RemotePlainGdbAdapter::handleGdbStartFailed()
{
}
void RemotePlainGdbAdapter::handleGdbStartFailed1()
{
m_engine->handleAdapterStartFailed(m_gdbProc.errorString());
}
void RemotePlainGdbAdapter::handleRemoteSetupFailed(const QString &reason)
void GdbRemotePlainEngine::handleRemoteSetupFailed(const QString &reason)
{
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
m_engine->handleAdapterStartFailed(reason);
handleAdapterStartFailed(reason);
}
} // namespace Internal
@@ -39,25 +39,24 @@
namespace Debugger {
namespace Internal {
class RemotePlainGdbAdapter : public AbstractPlainGdbAdapter
class GdbRemotePlainEngine : public GdbAbstractPlainEngine
{
Q_OBJECT
public:
friend class RemoteGdbProcess;
explicit RemotePlainGdbAdapter(GdbEngine *engine);
GdbRemotePlainEngine(const DebuggerStartParameters &startParameters,
DebuggerEngine *masterEngine);
private slots:
void handleGdbStarted();
void handleGdbStartFailed1();
private:
void startAdapter();
void handleGdbStartDone();
void handleGdbStartFailed();
void setupEngine();
void setupInferior();
void interruptInferior();
void shutdownAdapter();
void interruptInferior2();
void shutdownEngine();
void handleRemoteSetupDone(int gdbServerPort, int qmlPort);
void handleRemoteSetupFailed(const QString &reason);
AbstractGdbProcess *gdbProc() { return &m_gdbProc; }
+34 -39
View File
@@ -49,7 +49,7 @@ namespace Debugger {
namespace Internal {
#define CB(callback) \
static_cast<GdbEngine::AdapterCallback>(&TermGdbAdapter::callback), \
static_cast<GdbEngine::GdbCommandCallback>(&GdbTermEngine::callback), \
STRINGIFY(callback)
///////////////////////////////////////////////////////////////////////
@@ -58,8 +58,9 @@ namespace Internal {
//
///////////////////////////////////////////////////////////////////////
TermGdbAdapter::TermGdbAdapter(GdbEngine *engine)
: AbstractGdbAdapter(engine)
GdbTermEngine::GdbTermEngine(const DebuggerStartParameters &startParameters,
DebuggerEngine *masterEngine)
: GdbEngine(startParameters, masterEngine)
{
#ifdef Q_OS_WIN
// Windows up to xp needs a workaround for attaching to freshly started processes. see proc_stub_win
@@ -72,18 +73,14 @@ TermGdbAdapter::TermGdbAdapter(GdbEngine *engine)
m_stubProc.setMode(Utils::ConsoleProcess::Debug);
m_stubProc.setSettings(Core::ICore::settings());
#endif
connect(&m_stubProc, SIGNAL(processError(QString)), SLOT(stubError(QString)));
connect(&m_stubProc, SIGNAL(processStarted()), SLOT(handleInferiorSetupOk()));
connect(&m_stubProc, SIGNAL(wrapperStopped()), SLOT(stubExited()));
}
TermGdbAdapter::~TermGdbAdapter()
GdbTermEngine::~GdbTermEngine()
{
m_stubProc.disconnect(); // Avoid spurious state transitions from late exiting stub
}
AbstractGdbAdapter::DumperHandling TermGdbAdapter::dumperHandling() const
GdbEngine::DumperHandling GdbTermEngine::dumperHandling() const
{
// LD_PRELOAD fails for System-Qt on Mac.
#if defined(Q_OS_WIN) || defined(Q_OS_MAC)
@@ -93,7 +90,7 @@ AbstractGdbAdapter::DumperHandling TermGdbAdapter::dumperHandling() const
#endif
}
void TermGdbAdapter::startAdapter()
void GdbTermEngine::setupEngine()
{
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
showMessage(_("TRYING TO START ADAPTER"));
@@ -110,34 +107,32 @@ void TermGdbAdapter::startAdapter()
m_stubProc.setWorkingDirectory(startParameters().workingDirectory);
// Set environment + dumper preload.
m_stubProc.setEnvironment(startParameters().environment);
connect(&m_stubProc, SIGNAL(processError(QString)), SLOT(stubError(QString)));
connect(&m_stubProc, SIGNAL(processStarted()), SLOT(stubStarted()));
connect(&m_stubProc, SIGNAL(wrapperStopped()), SLOT(stubExited()));
// FIXME: Starting the stub implies starting the inferior. This is
// fairly unclean as far as the state machine and error reporting go.
if (!m_stubProc.start(startParameters().executable,
startParameters().processArgs)) {
// Error message for user is delivered via a signal.
m_engine->handleAdapterStartFailed(QString());
handleAdapterStartFailed(QString());
return;
}
m_engine->startGdb();
}
void TermGdbAdapter::handleGdbStartDone()
void GdbTermEngine::stubStarted()
{
startGdb();
}
void TermGdbAdapter::handleGdbStartFailed()
void GdbTermEngine::handleGdbStartFailed()
{
m_stubProc.stop();
}
void TermGdbAdapter::handleInferiorSetupOk()
{
QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
m_engine->handleAdapterStarted();
}
void TermGdbAdapter::setupInferior()
void GdbTermEngine::setupInferior()
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
const qint64 attachedPID = m_stubProc.applicationPID();
@@ -147,12 +142,12 @@ void TermGdbAdapter::setupInferior()
#else
showMessage(QString::fromLatin1("Attaching to %1").arg(attachedPID), LogMisc);
#endif
m_engine->notifyInferiorPid(attachedPID);
m_engine->postCommand("attach " + QByteArray::number(attachedPID),
notifyInferiorPid(attachedPID);
postCommand("attach " + QByteArray::number(attachedPID),
CB(handleStubAttached));
}
void TermGdbAdapter::handleStubAttached(const GdbResponse &response)
void GdbTermEngine::handleStubAttached(const GdbResponse &response)
{
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
#ifdef Q_OS_WIN
@@ -174,51 +169,51 @@ void TermGdbAdapter::handleStubAttached(const GdbResponse &response)
#else
showMessage(_("INFERIOR ATTACHED"));
#endif // Q_OS_WIN
m_engine->handleInferiorPrepared();
handleInferiorPrepared();
break;
case GdbResultError:
if (response.data.findChild("msg").data() == "ptrace: Operation not permitted.") {
m_engine->notifyInferiorSetupFailed(DumperHelper::msgPtraceError(startParameters().startMode));
notifyInferiorSetupFailed(DumperHelper::msgPtraceError(startParameters().startMode));
break;
}
m_engine->notifyInferiorSetupFailed(QString::fromLocal8Bit(response.data.findChild("msg").data()));
notifyInferiorSetupFailed(QString::fromLocal8Bit(response.data.findChild("msg").data()));
break;
default:
m_engine->notifyInferiorSetupFailed(QString::fromLatin1("Invalid response %1").arg(response.resultClass));
notifyInferiorSetupFailed(QString::fromLatin1("Invalid response %1").arg(response.resultClass));
break;
}
}
void TermGdbAdapter::runEngine()
void GdbTermEngine::runEngine()
{
QTC_ASSERT(state() == EngineRunRequested, qDebug() << state());
m_engine->notifyEngineRunAndInferiorStopOk();
m_engine->continueInferiorInternal();
notifyEngineRunAndInferiorStopOk();
continueInferiorInternal();
}
void TermGdbAdapter::interruptInferior()
void GdbTermEngine::interruptInferior2()
{
interruptLocalInferior(m_engine->inferiorPid());
interruptLocalInferior(inferiorPid());
}
void TermGdbAdapter::stubError(const QString &msg)
void GdbTermEngine::stubError(const QString &msg)
{
showMessageBox(QMessageBox::Critical, tr("Debugger Error"), msg);
}
void TermGdbAdapter::stubExited()
void GdbTermEngine::stubExited()
{
if (state() == EngineShutdownRequested || state() == DebuggerFinished) {
showMessage(_("STUB EXITED EXPECTEDLY"));
return;
}
showMessage(_("STUB EXITED"));
m_engine->notifyEngineIll();
notifyEngineIll();
}
void TermGdbAdapter::shutdownAdapter()
void GdbTermEngine::shutdownEngine()
{
m_engine->notifyAdapterShutdownOk();
notifyAdapterShutdownOk();
}
} // namespace Internal
+10 -9
View File
@@ -33,7 +33,7 @@
#ifndef DEBUGGER_TERMGDBADAPTER_H
#define DEBUGGER_TERMGDBADAPTER_H
#include "abstractgdbadapter.h"
#include "gdbengine.h"
#include "localgdbprocess.h"
#include <utils/consoleprocess.h>
@@ -47,30 +47,31 @@ namespace Internal {
//
///////////////////////////////////////////////////////////////////////
class TermGdbAdapter : public AbstractGdbAdapter
class GdbTermEngine : public GdbEngine
{
Q_OBJECT
public:
explicit TermGdbAdapter(GdbEngine *engine);
~TermGdbAdapter();
GdbTermEngine(const DebuggerStartParameters &startParameters,
DebuggerEngine *masterEngine);
~GdbTermEngine();
private:
DumperHandling dumperHandling() const;
void startAdapter();
void handleGdbStartDone();
void setupEngine();
void handleGdbStartFailed();
void setupInferior();
void runEngine();
void interruptInferior();
void shutdownAdapter();
void interruptInferior2();
void shutdownEngine();
AbstractGdbProcess *gdbProc() { return &m_gdbProc; }
void handleStubAttached(const GdbResponse &response);
Q_SLOT void handleInferiorSetupOk();
Q_SLOT void stubStarted();
Q_SLOT void stubExited();
Q_SLOT void stubError(const QString &msg);