Change Addr2line to use poll.

Moving from select to poll avoids any problems with the fd being
too large for the call to FD_SET. It also slightly simplifies the code.

Make sure that the call to read only ever occurs if there is really data
to be read. There was a case with the previous use of the select call
where the read would be called when there was no data to be read which
caused the process to hang forever.

Test: Ran the 137 test forcing a crash and verified the addr2line
Test: information is correct.
Test: Ran the 141 test forcing a crash and verifying that when more than
Test: two lines are returned by addr2line, it still display them all.
Test: Modified the Addr2line call to pass in an emptry string for the
Test: executable and verified there are no hangs.
Change-Id: I3d750e7796d0c70122686aad1eb40856157c9770
diff --git a/runtime/native_stack_dump.cc b/runtime/native_stack_dump.cc
index 396b09a..530c266 100644
--- a/runtime/native_stack_dump.cc
+++ b/runtime/native_stack_dump.cc
@@ -32,6 +32,7 @@
 #include <vector>
 
 #include <linux/unistd.h>
+#include <poll.h>
 #include <signal.h>
 #include <stdlib.h>
 #include <sys/time.h>
@@ -145,21 +146,14 @@
   bool prefix_written = false;
 
   for (;;) {
-    constexpr uint32_t kWaitTimeExpectedMicros = 500 * 1000;
-    constexpr uint32_t kWaitTimeUnexpectedMicros = 50 * 1000;
+    constexpr uint32_t kWaitTimeExpectedMilli = 500;
+    constexpr uint32_t kWaitTimeUnexpectedMilli = 50;
 
-    struct timeval tv;
-    tv.tv_sec = 0;
-    tv.tv_usec = expected > 0 ? kWaitTimeExpectedMicros : kWaitTimeUnexpectedMicros;
-
-    fd_set rfds;
-    FD_ZERO(&rfds);
-    FD_SET(in, &rfds);
-
-    int retval = TEMP_FAILURE_RETRY(select(in + 1, &rfds, nullptr, nullptr, &tv));
-
-    if (retval < 0) {
-      // Other side may have crashed or other errors.
+    int timeout = expected > 0 ? kWaitTimeExpectedMilli : kWaitTimeUnexpectedMilli;
+    struct pollfd read_fd{in, POLLIN, 0};
+    int retval = TEMP_FAILURE_RETRY(poll(&read_fd, 1, timeout));
+    if (retval == -1) {
+      // An error occurred.
       pipe->reset();
       return;
     }
@@ -169,19 +163,23 @@
       return;
     }
 
-    DCHECK_EQ(retval, 1);
+    if (!(read_fd.revents & POLLIN)) {
+      // addr2line call exited.
+      pipe->reset();
+      return;
+    }
 
     constexpr size_t kMaxBuffer = 128;  // Relatively small buffer. Should be OK as we're on an
     // alt stack, but just to be sure...
     char buffer[kMaxBuffer];
     memset(buffer, 0, kMaxBuffer);
     int bytes_read = TEMP_FAILURE_RETRY(read(in, buffer, kMaxBuffer - 1));
-
-    if (bytes_read < 0) {
+    if (bytes_read <= 0) {
       // This should not really happen...
       pipe->reset();
       return;
     }
+    buffer[bytes_read] = '\0';
 
     char* tmp = buffer;
     while (*tmp != 0) {