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/Config.cpp b/libc/malloc_debug/Config.cpp
index df453a9..e3798ab 100644
--- a/libc/malloc_debug/Config.cpp
+++ b/libc/malloc_debug/Config.cpp
@@ -56,6 +56,7 @@
 
 static constexpr size_t DEFAULT_BACKTRACE_FRAMES = 16;
 static constexpr size_t MAX_BACKTRACE_FRAMES = 256;
+static constexpr const char DEFAULT_BACKTRACE_DUMP_PREFIX[] = "/data/local/tmp/backtrace_heap";
 
 static constexpr size_t DEFAULT_EXPAND_BYTES = 16;
 static constexpr size_t MAX_EXPAND_BYTES = 16384;
@@ -85,6 +86,13 @@
       {BACKTRACE | TRACK_ALLOCS, &Config::SetBacktraceEnableOnSignal},
     },
 
+    {"backtrace_dump_on_exit",
+      {0, &Config::SetBacktraceDumpOnExit},
+    },
+    {"backtrace_dump_prefix",
+      {0, &Config::SetBacktraceDumpPrefix},
+    },
+
     {"fill",
       {FILL_ON_ALLOC | FILL_ON_FREE, &Config::SetFill},
     },
@@ -236,6 +244,24 @@
                     &backtrace_frames_);
 }
 
+bool Config::SetBacktraceDumpOnExit(const std::string& option, const std::string& value) {
+  if (Config::VerifyValueEmpty(option, value)) {
+    backtrace_dump_on_exit_ = true;
+    return true;
+  }
+  return false;
+}
+
+bool Config::SetBacktraceDumpPrefix(const std::string&, const std::string& value) {
+  if (value.empty()) {
+    backtrace_dump_prefix_ = DEFAULT_BACKTRACE_DUMP_PREFIX;
+  } else {
+    backtrace_dump_prefix_ = value;
+  }
+  return true;
+}
+
+
 bool Config::SetExpandAlloc(const std::string& option, const std::string& value) {
   return ParseValue(option, value, DEFAULT_EXPAND_BYTES, 1, MAX_EXPAND_BYTES, &expand_alloc_bytes_);
 }
@@ -309,6 +335,9 @@
   error_log("  backtrace[=XX]");
   error_log("    Enable capturing the backtrace at the point of allocation.");
   error_log("    If XX is set it sets the number of backtrace frames.");
+  error_log("    This option also enables dumping the backtrace heap data");
+  error_log("    when a signal is received. The data is dumped to the file");
+  error_log("    backtrace_dump_prefix.<PID>.txt.");
   error_log("    The default is %zu frames, the max number of frames is %zu.",
             DEFAULT_BACKTRACE_FRAMES, MAX_BACKTRACE_FRAMES);
   error_log("");
@@ -319,6 +348,19 @@
   error_log("    frames. The default is %zu frames, the max number of frames is %zu.",
             DEFAULT_BACKTRACE_FRAMES, MAX_BACKTRACE_FRAMES);
   error_log("");
+  error_log("  backtrace_dump_prefix[=FILE]");
+  error_log("    This option only has meaning if the backtrace option has been specified.");
+  error_log("    This is the prefix of the name of the file to which backtrace heap");
+  error_log("    data will be dumped. The file will be named backtrace_dump_prefix.<PID>.txt.");
+  error_log("    The default is %s.", DEFAULT_BACKTRACE_DUMP_PREFIX);
+
+  error_log("");
+  error_log("  backtrace_dump_on_exit");
+  error_log("    This option only has meaning if the backtrace option has been specified.");
+  error_log("    This will cause all live allocations to be dumped to the file");
+  error_log("    backtrace_dump_prefix.<PID>.final.txt.");
+  error_log("    The default is false.");
+  error_log("");
   error_log("  fill_on_alloc[=XX]");
   error_log("    On first allocation, fill with the value 0x%02x.", DEFAULT_FILL_ALLOC_VALUE);
   error_log("    If XX is set it will only fill up to XX bytes of the");
@@ -426,12 +468,15 @@
   front_guard_value_ = DEFAULT_FRONT_GUARD_VALUE;
   rear_guard_value_ = DEFAULT_REAR_GUARD_VALUE;
   backtrace_signal_ = SIGRTMAX - 19;
+  backtrace_dump_signal_ = SIGRTMAX - 17;
   record_allocs_signal_ = SIGRTMAX - 18;
   free_track_backtrace_num_frames_ = 0;
   record_allocs_file_.clear();
   fill_on_free_bytes_ = 0;
   backtrace_enable_on_signal_ = false;
   backtrace_enabled_ = false;
+  backtrace_dump_on_exit_ = false;
+  backtrace_dump_prefix_ = DEFAULT_BACKTRACE_DUMP_PREFIX;
 
   // Process each option name we can find.
   std::string option;