From 3b12f5f1d684786e0ff4f3d42a771458089287d6 Mon Sep 17 00:00:00 2001 From: ck Date: Thu, 1 Oct 2009 17:13:27 +0200 Subject: [PATCH] Some work towards functioning remote debugging Fix gdb commands, state changes and signals emissions. - There were some invalid gdb commands (e.g. "attach"). - There also were a number of unexplected state transitions. --- src/plugins/debugger/gdb/remotegdbadapter.cpp | 74 +++++++++---------- src/plugins/debugger/gdb/remotegdbadapter.h | 4 +- 2 files changed, 37 insertions(+), 41 deletions(-) diff --git a/src/plugins/debugger/gdb/remotegdbadapter.cpp b/src/plugins/debugger/gdb/remotegdbadapter.cpp index 233f96e1ddb..9dc6a48fd3e 100644 --- a/src/plugins/debugger/gdb/remotegdbadapter.cpp +++ b/src/plugins/debugger/gdb/remotegdbadapter.cpp @@ -86,12 +86,12 @@ void RemoteGdbAdapter::startAdapter() gdbArgs.prepend(_("mi")); gdbArgs.prepend(_("-i")); - if (!m_engine->m_outputCollector.listen()) { - emit adapterStartFailed(tr("Cannot set up communication with child process: %1") - .arg(m_engine->m_outputCollector.errorString())); - return; - } - gdbArgs.prepend(_("--tty=") + m_engine->m_outputCollector.serverName()); +// if (!m_engine->m_outputCollector.listen()) { +// emit adapterStartFailed(tr("Cannot set up communication with child process: %1") +// .arg(m_engine->m_outputCollector.errorString())); +// return; +// } +// gdbArgs.prepend(_("--tty=") + m_engine->m_outputCollector.serverName()); if (!startParameters().workingDir.isEmpty()) setWorkingDirectory(startParameters().workingDir); @@ -193,20 +193,23 @@ void RemoteGdbAdapter::prepareInferior() m_engine->postCommand(_("-exec-arguments ") + startParameters().processArgs.join(_(" "))); - //qq->breakHandler()->setAllPending(); - QFileInfo fi(startParameters().executable); - QString fileName = fi.absoluteFilePath(); - m_engine->postCommand(_("-file-exec-and-symbols \"%1\"").arg(fileName), - CB(handleFileExecAndSymbols)); + m_engine->postCommand(_("set target-async on"), CB(handleSetTargetAsync)); +} - // works only for > 6.8 - //postCommand(_("set target-async on"), CB(handleSetTargetAsync)); - // a typical response on "old" gdb is: - // &"set target-async on\n" - //&"No symbol table is loaded. Use the \"file\" command.\n" - //^error,msg="No symbol table is loaded. Use the \"file\" command." - //postCommand(_("detach")); - //emit inferiorPreparationFailed(msg); +void RemoteGdbAdapter::handleSetTargetAsync(const GdbResponse &response) +{ + QTC_ASSERT(state() == InferiorPreparing, qDebug() << state()); + if (response.resultClass == GdbResultDone) { + //qq->breakHandler()->setAllPending(); + QFileInfo fi(startParameters().executable); + QString fileName = fi.absoluteFilePath(); + m_engine->postCommand(_("-file-exec-and-symbols \"%1\"").arg(fileName), + CB(handleFileExecAndSymbols)); + } else if (response.resultClass == GdbResultError) { + QString msg = tr("Adapter too old: does not support asynchronous mode."); + setState(InferiorPreparationFailed); + emit inferiorPreparationFailed(msg); + } } void RemoteGdbAdapter::handleFileExecAndSymbols(const GdbResponse &response) @@ -214,9 +217,8 @@ void RemoteGdbAdapter::handleFileExecAndSymbols(const GdbResponse &response) QTC_ASSERT(state() == InferiorPreparing, qDebug() << state()); if (response.resultClass == GdbResultDone) { //m_breakHandler->clearBreakMarkers(); - QString channel = startParameters().remoteChannel; - m_engine->postCommand(_("target remote %1").arg(channel), - CB(handleTargetRemote)); + m_engine->setState(InferiorPrepared); + emit inferiorPrepared(); } else if (response.resultClass == GdbResultError) { QString msg = tr("Starting remote executable failed:\n"); msg += __(response.data.findChild("msg").data()); @@ -227,10 +229,11 @@ void RemoteGdbAdapter::handleFileExecAndSymbols(const GdbResponse &response) void RemoteGdbAdapter::handleTargetRemote(const GdbResponse &record) { - QTC_ASSERT(state() == InferiorPreparing, qDebug() << state()); + QTC_ASSERT(state() == InferiorStarting, qDebug() << state()); if (record.resultClass == GdbResultDone) { - setState(InferiorPrepared); - emit inferiorPrepared(); + // gdb server will stop the remote application itself. + debugMessage(_("INFERIOR STARTED")); + showStatusMessage(tr("Attached to stopped inferior.")); } else if (record.resultClass == GdbResultError) { // 16^error,msg="hd:5555: Connection timed out." QString msg = tr("Connecting to remote server failed:\n"); @@ -243,21 +246,14 @@ void RemoteGdbAdapter::handleTargetRemote(const GdbResponse &record) void RemoteGdbAdapter::startInferior() { QTC_ASSERT(state() == InferiorStarting, qDebug() << state()); - m_engine->postCommand(_("attach"), CB(handleFirstContinue)); -} + QString channel = startParameters().remoteChannel; -void RemoteGdbAdapter::handleFirstContinue(const GdbResponse &record) -{ - QTC_ASSERT(state() == InferiorRunningRequested, qDebug() << state()); - if (record.resultClass == GdbResultDone) { - setState(InferiorStopped); - debugMessage(_("INFERIOR STARTED")); - showStatusMessage(tr("Attached to stopped inferior.")); - } else if (record.resultClass == GdbResultError) { - //QString msg = __(record.data.findChild("msg").data()); - QString msg1 = tr("Connecting to remote server failed:\n"); - emit inferiorStartFailed(msg1 + record.toString()); - } + // "target remote" does three things: + // (1) connects to the gdb server + // (2) starts the remote application + // (3) stops the remote application (early, e.g. in the dynamic linker) + m_engine->postCommand(_("target remote %1").arg(channel), + CB(handleTargetRemote)); } void RemoteGdbAdapter::interruptInferior() diff --git a/src/plugins/debugger/gdb/remotegdbadapter.h b/src/plugins/debugger/gdb/remotegdbadapter.h index 15ef70c6f7b..6842e118296 100644 --- a/src/plugins/debugger/gdb/remotegdbadapter.h +++ b/src/plugins/debugger/gdb/remotegdbadapter.h @@ -71,11 +71,11 @@ private: Q_SLOT void readUploadStandardError(); Q_SLOT void uploadProcError(QProcess::ProcessError error); + void handleSetTargetAsync(const GdbResponse &response); void handleFileExecAndSymbols(const GdbResponse &response); + void handleTargetRemote(const GdbResponse &response); void handleKill(const GdbResponse &response); void handleExit(const GdbResponse &response); - void handleTargetRemote(const GdbResponse &response); - void handleFirstContinue(const GdbResponse &response); Q_SLOT void handleGdbStarted(); Q_SLOT void handleGdbError(QProcess::ProcessError error);