Don't stall waiting for target to crash

This modifies debuggerd to sleep-poll while waiting for the target
process to crash, rather than block (potentially forever).

Also, add/fix some error reporting.

Bug 5035703

Change-Id: Id62ab79f53104927f8de684dff1a5734dbdb8390
diff --git a/debuggerd/debuggerd.c b/debuggerd/debuggerd.c
index 892bc99..d03c214 100644
--- a/debuggerd/debuggerd.c
+++ b/debuggerd/debuggerd.c
@@ -593,19 +593,39 @@
      * debugger_signal_handler().
      */
     tid_attach_status = ptrace(PTRACE_ATTACH, tid, 0, 0);
+    int ptrace_error = errno;
 
-    TEMP_FAILURE_RETRY(write(fd, &tid, 1));
+    if (TEMP_FAILURE_RETRY(write(fd, &tid, 1)) != 1) {
+        XLOG("failed responding to client: %s\n",
+            strerror(errno));
+        goto done;
+    }
 
     if(tid_attach_status < 0) {
-        LOG("ptrace attach failed: %s\n", strerror(errno));
+        LOG("ptrace attach failed: %s\n", strerror(ptrace_error));
         goto done;
     }
 
     close(fd);
     fd = -1;
 
+    const int sleep_time_usec = 200000;         /* 0.2 seconds */
+    const int max_total_sleep_usec = 3000000;   /* 3 seconds */
+    int loop_limit = max_total_sleep_usec / sleep_time_usec;
     for(;;) {
-        n = waitpid(tid, &status, __WALL);
+        if (loop_limit-- == 0) {
+            LOG("timed out waiting for pid=%d tid=%d uid=%d to die\n",
+                cr.pid, tid, cr.uid);
+            goto done;
+        }
+        n = waitpid(tid, &status, __WALL | WNOHANG);
+
+        if (n == 0) {
+            /* not ready yet */
+            XLOG("not ready yet\n");
+            usleep(sleep_time_usec);
+            continue;
+        }
 
         if(n < 0) {
             if(errno == EAGAIN) continue;
@@ -734,8 +754,12 @@
         int fd;
 
         alen = sizeof(addr);
+        XLOG("waiting for connection\n");
         fd = accept(s, &addr, &alen);
-        if(fd < 0) continue;
+        if(fd < 0) {
+            XLOG("accept failed: %s\n", strerror(errno));
+            continue;
+        }
 
         fcntl(fd, F_SETFD, FD_CLOEXEC);