From 02526d486803de153d03851f4d5f9be7c555e46c Mon Sep 17 00:00:00 2001 From: David 'Digit' Turner Date: Fri, 21 Jan 2011 04:27:12 +0100 Subject: 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 --- debuggerd/debuggerd.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'debuggerd') 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; -- cgit v1.2.3