diff options
author | hjk <qtc-committer@nokia.com> | 2012-06-13 10:15:56 +0200 |
---|---|---|
committer | hjk <qthjk@ovi.com> | 2012-06-13 10:55:59 +0200 |
commit | 5d782df33f2ad68421df803ba23b2422691110c7 (patch) | |
tree | 0e0480a68cf4c09193aa4e50b70f0e862a4a1b63 | |
parent | c68cf6dcd9c60bd7db7f7fb621efba76377541bd (diff) | |
download | qt-creator-5d782df33f2ad68421df803ba23b2422691110c7.tar.gz |
debugger: Replace adapter classes by GdbEngine subclasses
Change-Id: Iee6195b1eed5251545b9d688221ac2edf19325c1
Reviewed-by: Christian Kandeler <christian.kandeler@nokia.com>
27 files changed, 606 insertions, 987 deletions
diff --git a/src/plugins/debugger/debugger.qbs b/src/plugins/debugger/debugger.qbs index 55c7b7a6e1..dc7b9ce43c 100644 --- a/src/plugins/debugger/debugger.qbs +++ b/src/plugins/debugger/debugger.qbs @@ -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", diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index f17c720bbd..d17b90f45f 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -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(); diff --git a/src/plugins/debugger/gdb/abstractgdbadapter.cpp b/src/plugins/debugger/gdb/abstractgdbadapter.cpp deleted file mode 100644 index c258ac7936..0000000000 --- a/src/plugins/debugger/gdb/abstractgdbadapter.cpp +++ /dev/null @@ -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 diff --git a/src/plugins/debugger/gdb/abstractgdbadapter.h b/src/plugins/debugger/gdb/abstractgdbadapter.h deleted file mode 100644 index 981c1c5e7b..0000000000 --- a/src/plugins/debugger/gdb/abstractgdbadapter.h +++ /dev/null @@ -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 diff --git a/src/plugins/debugger/gdb/abstractplaingdbadapter.cpp b/src/plugins/debugger/gdb/abstractplaingdbadapter.cpp index a9dd32c0a4..159689e1ef 100644 --- a/src/plugins/debugger/gdb/abstractplaingdbadapter.cpp +++ b/src/plugins/debugger/gdb/abstractplaingdbadapter.cpp @@ -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(); } } diff --git a/src/plugins/debugger/gdb/abstractplaingdbadapter.h b/src/plugins/debugger/gdb/abstractplaingdbadapter.h index 7b13ef5e4f..2e10ce4c01 100644 --- a/src/plugins/debugger/gdb/abstractplaingdbadapter.h +++ b/src/plugins/debugger/gdb/abstractplaingdbadapter.h @@ -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: diff --git a/src/plugins/debugger/gdb/attachgdbadapter.cpp b/src/plugins/debugger/gdb/attachgdbadapter.cpp index 8428169dd6..ccad37a36c 100644 --- a/src/plugins/debugger/gdb/attachgdbadapter.cpp +++ b/src/plugins/debugger/gdb/attachgdbadapter.cpp @@ -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 diff --git a/src/plugins/debugger/gdb/attachgdbadapter.h b/src/plugins/debugger/gdb/attachgdbadapter.h index 586105b7a7..e8b31e3068 100644 --- a/src/plugins/debugger/gdb/attachgdbadapter.h +++ b/src/plugins/debugger/gdb/attachgdbadapter.h @@ -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); diff --git a/src/plugins/debugger/gdb/classicgdbengine.cpp b/src/plugins/debugger/gdb/classicgdbengine.cpp index 938a4f32b7..589c36f53f 100644 --- a/src/plugins/debugger/gdb/classicgdbengine.cpp +++ b/src/plugins/debugger/gdb/classicgdbengine.cpp @@ -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"))); diff --git a/src/plugins/debugger/gdb/codagdbadapter.cpp b/src/plugins/debugger/gdb/codagdbadapter.cpp index 5c2e5674d2..ff53ad04ec 100644 --- a/src/plugins/debugger/gdb/codagdbadapter.cpp +++ b/src/plugins/debugger/gdb/codagdbadapter.cpp @@ -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 ¶meters = 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(®isterValue, 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')"). diff --git a/src/plugins/debugger/gdb/codagdbadapter.h b/src/plugins/debugger/gdb/codagdbadapter.h index a536d7109a..3c1875946a 100644 --- a/src/plugins/debugger/gdb/codagdbadapter.h +++ b/src/plugins/debugger/gdb/codagdbadapter.h @@ -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(); diff --git a/src/plugins/debugger/gdb/coregdbadapter.cpp b/src/plugins/debugger/gdb/coregdbadapter.cpp index 9784de688e..15ac074d71 100644 --- a/src/plugins/debugger/gdb/coregdbadapter.cpp +++ b/src/plugins/debugger/gdb/coregdbadapter.cpp @@ -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; } diff --git a/src/plugins/debugger/gdb/coregdbadapter.h b/src/plugins/debugger/gdb/coregdbadapter.h index 039c3881a2..686d456b34 100644 --- a/src/plugins/debugger/gdb/coregdbadapter.h +++ b/src/plugins/debugger/gdb/coregdbadapter.h @@ -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; diff --git a/src/plugins/debugger/gdb/gdb.pri b/src/plugins/debugger/gdb/gdb.pri index 04d3b4074d..003ba65bd6 100644 --- a/src/plugins/debugger/gdb/gdb.pri +++ b/src/plugins/debugger/gdb/gdb.pri @@ -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 \ diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 8900381349..f0a9d6f68c 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -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) diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index 038734f8ed..beaa4833d3 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -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 diff --git a/src/plugins/debugger/gdb/localplaingdbadapter.cpp b/src/plugins/debugger/gdb/localplaingdbadapter.cpp index 04dcf3df76..476a13903f 100644 --- a/src/plugins/debugger/gdb/localplaingdbadapter.cpp +++ b/src/plugins/debugger/gdb/localplaingdbadapter.cpp @@ -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); } diff --git a/src/plugins/debugger/gdb/localplaingdbadapter.h b/src/plugins/debugger/gdb/localplaingdbadapter.h index 3e9289bd30..1fabadd0a6 100644 --- a/src/plugins/debugger/gdb/localplaingdbadapter.h +++ b/src/plugins/debugger/gdb/localplaingdbadapter.h @@ -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; } diff --git a/src/plugins/debugger/gdb/pythongdbengine.cpp b/src/plugins/debugger/gdb/pythongdbengine.cpp index 5c9f942c8f..8ce00afcc4 100644 --- a/src/plugins/debugger/gdb/pythongdbengine.cpp +++ b/src/plugins/debugger/gdb/pythongdbengine.cpp @@ -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(); diff --git a/src/plugins/debugger/gdb/remotegdbprocess.cpp b/src/plugins/debugger/gdb/remotegdbprocess.cpp index 7ce4ebbe50..cb926e7a48 100644 --- a/src/plugins/debugger/gdb/remotegdbprocess.cpp +++ b/src/plugins/debugger/gdb/remotegdbprocess.cpp @@ -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) { diff --git a/src/plugins/debugger/gdb/remotegdbprocess.h b/src/plugins/debugger/gdb/remotegdbprocess.h index 8425a02f76..2546247cb9 100644 --- a/src/plugins/debugger/gdb/remotegdbprocess.h +++ b/src/plugins/debugger/gdb/remotegdbprocess.h @@ -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 diff --git a/src/plugins/debugger/gdb/remotegdbserveradapter.cpp b/src/plugins/debugger/gdb/remotegdbserveradapter.cpp index 38575baefa..c19525badc 100644 --- a/src/plugins/debugger/gdb/remotegdbserveradapter.cpp +++ b/src/plugins/debugger/gdb/remotegdbserveradapter.cpp @@ -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(); -} - -void RemoteGdbServerAdapter::handleGdbStartDone() -{ - m_engine->handleAdapterStarted(); + startGdb(); } -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 diff --git a/src/plugins/debugger/gdb/remotegdbserveradapter.h b/src/plugins/debugger/gdb/remotegdbserveradapter.h index 0799ee48c1..c047e7c77c 100644 --- a/src/plugins/debugger/gdb/remotegdbserveradapter.h +++ b/src/plugins/debugger/gdb/remotegdbserveradapter.h @@ -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; } diff --git a/src/plugins/debugger/gdb/remoteplaingdbadapter.cpp b/src/plugins/debugger/gdb/remoteplaingdbadapter.cpp index ea1dfefb3b..429257ab96 100644 --- a/src/plugins/debugger/gdb/remoteplaingdbadapter.cpp +++ b/src/plugins/debugger/gdb/remoteplaingdbadapter.cpp @@ -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 diff --git a/src/plugins/debugger/gdb/remoteplaingdbadapter.h b/src/plugins/debugger/gdb/remoteplaingdbadapter.h index 91c5825a50..f69a22ac67 100644 --- a/src/plugins/debugger/gdb/remoteplaingdbadapter.h +++ b/src/plugins/debugger/gdb/remoteplaingdbadapter.h @@ -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; } diff --git a/src/plugins/debugger/gdb/termgdbadapter.cpp b/src/plugins/debugger/gdb/termgdbadapter.cpp index dd5a570ecb..ded54d089b 100644 --- a/src/plugins/debugger/gdb/termgdbadapter.cpp +++ b/src/plugins/debugger/gdb/termgdbadapter.cpp @@ -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 diff --git a/src/plugins/debugger/gdb/termgdbadapter.h b/src/plugins/debugger/gdb/termgdbadapter.h index 69f613f143..561d617213 100644 --- a/src/plugins/debugger/gdb/termgdbadapter.h +++ b/src/plugins/debugger/gdb/termgdbadapter.h @@ -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); |