debuggerd_handler: implement missing fallback functionality.

Allow the fallback implementation to dump traces and create tombstones
in seccomped processes.

Bug: http://b/35858739
Test: debuggerd -b `pidof media.codec`; killall -ABRT media.codec
Change-Id: I381b283de39a66d8900f1c320d32497d6f2b4ec4
diff --git a/debuggerd/libdebuggerd/backtrace.cpp b/debuggerd/libdebuggerd/backtrace.cpp
index 0664442..df49aef 100644
--- a/debuggerd/libdebuggerd/backtrace.cpp
+++ b/debuggerd/libdebuggerd/backtrace.cpp
@@ -67,15 +67,15 @@
   _LOG(log, logtype::BACKTRACE, "\n----- end %d -----\n", pid);
 }
 
-static void dump_thread(log_t* log, BacktraceMap* map, pid_t pid, pid_t tid) {
-  char path[PATH_MAX];
-  char threadnamebuf[1024];
-  char* threadname = NULL;
+static void log_thread_name(log_t* log, pid_t tid) {
   FILE* fp;
+  char buf[1024];
+  char path[PATH_MAX];
+  char* threadname = NULL;
 
   snprintf(path, sizeof(path), "/proc/%d/comm", tid);
   if ((fp = fopen(path, "r"))) {
-    threadname = fgets(threadnamebuf, sizeof(threadnamebuf), fp);
+    threadname = fgets(buf, sizeof(buf), fp);
     fclose(fp);
     if (threadname) {
       size_t len = strlen(threadname);
@@ -84,8 +84,11 @@
       }
     }
   }
-
   _LOG(log, logtype::BACKTRACE, "\n\"%s\" sysTid=%d\n", threadname ? threadname : "<unknown>", tid);
+}
+
+static void dump_thread(log_t* log, BacktraceMap* map, pid_t pid, pid_t tid) {
+  log_thread_name(log, tid);
 
   std::unique_ptr<Backtrace> backtrace(Backtrace::Create(pid, tid, map));
   if (backtrace->Unwind(0)) {
@@ -112,6 +115,41 @@
   dump_process_footer(&log, pid);
 }
 
+void dump_backtrace_ucontext(int output_fd, ucontext_t* ucontext) {
+  pid_t pid = getpid();
+  pid_t tid = gettid();
+
+  log_t log;
+  log.tfd = output_fd;
+  log.amfd_data = nullptr;
+
+  log_thread_name(&log, tid);
+
+  std::unique_ptr<Backtrace> backtrace(Backtrace::Create(pid, tid));
+  if (backtrace->Unwind(0, ucontext)) {
+    dump_backtrace_to_log(backtrace.get(), &log, "  ");
+  } else {
+    ALOGE("Unwind failed: tid = %d: %s", tid,
+          backtrace->GetErrorString(backtrace->GetError()).c_str());
+  }
+}
+
+void dump_backtrace_header(int output_fd) {
+  log_t log;
+  log.tfd = output_fd;
+  log.amfd_data = nullptr;
+
+  dump_process_header(&log, getpid());
+}
+
+void dump_backtrace_footer(int output_fd) {
+  log_t log;
+  log.tfd = output_fd;
+  log.amfd_data = nullptr;
+
+  dump_process_footer(&log, getpid());
+}
+
 void dump_backtrace_to_log(Backtrace* backtrace, log_t* log, const char* prefix) {
   for (size_t i = 0; i < backtrace->NumFrames(); i++) {
     _LOG(log, logtype::BACKTRACE, "%s%s\n", prefix, backtrace->FormatFrameData(i).c_str());