debuggerd: rethrow the full signal we receive, always.

The previous code assumed that returning would be sufficient to rethrow
signals like SIGSEGV. This is not true, for example,  in the case where a
SIGSEGV is sent via kill(2). We were previously only sending the signal
to ourselves in some cases, because using kill(2) would lose information
in the siginfo_t argument. Use rt_tgsigqueueinfo(2) instead to preserve
its contents.

Bug: http://b/27367422
Change-Id: I1be822818d5905461979c7e12dc4e9c25049273b
(cherry picked from commit 61cf3f3e033d2d7d13b06e0ae009ff12db787860)
diff --git a/linker/debugger.cpp b/linker/debugger.cpp
index 3731c99..670d1ea 100644
--- a/linker/debugger.cpp
+++ b/linker/debugger.cpp
@@ -38,6 +38,7 @@
 #include <sys/mman.h>
 #include <sys/prctl.h>
 #include <sys/socket.h>
+#include <sys/syscall.h>
 #include <sys/un.h>
 #include <unistd.h>
 
@@ -60,7 +61,9 @@
   DEBUGGER_ACTION_DUMP_BACKTRACE,
 };
 
-/* message sent over the socket */
+// Message sent over the socket.
+// NOTE: Any changes to this structure must also be reflected in
+//       system/core/include/cutils/debugger.h.
 struct __attribute__((packed)) debugger_msg_t {
   int32_t action;
   pid_t tid;
@@ -266,26 +269,32 @@
 
   send_debuggerd_packet(info);
 
-  // Remove our net so we fault for real when we return.
+  // We need to return from the signal handler so that debuggerd can dump the
+  // thread that crashed, but returning here does not guarantee that the signal
+  // will be thrown again, even for SIGSEGV and friends, since the signal could
+  // have been sent manually. Resend the signal with rt_tgsigqueueinfo(2) to
+  // preserve the SA_SIGINFO contents.
   signal(signal_number, SIG_DFL);
 
-  // These signals are not re-thrown when we resume.  This means that
-  // crashing due to (say) SIGABRT doesn't work the way you'd expect it
-  // to.  We work around this by throwing them manually.  We don't want
-  // to do this for *all* signals because it'll screw up the si_addr for
-  // faults like SIGSEGV. It does screw up the si_code, which is why we
-  // passed that to debuggerd above.
-  switch (signal_number) {
-    case SIGABRT:
-    case SIGFPE:
-#if defined(SIGSTKFLT)
-    case SIGSTKFLT:
-#endif
-    case SIGTRAP:
-      tgkill(getpid(), gettid(), signal_number);
-      break;
-    default:    // SIGILL, SIGBUS, SIGSEGV
-      break;
+  struct siginfo si;
+  if (!info) {
+    memset(&si, 0, sizeof(si));
+    si.si_code = SI_USER;
+    si.si_pid = getpid();
+    si.si_uid = getuid();
+    info = &si;
+  } else if (info->si_code >= 0 || info->si_code == SI_TKILL) {
+    // rt_tgsigqueueinfo(2)'s documentation appears to be incorrect on kernels
+    // that contain commit 66dd34a (3.9+). The manpage claims to only allow
+    // negative si_code values that are not SI_TKILL, but 66dd34a changed the
+    // check to allow all si_code values in calls coming from inside the house.
+  }
+
+  int rc = syscall(SYS_rt_tgsigqueueinfo, getpid(), gettid(), signal_number, info);
+  if (rc != 0) {
+    __libc_format_log(ANDROID_LOG_FATAL, "libc", "failed to resend signal during crash: %s",
+                      strerror(errno));
+    _exit(0);
   }
 }