Provide method to dump backtrace heap data.

For non-zygote spawned processes, we might want to dump the backtrace
data. Provide a method to send a signal to a process and then dump the
data to a file.

Adds a method to dump the backtrace data on exit.

Update documentation and explain format of heap dump data.

Test: Ran unit tests, enabled new options and used them.
Change-Id: Ie2fa706694160731afe02c1382b037d06df1d069
diff --git a/libc/malloc_debug/BacktraceData.cpp b/libc/malloc_debug/BacktraceData.cpp
index 752d507..65ae6fa 100644
--- a/libc/malloc_debug/BacktraceData.cpp
+++ b/libc/malloc_debug/BacktraceData.cpp
@@ -41,12 +41,12 @@
 #include "debug_log.h"
 #include "malloc_debug.h"
 
-static void EnableToggle(int, siginfo_t*, void*) {
-  if (g_debug->backtrace->enabled()) {
-    g_debug->backtrace->set_enabled(false);
-  } else {
-    g_debug->backtrace->set_enabled(true);
-  }
+static void ToggleBacktraceEnable(int, siginfo_t*, void*) {
+  g_debug->backtrace->ToggleBacktraceEnabled();
+}
+
+static void EnableDump(int, siginfo_t*, void*) {
+  g_debug->backtrace->EnableDumping();
 }
 
 BacktraceData::BacktraceData(DebugData* debug_data, const Config& config, size_t* offset)
@@ -62,7 +62,7 @@
     struct sigaction enable_act;
     memset(&enable_act, 0, sizeof(enable_act));
 
-    enable_act.sa_sigaction = EnableToggle;
+    enable_act.sa_sigaction = ToggleBacktraceEnable;
     enable_act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
     sigemptyset(&enable_act.sa_mask);
     if (sigaction(config.backtrace_signal(), &enable_act, nullptr) != 0) {
@@ -72,5 +72,20 @@
     info_log("%s: Run: 'kill -%d %d' to enable backtracing.", getprogname(),
              config.backtrace_signal(), getpid());
   }
+
+  struct sigaction act;
+  memset(&act, 0, sizeof(act));
+
+  act.sa_sigaction = EnableDump;
+  act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
+  sigemptyset(&act.sa_mask);
+  if (sigaction(config.backtrace_dump_signal(), &act, nullptr) != 0) {
+    error_log("Unable to set up backtrace dump signal function: %s", strerror(errno));
+    return false;
+  }
+  info_log("%s: Run: 'kill -%d %d' to dump the backtrace.", getprogname(),
+           config.backtrace_dump_signal(), getpid());
+
+  dump_ = false;
   return true;
 }