diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 2fdde0ac2a1561e7fabd5e8a597604ad5a540f3b..06d5b1f3394388db56a90fe6f71a2e4d59975bb0 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -285,6 +285,9 @@ void GdbEngine::initializeVariables() m_currentFunctionArgs.clear(); m_currentFrame.clear(); m_dumperHelper.clear(); +#ifdef Q_OS_LINUX + m_entryPoint.clear(); +#endif } QString GdbEngine::errorMessage(QProcess::ProcessError error) @@ -1068,16 +1071,19 @@ void GdbEngine::handleStopResponse(const GdbMi &data) #ifdef Q_OS_LINUX // For some reason, attaching to a stopped process causes *two* stops - // when trying to continue (kernel 2.6.24-23-ubuntu). + // when trying to continue (kernel i386 2.6.24-23-ubuntu, gdb 6.8). // Interestingly enough, on MacOSX no signal is delivered at all. - if (reason == "signal-received" - && data.findChild("signal-name").data() == "SIGSTOP") { - GdbMi frameData = data.findChild("frame"); - if (frameData.findChild("func").data() == "_start" - && frameData.findChild("from").data() == "/lib/ld-linux.so.2") { - continueInferiorInternal(); - return; + if (!m_entryPoint.isEmpty()) { + if (reason == "signal-received" + && data.findChild("signal-name").data() == "SIGSTOP") { + GdbMi frameData = data.findChild("frame"); + if (frameData.findChild("addr").data() == m_entryPoint) { + continueInferiorInternal(); + return; + } } + // We are past the initial stops. No need to waste time on further checks. + m_entryPoint.clear(); } #endif diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index 1229cc17d9d759a862a4f33d6cbe3e7592a4f09c..2636d16c8dd69bfd637cfc8d04a8cb563ebd3b8a 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -294,6 +294,10 @@ private: ////////// Inferior Management ////////// void handleInferiorPidChanged(qint64 pid) { manager()->notifyInferiorPidChanged(pid); } void maybeHandleInferiorPidChanged(const QString &pid); +#ifdef Q_OS_LINUX + QByteArray m_entryPoint; +#endif + private: ////////// View & Data Stuff ////////// virtual void selectThread(int index); diff --git a/src/plugins/debugger/gdb/termgdbadapter.cpp b/src/plugins/debugger/gdb/termgdbadapter.cpp index e5f43eef211b940d49fc038204c624e969dc56ac..b369dad4c6d8d92597686f0f841c528013981188 100644 --- a/src/plugins/debugger/gdb/termgdbadapter.cpp +++ b/src/plugins/debugger/gdb/termgdbadapter.cpp @@ -119,6 +119,9 @@ void TermGdbAdapter::handleStubAttached(const GdbResponse &response) setState(InferiorStopped); debugMessage(_("INFERIOR ATTACHED")); emit inferiorPrepared(); +#ifdef Q_OS_LINUX + m_engine->postCommand(_("-stack-list-frames 0 0"), CB(handleEntryPoint)); +#endif } else if (response.resultClass == GdbResultError) { QString msg = _(response.data.findChild("msg").data()); emit inferiorStartFailed(msg); @@ -130,6 +133,17 @@ void TermGdbAdapter::startInferiorPhase2() m_engine->continueInferiorInternal(); } +#ifdef Q_OS_LINUX +void TermGdbAdapter::handleEntryPoint(const GdbResponse &response) +{ + if (response.resultClass == GdbResultDone) { + GdbMi stack = response.data.findChild("stack"); + if (stack.isValid() && stack.childCount() == 1) + m_engine->m_entryPoint = stack.childAt(0).findChild("addr").data(); + } +} +#endif + void TermGdbAdapter::interruptInferior() { const qint64 attachedPID = m_engine->inferiorPid(); diff --git a/src/plugins/debugger/gdb/termgdbadapter.h b/src/plugins/debugger/gdb/termgdbadapter.h index 11fb04a2c4cb03b9918fa934f36094377fc55fa6..1b98eed9874bc906b09d7829a2267afb117a3056 100644 --- a/src/plugins/debugger/gdb/termgdbadapter.h +++ b/src/plugins/debugger/gdb/termgdbadapter.h @@ -60,6 +60,9 @@ public: private: void handleStubAttached(const GdbResponse &response); +#ifdef Q_OS_LINUX + void handleEntryPoint(const GdbResponse &response); +#endif Q_SLOT void handleInferiorStarted(); Q_SLOT void stubExited();