am 02526d48: debuggerd: properly unblock signal handler.

* commit '02526d486803de153d03851f4d5f9be7c555e46c':
  debuggerd: properly unblock signal handler.
diff --git a/debuggerd/debuggerd.c b/debuggerd/debuggerd.c
index 5fa4442..7a3e781 100644
--- a/debuggerd/debuggerd.c
+++ b/debuggerd/debuggerd.c
@@ -642,7 +642,7 @@
         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 @@
 
     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;