From 17c18623ef419ee46bb52553324974530e03b1df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20N=C3=A4tterlund?= Date: Fri, 10 Feb 2012 07:42:44 +0100 Subject: [PATCH] Add support for the remote QNX debugging protocol Change-Id: Ifb2a378cdc000eb84b65f25c2132783d3a3f53c4 Reviewed-by: hjk --- .../debugger/debuggerstartparameters.h | 1 + src/plugins/debugger/gdb/gdbengine.cpp | 4 +- src/plugins/debugger/gdb/gdbengine.h | 1 + src/plugins/debugger/gdb/gdbmi.cpp | 3 +- src/plugins/debugger/gdb/gdbmi.h | 2 +- .../debugger/gdb/remotegdbserveradapter.cpp | 58 ++++++++++++++++++- .../debugger/gdb/remotegdbserveradapter.h | 2 + 7 files changed, 66 insertions(+), 5 deletions(-) diff --git a/src/plugins/debugger/debuggerstartparameters.h b/src/plugins/debugger/debuggerstartparameters.h index 2b5b25332a..859f24db86 100644 --- a/src/plugins/debugger/debuggerstartparameters.h +++ b/src/plugins/debugger/debuggerstartparameters.h @@ -110,6 +110,7 @@ public: bool useServerStartScript; QString serverStartScript; QString sysroot; + QString searchPath; // Gdb "set solib-search-path" QString debugInfoLocation; // Gdb "set-debug-file-directory". QStringList debugSourceLocation; // Gdb "directory" QByteArray remoteDumperLib; diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 2d8321c37c..92ba0f5795 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -196,6 +196,7 @@ GdbEngine::GdbEngine(const DebuggerStartParameters &startParameters, m_gdbVersion = 100; m_gdbBuildVersion = -1; m_isMacGdb = false; + m_isQnxGdb = false; m_hasBreakpointNotifications = false; m_hasPython = false; m_registerNamesListed = false; @@ -1689,9 +1690,10 @@ void GdbEngine::handleShowVersion(const GdbResponse &response) m_gdbVersion = 100; m_gdbBuildVersion = -1; m_isMacGdb = false; + m_isQnxGdb = false; QString msg = QString::fromLocal8Bit(response.consoleStreamOutput); extractGdbVersion(msg, - &m_gdbVersion, &m_gdbBuildVersion, &m_isMacGdb); + &m_gdbVersion, &m_gdbBuildVersion, &m_isMacGdb, &m_isQnxGdb); // On Mac, fsf gdb does not work sufficiently well, // and on Linux and Windows we require at least 7.2. diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index e42f12dc83..f4de4e1f70 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -438,6 +438,7 @@ private: ////////// Gdb Output, State & Capability Handling ////////// int m_gdbVersion; // 6.8.0 is 60800 int m_gdbBuildVersion; // MAC only? bool m_isMacGdb; + bool m_isQnxGdb; bool m_hasBreakpointNotifications; bool m_hasPython; bool m_hasInferiorThreadList; diff --git a/src/plugins/debugger/gdb/gdbmi.cpp b/src/plugins/debugger/gdb/gdbmi.cpp index 5946b57102..9d3437a84e 100644 --- a/src/plugins/debugger/gdb/gdbmi.cpp +++ b/src/plugins/debugger/gdb/gdbmi.cpp @@ -409,7 +409,7 @@ QByteArray GdbResponse::toString() const ////////////////////////////////////////////////////////////////////////////////// void extractGdbVersion(const QString &msg, - int *gdbVersion, int *gdbBuildVersion, bool *isMacGdb) + int *gdbVersion, int *gdbBuildVersion, bool *isMacGdb, bool *isQnxGdb) { const QChar dot(QLatin1Char('.')); @@ -433,6 +433,7 @@ void extractGdbVersion(const QString &msg, } *isMacGdb = msg.contains(QLatin1String("Apple version")); + *isQnxGdb = msg.contains(QLatin1String("qnx-nto")); *gdbVersion = 10000 * cleaned.section(dot, 0, 0).toInt() + 100 * cleaned.section(dot, 1, 1).toInt() diff --git a/src/plugins/debugger/gdb/gdbmi.h b/src/plugins/debugger/gdb/gdbmi.h index 1e1036cca3..9727f42764 100644 --- a/src/plugins/debugger/gdb/gdbmi.h +++ b/src/plugins/debugger/gdb/gdbmi.h @@ -174,7 +174,7 @@ public: }; void extractGdbVersion(const QString &msg, - int *gdbVersion, int *gdbBuildVersion, bool *isMacGdb); + int *gdbVersion, int *gdbBuildVersion, bool *isMacGdb, bool *isQnxGdb); } // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/gdb/remotegdbserveradapter.cpp b/src/plugins/debugger/gdb/remotegdbserveradapter.cpp index 6e4b566291..26ee53b9a2 100644 --- a/src/plugins/debugger/gdb/remotegdbserveradapter.cpp +++ b/src/plugins/debugger/gdb/remotegdbserveradapter.cpp @@ -173,6 +173,7 @@ void RemoteGdbServerAdapter::setupInferior() 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 QString args = sp.processArgs; if (!remoteArch.isEmpty()) @@ -181,6 +182,8 @@ void RemoteGdbServerAdapter::setupInferior() m_engine->postCommand("set gnutarget " + gnuTarget); if (!sysroot.isEmpty()) m_engine->postCommand("set sysroot " + sysroot); + if (!searchPath.isEmpty()) + m_engine->postCommand("set solib-search-path " + searchPath); if (!args.isEmpty()) m_engine->postCommand("-exec-arguments " + args.toLocal8Bit()); @@ -245,8 +248,13 @@ void RemoteGdbServerAdapter::callTargetRemote() // (2) starts the remote application // (3) stops the remote application (early, e.g. in the dynamic linker) QString channel = startParameters().remoteChannel; - m_engine->postCommand("target remote " + channel.toLatin1(), - CB(handleTargetRemote)); + if (m_engine->m_isQnxGdb) { + m_engine->postCommand("target qnx " + channel.toLatin1(), + CB(handleTargetQnx)); + } else { + m_engine->postCommand("target remote " + channel.toLatin1(), + CB(handleTargetRemote)); + } } void RemoteGdbServerAdapter::handleTargetRemote(const GdbResponse &record) @@ -265,6 +273,52 @@ void RemoteGdbServerAdapter::handleTargetRemote(const GdbResponse &record) } } +void RemoteGdbServerAdapter::handleTargetQnx(const GdbResponse &response) +{ + QTC_ASSERT(m_engine->m_isQnxGdb, qDebug() << m_engine->m_isQnxGdb); + QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); + if (response.resultClass == GdbResultDone) { + // gdb server will stop the remote application itself. + showMessage(_("INFERIOR STARTED")); + showMessage(msgAttachedToStoppedInferior(), StatusBar); + + const qint64 pid = startParameters().attachPID; + if (pid > -1) { + m_engine->postCommand("attach " + QByteArray::number(pid), CB(handleAttach)); + } else { + m_engine->handleInferiorPrepared(); + } + } else { + // 16^error,msg="hd:5555: Connection timed out." + QString msg = msgConnectRemoteServerFailed( + QString::fromLocal8Bit(response.data.findChild("msg").data())); + m_engine->notifyInferiorSetupFailed(msg); + } +} + +void RemoteGdbServerAdapter::handleAttach(const GdbResponse &response) +{ + QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state()); + switch (response.resultClass) { + case GdbResultDone: + case GdbResultRunning: { + showMessage(_("INFERIOR ATTACHED")); + showMessage(msgAttachedToStoppedInferior(), StatusBar); + m_engine->handleInferiorPrepared(); + break; + } + case GdbResultError: + if (response.data.findChild("msg").data() == "ptrace: Operation not permitted.") { + m_engine->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); + } +} + void RemoteGdbServerAdapter::runEngine() { QTC_ASSERT(state() == EngineRunRequested, qDebug() << state()); diff --git a/src/plugins/debugger/gdb/remotegdbserveradapter.h b/src/plugins/debugger/gdb/remotegdbserveradapter.h index 50cf81e32e..9261797d6d 100644 --- a/src/plugins/debugger/gdb/remotegdbserveradapter.h +++ b/src/plugins/debugger/gdb/remotegdbserveradapter.h @@ -90,6 +90,8 @@ private: void handleFileExecAndSymbols(const GdbResponse &response); void callTargetRemote(); void handleTargetRemote(const GdbResponse &response); + void handleTargetQnx(const GdbResponse &response); + void handleAttach(const GdbResponse &response); void handleInterruptInferior(const GdbResponse &response); QProcess m_uploadProc; -- GitLab