summaryrefslogtreecommitdiff
path: root/src/plugins
diff options
context:
space:
mode:
authorOswald Buddenhagen <oswald.buddenhagen@nokia.com>2009-10-30 17:16:56 +0100
committerOswald Buddenhagen <oswald.buddenhagen@nokia.com>2009-10-30 17:47:51 +0100
commit151b785d010b85ee0b5788f5ea95c4154d7530e0 (patch)
tree6e43ac7807274828130892478ec3645ae2696f10 /src/plugins
parent6d6ed26eae39fc6d4b2e843edb8498e0008f15ef (diff)
downloadqt-creator-151b785d010b85ee0b5788f5ea95c4154d7530e0.tar.gz
terminal adapter: make skipping of initial SIGSTOPs more reliable
first, _start being resolvable depends on libc-dbg being installed. second, depending on the frame being in the dynloader makes it a) work only for dynamic executables and b) fail on multi-target systems (due to a hard-coded file name). so instead just remember the entry point, as we are already there anyway. Reviewed-By: hjk
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/debugger/gdb/gdbengine.cpp22
-rw-r--r--src/plugins/debugger/gdb/gdbengine.h4
-rw-r--r--src/plugins/debugger/gdb/termgdbadapter.cpp14
-rw-r--r--src/plugins/debugger/gdb/termgdbadapter.h3
4 files changed, 35 insertions, 8 deletions
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index 2fdde0ac2a..06d5b1f339 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 1229cc17d9..2636d16c8d 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 e5f43eef21..b369dad4c6 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 11fb04a2c4..1b98eed987 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();