summaryrefslogtreecommitdiffstats
path: root/debuggerd
diff options
context:
space:
mode:
authorDavid 'Digit' Turner <digit@google.com>2011-01-21 04:27:12 +0100
committerDavid 'Digit' Turner <digit@google.com>2011-01-21 04:27:12 +0100
commit02526d486803de153d03851f4d5f9be7c555e46c (patch)
treee259d7324cddf635a92e68252c0b1b260ed672e0 /debuggerd
parentc1b546b22dc229fdbef9105f010e3ac0172cfc8f (diff)
downloadcore-02526d486803de153d03851f4d5f9be7c555e46c.tar.gz
core-02526d486803de153d03851f4d5f9be7c555e46c.tar.bz2
core-02526d486803de153d03851f4d5f9be7c555e46c.zip
debuggerd: properly unblock signal handler.
This change ensures that debuggered properly releases the signal handler that invoked it after the PTRACE_ATTACH. The previous code simply did a close() of the file descriptor, but for some reason, this didn't always make the read() blocking the signal handler exit. Instead, the thread would stay blocked and never fault, preventing the generation of a useful stack trace. Change-Id: I6b0579041165a710d74ec1bece113ff7b828aed4
Diffstat (limited to 'debuggerd')
-rw-r--r--debuggerd/debuggerd.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/debuggerd/debuggerd.c b/debuggerd/debuggerd.c
index 5fa444221..7a3e781ec 100644
--- a/debuggerd/debuggerd.c
+++ b/debuggerd/debuggerd.c
@@ -642,7 +642,7 @@ static void handle_crashing_process(int fd)
goto done;
}
- sprintf(buf,"/proc/%d/task/%d", cr.pid, tid);
+ snprintf(buf, sizeof buf, "/proc/%d/task/%d", cr.pid, tid);
if(stat(buf, &s)) {
LOG("tid %d does not exist in pid %d. ignoring debug request\n",
tid, cr.pid);
@@ -652,7 +652,19 @@ static void handle_crashing_process(int fd)
XLOG("BOOM: pid=%d uid=%d gid=%d tid=%d\n", cr.pid, cr.uid, cr.gid, tid);
+ /* Note that at this point, the target thread's signal handler
+ * is blocked in a read() call. This gives us the time to PTRACE_ATTACH
+ * to it before it has a chance to really fault.
+ *
+ * After the attach, the thread is stopped, and we write to the file
+ * descriptor to ensure that it will run as soon as we call PTRACE_CONT
+ * below. See details in bionic/libc/linker/debugger.c, in function
+ * debugger_signal_handler().
+ */
tid_attach_status = ptrace(PTRACE_ATTACH, tid, 0, 0);
+
+ TEMP_FAILURE_RETRY(write(fd, &tid, 1));
+
if(tid_attach_status < 0) {
LOG("ptrace attach failed: %s\n", strerror(errno));
goto done;