diff options
author | David 'Digit' Turner <digit@google.com> | 2011-01-21 04:27:12 +0100 |
---|---|---|
committer | David 'Digit' Turner <digit@google.com> | 2011-01-21 04:27:12 +0100 |
commit | 02526d486803de153d03851f4d5f9be7c555e46c (patch) | |
tree | e259d7324cddf635a92e68252c0b1b260ed672e0 /debuggerd | |
parent | c1b546b22dc229fdbef9105f010e3ac0172cfc8f (diff) | |
download | core-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.c | 14 |
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; |