Changing how debuggerd filters log messages to different locations.

The system by which debuggerd filters its output to different locations
is now based on an enum called logtype with easy to understand
categories for log messages (like THREAD, MEMORY, etc.) instead of the
old, fairly esoteric scope_flags variable.  Now much of the output that
previously went to logcat does not show up on the screen, but all output
can be found in the tombstone file.  In addition, the tombstone's
location is now printed so it can be located easily.

Bug: 15341747
Change-Id: Ia2f2051d1dfdea934d0e6ed220f24345e35ba6a2
diff --git a/debuggerd/arm/machine.cpp b/debuggerd/arm/machine.cpp
index fd2f69b..839d47a 100644
--- a/debuggerd/arm/machine.cpp
+++ b/debuggerd/arm/machine.cpp
@@ -40,57 +40,55 @@
 
 // If configured to do so, dump memory around *all* registers
 // for the crashing thread.
-void dump_memory_and_code(log_t* log, pid_t tid, int scope_flags) {
+void dump_memory_and_code(log_t* log, pid_t tid) {
   struct pt_regs regs;
   if (ptrace(PTRACE_GETREGS, tid, 0, &regs)) {
     return;
   }
 
-  if (IS_AT_FAULT(scope_flags) && DUMP_MEMORY_FOR_ALL_REGISTERS) {
-    static const char REG_NAMES[] = "r0r1r2r3r4r5r6r7r8r9slfpipsp";
+  static const char REG_NAMES[] = "r0r1r2r3r4r5r6r7r8r9slfpipsp";
 
-    for (int reg = 0; reg < 14; reg++) {
-      // this may not be a valid way to access, but it'll do for now
-      uintptr_t addr = regs.uregs[reg];
+  for (int reg = 0; reg < 14; reg++) {
+    // this may not be a valid way to access, but it'll do for now
+    uintptr_t addr = regs.uregs[reg];
 
-      // Don't bother if it looks like a small int or ~= null, or if
-      // it's in the kernel area.
-      if (addr < 4096 || addr >= 0xc0000000) {
-        continue;
-      }
-
-      _LOG(log, scope_flags | SCOPE_SENSITIVE, "\nmemory near %.2s:\n", &REG_NAMES[reg * 2]);
-      dump_memory(log, tid, addr, scope_flags | SCOPE_SENSITIVE);
+    // Don't bother if it looks like a small int or ~= null, or if
+    // it's in the kernel area.
+    if (addr < 4096 || addr >= 0xc0000000) {
+      continue;
     }
+
+    _LOG(log, logtype::MEMORY, "\nmemory near %.2s:\n", &REG_NAMES[reg * 2]);
+    dump_memory(log, tid, addr);
   }
 
   // explicitly allow upload of code dump logging
-  _LOG(log, scope_flags, "\ncode around pc:\n");
-  dump_memory(log, tid, static_cast<uintptr_t>(regs.ARM_pc), scope_flags);
+  _LOG(log, logtype::MEMORY, "\ncode around pc:\n");
+  dump_memory(log, tid, static_cast<uintptr_t>(regs.ARM_pc));
 
   if (regs.ARM_pc != regs.ARM_lr) {
-    _LOG(log, scope_flags, "\ncode around lr:\n");
-    dump_memory(log, tid, static_cast<uintptr_t>(regs.ARM_lr), scope_flags);
+    _LOG(log, logtype::MEMORY, "\ncode around lr:\n");
+    dump_memory(log, tid, static_cast<uintptr_t>(regs.ARM_lr));
   }
 }
 
-void dump_registers(log_t* log, pid_t tid, int scope_flags) {
+void dump_registers(log_t* log, pid_t tid) {
   struct pt_regs r;
   if (ptrace(PTRACE_GETREGS, tid, 0, &r)) {
-    _LOG(log, scope_flags, "cannot get registers: %s\n", strerror(errno));
+    _LOG(log, logtype::REGISTERS, "cannot get registers: %s\n", strerror(errno));
     return;
   }
 
-  _LOG(log, scope_flags, "    r0 %08x  r1 %08x  r2 %08x  r3 %08x\n",
+  _LOG(log, logtype::REGISTERS, "    r0 %08x  r1 %08x  r2 %08x  r3 %08x\n",
        static_cast<uint32_t>(r.ARM_r0), static_cast<uint32_t>(r.ARM_r1),
        static_cast<uint32_t>(r.ARM_r2), static_cast<uint32_t>(r.ARM_r3));
-  _LOG(log, scope_flags, "    r4 %08x  r5 %08x  r6 %08x  r7 %08x\n",
+  _LOG(log, logtype::REGISTERS, "    r4 %08x  r5 %08x  r6 %08x  r7 %08x\n",
        static_cast<uint32_t>(r.ARM_r4), static_cast<uint32_t>(r.ARM_r5),
        static_cast<uint32_t>(r.ARM_r6), static_cast<uint32_t>(r.ARM_r7));
-  _LOG(log, scope_flags, "    r8 %08x  r9 %08x  sl %08x  fp %08x\n",
+  _LOG(log, logtype::REGISTERS, "    r8 %08x  r9 %08x  sl %08x  fp %08x\n",
        static_cast<uint32_t>(r.ARM_r8), static_cast<uint32_t>(r.ARM_r9),
        static_cast<uint32_t>(r.ARM_r10), static_cast<uint32_t>(r.ARM_fp));
-  _LOG(log, scope_flags, "    ip %08x  sp %08x  lr %08x  pc %08x  cpsr %08x\n",
+  _LOG(log, logtype::REGISTERS, "    ip %08x  sp %08x  lr %08x  pc %08x  cpsr %08x\n",
        static_cast<uint32_t>(r.ARM_ip), static_cast<uint32_t>(r.ARM_sp),
        static_cast<uint32_t>(r.ARM_lr), static_cast<uint32_t>(r.ARM_pc),
        static_cast<uint32_t>(r.ARM_cpsr));
@@ -100,14 +98,14 @@
   int i;
 
   if (ptrace(PTRACE_GETVFPREGS, tid, 0, &vfp_regs)) {
-    _LOG(log, scope_flags, "cannot get registers: %s\n", strerror(errno));
+    _LOG(log, logtype::REGISTERS, "cannot get registers: %s\n", strerror(errno));
     return;
   }
 
   for (i = 0; i < NUM_VFP_REGS; i += 2) {
-    _LOG(log, scope_flags, "    d%-2d %016llx  d%-2d %016llx\n",
+    _LOG(log, logtype::REGISTERS, "    d%-2d %016llx  d%-2d %016llx\n",
          i, vfp_regs.fpregs[i], i+1, vfp_regs.fpregs[i+1]);
   }
-  _LOG(log, scope_flags, "    scr %08lx\n", vfp_regs.fpscr);
+  _LOG(log, logtype::REGISTERS, "    scr %08lx\n", vfp_regs.fpscr);
 #endif
 }
diff --git a/debuggerd/arm64/machine.cpp b/debuggerd/arm64/machine.cpp
index 2413d5e..f3409d5 100644
--- a/debuggerd/arm64/machine.cpp
+++ b/debuggerd/arm64/machine.cpp
@@ -37,68 +37,66 @@
  * If configured to do so, dump memory around *all* registers
  * for the crashing thread.
  */
-void dump_memory_and_code(log_t* log, pid_t tid, int scope_flags) {
+void dump_memory_and_code(log_t* log, pid_t tid) {
     struct user_pt_regs regs;
     struct iovec io;
     io.iov_base = &regs;
     io.iov_len = sizeof(regs);
 
     if (ptrace(PTRACE_GETREGSET, tid, (void*)NT_PRSTATUS, &io) == -1) {
-        _LOG(log, scope_flags, "%s: ptrace failed to get registers: %s\n",
+        LOG_ERROR("%s: ptrace failed to get registers: %s\n",
              __func__, strerror(errno));
         return;
     }
 
-    if (IS_AT_FAULT(scope_flags) && DUMP_MEMORY_FOR_ALL_REGISTERS) {
-        for (int reg = 0; reg < 31; reg++) {
-            uintptr_t addr = regs.regs[reg];
+    for (int reg = 0; reg < 31; reg++) {
+        uintptr_t addr = regs.regs[reg];
 
-            /*
-             * Don't bother if it looks like a small int or ~= null, or if
-             * it's in the kernel area.
-             */
-            if (addr < 4096 || addr >= (1UL<<63)) {
-                continue;
-            }
-
-            _LOG(log, scope_flags | SCOPE_SENSITIVE, "\nmemory near x%d:\n", reg);
-            dump_memory(log, tid, addr, scope_flags | SCOPE_SENSITIVE);
+        /*
+         * Don't bother if it looks like a small int or ~= null, or if
+         * it's in the kernel area.
+         */
+        if (addr < 4096 || addr >= (1UL<<63)) {
+            continue;
         }
+
+        _LOG(log, logtype::MEMORY, "\nmemory near x%d:\n", reg);
+        dump_memory(log, tid, addr);
     }
 
-    _LOG(log, scope_flags, "\ncode around pc:\n");
-    dump_memory(log, tid, (uintptr_t)regs.pc, scope_flags);
+    _LOG(log, logtype::MEMORY, "\ncode around pc:\n");
+    dump_memory(log, tid, (uintptr_t)regs.pc);
 
     if (regs.pc != regs.sp) {
-        _LOG(log, scope_flags, "\ncode around sp:\n");
-        dump_memory(log, tid, (uintptr_t)regs.sp, scope_flags);
+        _LOG(log, logtype::MEMORY, "\ncode around sp:\n");
+        dump_memory(log, tid, (uintptr_t)regs.sp);
     }
 }
 
-void dump_registers(log_t* log, pid_t tid, int scope_flags)
-{
+void dump_registers(log_t* log, pid_t tid) {
   struct user_pt_regs r;
   struct iovec io;
   io.iov_base = &r;
   io.iov_len = sizeof(r);
 
   if (ptrace(PTRACE_GETREGSET, tid, (void*) NT_PRSTATUS, (void*) &io) == -1) {
-    _LOG(log, scope_flags, "ptrace error: %s\n", strerror(errno));
+    LOG_ERROR("ptrace error: %s\n", strerror(errno));
     return;
   }
 
   for (int i = 0; i < 28; i += 4) {
-    _LOG(log, scope_flags, "    x%-2d  %016lx  x%-2d  %016lx  x%-2d  %016lx  x%-2d  %016lx\n",
+    _LOG(log, logtype::REGISTERS,
+         "    x%-2d  %016lx  x%-2d  %016lx  x%-2d  %016lx  x%-2d  %016lx\n",
          i, (uint64_t)r.regs[i],
          i+1, (uint64_t)r.regs[i+1],
          i+2, (uint64_t)r.regs[i+2],
          i+3, (uint64_t)r.regs[i+3]);
   }
 
-  _LOG(log, scope_flags, "    x28  %016lx  x29  %016lx  x30  %016lx\n",
+  _LOG(log, logtype::REGISTERS, "    x28  %016lx  x29  %016lx  x30  %016lx\n",
        (uint64_t)r.regs[28], (uint64_t)r.regs[29], (uint64_t)r.regs[30]);
 
-  _LOG(log, scope_flags, "    sp   %016lx  pc   %016lx\n",
+  _LOG(log, logtype::REGISTERS, "    sp   %016lx  pc   %016lx\n",
        (uint64_t)r.sp, (uint64_t)r.pc);
 
 
@@ -107,12 +105,12 @@
   io.iov_len = sizeof(f);
 
   if (ptrace(PTRACE_GETREGSET, tid, (void*) NT_PRFPREG, (void*) &io) == -1) {
-    _LOG(log, scope_flags, "ptrace error: %s\n", strerror(errno));
+    LOG_ERROR("ptrace error: %s\n", strerror(errno));
     return;
   }
 
   for (int i = 0; i < 32; i += 4) {
-    _LOG(log, scope_flags, "    v%-2d  %016lx  v%-2d  %016lx  v%-2d  %016lx  v%-2d  %016lx\n",
+    _LOG(log, logtype::REGISTERS, "    v%-2d  %016lx  v%-2d  %016lx  v%-2d  %016lx  v%-2d  %016lx\n",
          i, (uint64_t)f.vregs[i],
          i+1, (uint64_t)f.vregs[i+1],
          i+2, (uint64_t)f.vregs[i+2],
diff --git a/debuggerd/backtrace.cpp b/debuggerd/backtrace.cpp
index d388348..d08242e 100644
--- a/debuggerd/backtrace.cpp
+++ b/debuggerd/backtrace.cpp
@@ -30,6 +30,7 @@
 #include <UniquePtr.h>
 
 #include "backtrace.h"
+
 #include "utility.h"
 
 static void dump_process_header(log_t* log, pid_t pid) {
@@ -49,15 +50,15 @@
   localtime_r(&t, &tm);
   char timestr[64];
   strftime(timestr, sizeof(timestr), "%F %T", &tm);
-  _LOG(log, SCOPE_AT_FAULT, "\n\n----- pid %d at %s -----\n", pid, timestr);
+  _LOG(log, logtype::BACKTRACE, "\n\n----- pid %d at %s -----\n", pid, timestr);
 
   if (procname) {
-    _LOG(log, SCOPE_AT_FAULT, "Cmd line: %s\n", procname);
+    _LOG(log, logtype::BACKTRACE, "Cmd line: %s\n", procname);
   }
 }
 
 static void dump_process_footer(log_t* log, pid_t pid) {
-  _LOG(log, SCOPE_AT_FAULT, "\n----- end %d -----\n", pid);
+  _LOG(log, logtype::BACKTRACE, "\n----- end %d -----\n", pid);
 }
 
 static void dump_thread(
@@ -79,10 +80,10 @@
     }
   }
 
-  _LOG(log, SCOPE_AT_FAULT, "\n\"%s\" sysTid=%d\n", threadname ? threadname : "<unknown>", tid);
+  _LOG(log, logtype::BACKTRACE, "\n\"%s\" sysTid=%d\n", threadname ? threadname : "<unknown>", tid);
 
   if (!attached && ptrace(PTRACE_ATTACH, tid, 0, 0) < 0) {
-    _LOG(log, SCOPE_AT_FAULT, "Could not attach to thread: %s\n", strerror(errno));
+    _LOG(log, logtype::BACKTRACE, "Could not attach to thread: %s\n", strerror(errno));
     return;
   }
 
@@ -90,11 +91,11 @@
 
   UniquePtr<Backtrace> backtrace(Backtrace::Create(tid, BACKTRACE_CURRENT_THREAD));
   if (backtrace->Unwind(0)) {
-    dump_backtrace_to_log(backtrace.get(), log, SCOPE_AT_FAULT, "  ");
+    dump_backtrace_to_log(backtrace.get(), log, "  ");
   }
 
   if (!attached && ptrace(PTRACE_DETACH, tid, 0, 0) != 0) {
-    LOG("ptrace detach from %d failed: %s\n", tid, strerror(errno));
+    LOG_ERROR("ptrace detach from %d failed: %s\n", tid, strerror(errno));
     *detach_failed = true;
   }
 }
@@ -133,9 +134,8 @@
   dump_process_footer(&log, pid);
 }
 
-void dump_backtrace_to_log(Backtrace* backtrace, log_t* log,
-                           int scope_flags, const char* prefix) {
+void dump_backtrace_to_log(Backtrace* backtrace, log_t* log, const char* prefix) {
   for (size_t i = 0; i < backtrace->NumFrames(); i++) {
-    _LOG(log, scope_flags, "%s%s\n", prefix, backtrace->FormatFrameData(i).c_str());
+    _LOG(log, logtype::BACKTRACE, "%s%s\n", prefix, backtrace->FormatFrameData(i).c_str());
   }
 }
diff --git a/debuggerd/backtrace.h b/debuggerd/backtrace.h
index 2ec8afb..da14cd4 100644
--- a/debuggerd/backtrace.h
+++ b/debuggerd/backtrace.h
@@ -29,7 +29,6 @@
                     int* total_sleep_time_usec);
 
 /* Dumps the backtrace in the backtrace data structure to the log. */
-void dump_backtrace_to_log(Backtrace* backtrace, log_t* log,
-                           int scope_flags, const char* prefix);
+void dump_backtrace_to_log(Backtrace* backtrace, log_t* log, const char* prefix);
 
 #endif // _DEBUGGERD_BACKTRACE_H
diff --git a/debuggerd/debuggerd.cpp b/debuggerd/debuggerd.cpp
index 3726c38..dde8f90 100644
--- a/debuggerd/debuggerd.cpp
+++ b/debuggerd/debuggerd.cpp
@@ -30,7 +30,6 @@
 #include <sys/stat.h>
 #include <sys/poll.h>
 
-#include <log/logd.h>
 #include <log/logger.h>
 
 #include <cutils/sockets.h>
@@ -62,7 +61,7 @@
   char exe[PATH_MAX];
   int count;
   if ((count = readlink(path, exe, sizeof(exe) - 1)) == -1) {
-    LOG("readlink('%s') failed: %s", path, strerror(errno));
+    LOG_ERROR("readlink('%s') failed: %s", path, strerror(errno));
     strlcpy(exe, "unknown", sizeof(exe));
   } else {
     exe[count] = '\0';
@@ -79,7 +78,7 @@
   }
 
   // Explain how to attach the debugger.
-  LOG(    "********************************************************\n"
+  LOG_ERROR(    "********************************************************\n"
           "* Process %d has been suspended while crashing.\n"
           "* To attach gdbserver for a gdb connection on port 5039\n"
           "* and start gdbclient:\n"
@@ -104,7 +103,7 @@
     uninit_getevent();
   }
 
-  LOG("debuggerd resuming process %d", pid);
+  LOG_ERROR("debuggerd resuming process %d", pid);
 }
 
 static int get_process_info(pid_t tid, pid_t* out_pid, uid_t* out_uid, uid_t* out_gid) {
@@ -140,7 +139,7 @@
   socklen_t len = sizeof(cr);
   int status = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cr, &len);
   if (status != 0) {
-    LOG("cannot get credentials\n");
+    LOG_ERROR("cannot get credentials\n");
     return -1;
   }
 
@@ -153,7 +152,7 @@
   pollfds[0].revents = 0;
   status = TEMP_FAILURE_RETRY(poll(pollfds, 1, 3000));
   if (status != 1) {
-    LOG("timed out reading tid (from pid=%d uid=%d)\n", cr.pid, cr.uid);
+    LOG_ERROR("timed out reading tid (from pid=%d uid=%d)\n", cr.pid, cr.uid);
     return -1;
   }
 
@@ -161,14 +160,14 @@
   memset(&msg, 0, sizeof(msg));
   status = TEMP_FAILURE_RETRY(read(fd, &msg, sizeof(msg)));
   if (status < 0) {
-    LOG("read failure? %s (pid=%d uid=%d)\n", strerror(errno), cr.pid, cr.uid);
+    LOG_ERROR("read failure? %s (pid=%d uid=%d)\n", strerror(errno), cr.pid, cr.uid);
     return -1;
   }
   if (status == sizeof(debugger_msg_t)) {
     XLOG("crash request of size %d abort_msg_address=0x%" PRIPTR "\n",
          status, msg.abort_msg_address);
   } else {
-    LOG("invalid crash request of size %d (from pid=%d uid=%d)\n", status, cr.pid, cr.uid);
+    LOG_ERROR("invalid crash request of size %d (from pid=%d uid=%d)\n", status, cr.pid, cr.uid);
     return -1;
   }
 
@@ -186,7 +185,7 @@
     struct stat s;
     snprintf(buf, sizeof buf, "/proc/%d/task/%d", out_request->pid, out_request->tid);
     if (stat(buf, &s)) {
-      LOG("tid %d does not exist in pid %d. ignoring debug request\n",
+      LOG_ERROR("tid %d does not exist in pid %d. ignoring debug request\n",
           out_request->tid, out_request->pid);
       return -1;
     }
@@ -197,7 +196,7 @@
     status = get_process_info(out_request->tid, &out_request->pid,
                               &out_request->uid, &out_request->gid);
     if (status < 0) {
-      LOG("tid %d does not exist. ignoring explicit dump request\n", out_request->tid);
+      LOG_ERROR("tid %d does not exist. ignoring explicit dump request\n", out_request->tid);
       return -1;
     }
   } else {
@@ -238,12 +237,12 @@
     // See details in bionic/libc/linker/debugger.c, in function
     // debugger_signal_handler().
     if (ptrace(PTRACE_ATTACH, request.tid, 0, 0)) {
-      LOG("ptrace attach failed: %s\n", strerror(errno));
+      LOG_ERROR("ptrace attach failed: %s\n", strerror(errno));
     } else {
       bool detach_failed = false;
       bool attach_gdb = should_attach_gdb(&request);
       if (TEMP_FAILURE_RETRY(write(fd, "\0", 1)) != 1) {
-        LOG("failed responding to client: %s\n", strerror(errno));
+        LOG_ERROR("failed responding to client: %s\n", strerror(errno));
       } else {
         char* tombstone_path = NULL;
 
@@ -275,7 +274,7 @@
                 XLOG("stopped -- continuing\n");
                 status = ptrace(PTRACE_CONT, request.tid, 0, 0);
                 if (status) {
-                  LOG("ptrace continue failed: %s\n", strerror(errno));
+                  LOG_ERROR("ptrace continue failed: %s\n", strerror(errno));
                 }
                 continue; // loop again
               }
@@ -307,7 +306,7 @@
 
             default:
               XLOG("stopped -- unexpected signal\n");
-              LOG("process stopped due to unexpected signal %d\n", signal);
+              LOG_ERROR("process stopped due to unexpected signal %d\n", signal);
               break;
           }
           break;
@@ -330,7 +329,7 @@
 
         // detach so we can attach gdbserver
         if (ptrace(PTRACE_DETACH, request.tid, 0, 0)) {
-          LOG("ptrace detach from %d failed: %s\n", request.tid, strerror(errno));
+          LOG_ERROR("ptrace detach from %d failed: %s\n", request.tid, strerror(errno));
           detach_failed = true;
         }
 
@@ -342,7 +341,7 @@
       } else {
         // just detach
         if (ptrace(PTRACE_DETACH, request.tid, 0, 0)) {
-          LOG("ptrace detach from %d failed: %s\n", request.tid, strerror(errno));
+          LOG_ERROR("ptrace detach from %d failed: %s\n", request.tid, strerror(errno));
           detach_failed = true;
         }
       }
@@ -354,7 +353,7 @@
       // actual parent won't receive a death notification via wait(2).  At this point
       // there's not much we can do about that.
       if (detach_failed) {
-        LOG("debuggerd committing suicide to free the zombie!\n");
+        LOG_ERROR("debuggerd committing suicide to free the zombie!\n");
         kill(getpid(), SIGKILL);
       }
     }
@@ -400,7 +399,7 @@
     return 1;
   fcntl(s, F_SETFD, FD_CLOEXEC);
 
-  LOG("debuggerd: " __DATE__ " " __TIME__ "\n");
+  LOG_ERROR("debuggerd: " __DATE__ " " __TIME__ "\n");
 
   for (;;) {
     sockaddr addr;
diff --git a/debuggerd/machine.h b/debuggerd/machine.h
index 2f1e201..fca9fbe 100644
--- a/debuggerd/machine.h
+++ b/debuggerd/machine.h
@@ -21,7 +21,7 @@
 
 #include "utility.h"
 
-void dump_memory_and_code(log_t* log, pid_t tid, int scope_flags);
-void dump_registers(log_t* log, pid_t tid, int scope_flags);
+void dump_memory_and_code(log_t* log, pid_t tid);
+void dump_registers(log_t* log, pid_t tid);
 
 #endif // _DEBUGGERD_MACHINE_H
diff --git a/debuggerd/mips/machine.cpp b/debuggerd/mips/machine.cpp
index 5c82d4d..605275b 100644
--- a/debuggerd/mips/machine.cpp
+++ b/debuggerd/mips/machine.cpp
@@ -27,9 +27,6 @@
 #include "../utility.h"
 #include "../machine.h"
 
-// enable to dump memory pointed to by every register
-#define DUMP_MEMORY_FOR_ALL_REGISTERS 1
-
 #define R(x) (static_cast<unsigned int>(x))
 
 // The MIPS uapi ptrace.h has the wrong definition for pt_regs. PTRACE_GETREGS
@@ -46,72 +43,70 @@
 
 // If configured to do so, dump memory around *all* registers
 // for the crashing thread.
-void dump_memory_and_code(log_t* log, pid_t tid, int scope_flags) {
+void dump_memory_and_code(log_t* log, pid_t tid) {
   pt_regs_mips_t r;
   if (ptrace(PTRACE_GETREGS, tid, 0, &r)) {
     return;
   }
 
-  if (IS_AT_FAULT(scope_flags) && DUMP_MEMORY_FOR_ALL_REGISTERS) {
-    static const char REG_NAMES[] = "$0atv0v1a0a1a2a3t0t1t2t3t4t5t6t7s0s1s2s3s4s5s6s7t8t9k0k1gpsps8ra";
+  static const char REG_NAMES[] = "$0atv0v1a0a1a2a3t0t1t2t3t4t5t6t7s0s1s2s3s4s5s6s7t8t9k0k1gpsps8ra";
 
-    for (int reg = 0; reg < 32; reg++) {
-      // skip uninteresting registers
-      if (reg == 0 // $0
-          || reg == 26 // $k0
-          || reg == 27 // $k1
-          || reg == 31 // $ra (done below)
-         )
-        continue;
+  for (int reg = 0; reg < 32; reg++) {
+    // skip uninteresting registers
+    if (reg == 0 // $0
+        || reg == 26 // $k0
+        || reg == 27 // $k1
+        || reg == 31 // $ra (done below)
+       )
+      continue;
 
-      uintptr_t addr = R(r.regs[reg]);
+    uintptr_t addr = R(r.regs[reg]);
 
-      // Don't bother if it looks like a small int or ~= null, or if
-      // it's in the kernel area.
-      if (addr < 4096 || addr >= 0x80000000) {
-        continue;
-      }
-
-      _LOG(log, scope_flags | SCOPE_SENSITIVE, "\nmemory near %.2s:\n", &REG_NAMES[reg * 2]);
-      dump_memory(log, tid, addr, scope_flags | SCOPE_SENSITIVE);
+    // Don't bother if it looks like a small int or ~= null, or if
+    // it's in the kernel area.
+    if (addr < 4096 || addr >= 0x80000000) {
+      continue;
     }
+
+    _LOG(log, logtype::MEMORY, "\nmemory near %.2s:\n", &REG_NAMES[reg * 2]);
+    dump_memory(log, tid, addr);
   }
 
   unsigned int pc = R(r.cp0_epc);
   unsigned int ra = R(r.regs[31]);
 
-  _LOG(log, scope_flags, "\ncode around pc:\n");
-  dump_memory(log, tid, (uintptr_t)pc, scope_flags);
+  _LOG(log, logtype::MEMORY, "\ncode around pc:\n");
+  dump_memory(log, tid, (uintptr_t)pc);
 
   if (pc != ra) {
-    _LOG(log, scope_flags, "\ncode around ra:\n");
-    dump_memory(log, tid, (uintptr_t)ra, scope_flags);
+    _LOG(log, logtype::MEMORY, "\ncode around ra:\n");
+    dump_memory(log, tid, (uintptr_t)ra);
   }
 }
 
-void dump_registers(log_t* log, pid_t tid, int scope_flags) {
+void dump_registers(log_t* log, pid_t tid) {
   pt_regs_mips_t r;
   if(ptrace(PTRACE_GETREGS, tid, 0, &r)) {
-    _LOG(log, scope_flags, "cannot get registers: %s\n", strerror(errno));
+    LOG_ERROR("cannot get registers: %s\n", strerror(errno));
     return;
   }
 
-  _LOG(log, scope_flags, " zr %08x  at %08x  v0 %08x  v1 %08x\n",
+  _LOG(log, logtype::REGISTERS, " zr %08x  at %08x  v0 %08x  v1 %08x\n",
        R(r.regs[0]), R(r.regs[1]), R(r.regs[2]), R(r.regs[3]));
-  _LOG(log, scope_flags, " a0 %08x  a1 %08x  a2 %08x  a3 %08x\n",
+  _LOG(log, logtype::REGISTERS, " a0 %08x  a1 %08x  a2 %08x  a3 %08x\n",
        R(r.regs[4]), R(r.regs[5]), R(r.regs[6]), R(r.regs[7]));
-  _LOG(log, scope_flags, " t0 %08x  t1 %08x  t2 %08x  t3 %08x\n",
+  _LOG(log, logtype::REGISTERS, " t0 %08x  t1 %08x  t2 %08x  t3 %08x\n",
        R(r.regs[8]), R(r.regs[9]), R(r.regs[10]), R(r.regs[11]));
-  _LOG(log, scope_flags, " t4 %08x  t5 %08x  t6 %08x  t7 %08x\n",
+  _LOG(log, logtype::REGISTERS, " t4 %08x  t5 %08x  t6 %08x  t7 %08x\n",
        R(r.regs[12]), R(r.regs[13]), R(r.regs[14]), R(r.regs[15]));
-  _LOG(log, scope_flags, " s0 %08x  s1 %08x  s2 %08x  s3 %08x\n",
+  _LOG(log, logtype::REGISTERS, " s0 %08x  s1 %08x  s2 %08x  s3 %08x\n",
        R(r.regs[16]), R(r.regs[17]), R(r.regs[18]), R(r.regs[19]));
-  _LOG(log, scope_flags, " s4 %08x  s5 %08x  s6 %08x  s7 %08x\n",
+  _LOG(log, logtype::REGISTERS, " s4 %08x  s5 %08x  s6 %08x  s7 %08x\n",
        R(r.regs[20]), R(r.regs[21]), R(r.regs[22]), R(r.regs[23]));
-  _LOG(log, scope_flags, " t8 %08x  t9 %08x  k0 %08x  k1 %08x\n",
+  _LOG(log, logtype::REGISTERS, " t8 %08x  t9 %08x  k0 %08x  k1 %08x\n",
        R(r.regs[24]), R(r.regs[25]), R(r.regs[26]), R(r.regs[27]));
-  _LOG(log, scope_flags, " gp %08x  sp %08x  s8 %08x  ra %08x\n",
+  _LOG(log, logtype::REGISTERS, " gp %08x  sp %08x  s8 %08x  ra %08x\n",
        R(r.regs[28]), R(r.regs[29]), R(r.regs[30]), R(r.regs[31]));
-  _LOG(log, scope_flags, " hi %08x  lo %08x bva %08x epc %08x\n",
+  _LOG(log, logtype::REGISTERS, " hi %08x  lo %08x bva %08x epc %08x\n",
        R(r.hi), R(r.lo), R(r.cp0_badvaddr), R(r.cp0_epc));
 }
diff --git a/debuggerd/tombstone.cpp b/debuggerd/tombstone.cpp
index fb5f02a..a06effc 100755
--- a/debuggerd/tombstone.cpp
+++ b/debuggerd/tombstone.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "DEBUG"
+
 #include <dirent.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -179,16 +181,16 @@
   property_get("ro.build.fingerprint", fingerprint, "unknown");
   property_get("ro.revision", revision, "unknown");
 
-  _LOG(log, SCOPE_AT_FAULT, "Build fingerprint: '%s'\n", fingerprint);
-  _LOG(log, SCOPE_AT_FAULT, "Revision: '%s'\n", revision);
-  _LOG(log, SCOPE_AT_FAULT, "ABI: '%s'\n", ABI_STRING);
+  _LOG(log, logtype::HEADER, "Build fingerprint: '%s'\n", fingerprint);
+  _LOG(log, logtype::HEADER, "Revision: '%s'\n", revision);
+  _LOG(log, logtype::HEADER, "ABI: '%s'\n", ABI_STRING);
 }
 
 static void dump_signal_info(log_t* log, pid_t tid, int signal, int si_code) {
   siginfo_t si;
   memset(&si, 0, sizeof(si));
   if (ptrace(PTRACE_GETSIGINFO, tid, 0, &si) == -1) {
-    _LOG(log, SCOPE_AT_FAULT, "cannot get siginfo: %s\n", strerror(errno));
+    _LOG(log, logtype::HEADER, "cannot get siginfo: %s\n", strerror(errno));
     return;
   }
 
@@ -202,11 +204,11 @@
     snprintf(addr_desc, sizeof(addr_desc), "--------");
   }
 
-  _LOG(log, SCOPE_AT_FAULT, "signal %d (%s), code %d (%s), fault addr %s\n",
+  _LOG(log, logtype::HEADER, "signal %d (%s), code %d (%s), fault addr %s\n",
        signal, get_signame(signal), si.si_code, get_sigcode(signal, si.si_code), addr_desc);
 }
 
-static void dump_thread_info(log_t* log, pid_t pid, pid_t tid, int scope_flags) {
+static void dump_thread_info(log_t* log, pid_t pid, pid_t tid) {
   char path[64];
   char threadnamebuf[1024];
   char* threadname = NULL;
@@ -224,25 +226,21 @@
     }
   }
 
-  if (IS_AT_FAULT(scope_flags)) {
-    char procnamebuf[1024];
-    char* procname = NULL;
+  char procnamebuf[1024];
+  char* procname = NULL;
 
-    snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
-    if ((fp = fopen(path, "r"))) {
-      procname = fgets(procnamebuf, sizeof(procnamebuf), fp);
-      fclose(fp);
-    }
-
-    _LOG(log, SCOPE_AT_FAULT, "pid: %d, tid: %d, name: %s  >>> %s <<<\n", pid, tid,
-         threadname ? threadname : "UNKNOWN", procname ? procname : "UNKNOWN");
-  } else {
-    _LOG(log, 0, "pid: %d, tid: %d, name: %s\n", pid, tid, threadname ? threadname : "UNKNOWN");
+  snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
+  if ((fp = fopen(path, "r"))) {
+    procname = fgets(procnamebuf, sizeof(procnamebuf), fp);
+    fclose(fp);
   }
+
+  _LOG(log, logtype::THREAD, "pid: %d, tid: %d, name: %s  >>> %s <<<\n", pid, tid,
+       threadname ? threadname : "UNKNOWN", procname ? procname : "UNKNOWN");
 }
 
 static void dump_stack_segment(
-    Backtrace* backtrace, log_t* log, int scope_flags, uintptr_t* sp, size_t words, int label) {
+    Backtrace* backtrace, log_t* log, uintptr_t* sp, size_t words, int label) {
   for (size_t i = 0; i < words; i++) {
     word_t stack_content;
     if (!backtrace->ReadWord(*sp, &stack_content)) {
@@ -261,27 +259,27 @@
     if (!func_name.empty()) {
       if (!i && label >= 0) {
         if (offset) {
-          _LOG(log, scope_flags, "    #%02d  %" PRIPTR "  %" PRIPTR "  %s (%s+%" PRIuPTR ")\n",
+          _LOG(log, logtype::STACK, "    #%02d  %" PRIPTR "  %" PRIPTR "  %s (%s+%" PRIuPTR ")\n",
                label, *sp, stack_content, map_name, func_name.c_str(), offset);
         } else {
-          _LOG(log, scope_flags, "    #%02d  %" PRIPTR "  %" PRIPTR "  %s (%s)\n",
+          _LOG(log, logtype::STACK, "    #%02d  %" PRIPTR "  %" PRIPTR "  %s (%s)\n",
                label, *sp, stack_content, map_name, func_name.c_str());
         }
       } else {
         if (offset) {
-          _LOG(log, scope_flags, "         %" PRIPTR "  %" PRIPTR "  %s (%s+%" PRIuPTR ")\n",
+          _LOG(log, logtype::STACK, "         %" PRIPTR "  %" PRIPTR "  %s (%s+%" PRIuPTR ")\n",
                *sp, stack_content, map_name, func_name.c_str(), offset);
         } else {
-          _LOG(log, scope_flags, "         %" PRIPTR "  %" PRIPTR "  %s (%s)\n",
+          _LOG(log, logtype::STACK, "         %" PRIPTR "  %" PRIPTR "  %s (%s)\n",
                *sp, stack_content, map_name, func_name.c_str());
         }
       }
     } else {
       if (!i && label >= 0) {
-        _LOG(log, scope_flags, "    #%02d  %" PRIPTR "  %" PRIPTR "  %s\n",
+        _LOG(log, logtype::STACK, "    #%02d  %" PRIPTR "  %" PRIPTR "  %s\n",
              label, *sp, stack_content, map_name);
       } else {
-        _LOG(log, scope_flags, "         %" PRIPTR "  %" PRIPTR "  %s\n",
+        _LOG(log, logtype::STACK, "         %" PRIPTR "  %" PRIPTR "  %s\n",
              *sp, stack_content, map_name);
       }
     }
@@ -290,7 +288,7 @@
   }
 }
 
-static void dump_stack(Backtrace* backtrace, log_t* log, int scope_flags) {
+static void dump_stack(Backtrace* backtrace, log_t* log) {
   size_t first = 0, last;
   for (size_t i = 0; i < backtrace->NumFrames(); i++) {
     const backtrace_frame_data_t* frame = backtrace->GetFrame(i);
@@ -306,27 +304,22 @@
   }
   first--;
 
-  scope_flags |= SCOPE_SENSITIVE;
-
   // Dump a few words before the first frame.
   word_t sp = backtrace->GetFrame(first)->sp - STACK_WORDS * sizeof(word_t);
-  dump_stack_segment(backtrace, log, scope_flags, &sp, STACK_WORDS, -1);
+  dump_stack_segment(backtrace, log, &sp, STACK_WORDS, -1);
 
   // Dump a few words from all successive frames.
   // Only log the first 3 frames, put the rest in the tombstone.
   for (size_t i = first; i <= last; i++) {
     const backtrace_frame_data_t* frame = backtrace->GetFrame(i);
     if (sp != frame->sp) {
-      _LOG(log, scope_flags, "         ........  ........\n");
+      _LOG(log, logtype::STACK, "         ........  ........\n");
       sp = frame->sp;
     }
-    if (i - first == 3) {
-      scope_flags &= (~SCOPE_AT_FAULT);
-    }
     if (i == last) {
-      dump_stack_segment(backtrace, log, scope_flags, &sp, STACK_WORDS, i);
+      dump_stack_segment(backtrace, log, &sp, STACK_WORDS, i);
       if (sp < frame->sp + frame->stack_size) {
-        _LOG(log, scope_flags, "         ........  ........\n");
+        _LOG(log, logtype::STACK, "         ........  ........\n");
       }
     } else {
       size_t words = frame->stack_size / sizeof(word_t);
@@ -335,37 +328,36 @@
       } else if (words > STACK_WORDS) {
         words = STACK_WORDS;
       }
-      dump_stack_segment(backtrace, log, scope_flags, &sp, words, i);
+      dump_stack_segment(backtrace, log, &sp, words, i);
     }
   }
 }
 
-static void dump_backtrace_and_stack(Backtrace* backtrace, log_t* log, int scope_flags) {
+static void dump_backtrace_and_stack(Backtrace* backtrace, log_t* log) {
   if (backtrace->NumFrames()) {
-    _LOG(log, scope_flags, "\nbacktrace:\n");
-    dump_backtrace_to_log(backtrace, log, scope_flags, "    ");
+    _LOG(log, logtype::BACKTRACE, "\nbacktrace:\n");
+    dump_backtrace_to_log(backtrace, log, "    ");
 
-    _LOG(log, scope_flags, "\nstack:\n");
-    dump_stack(backtrace, log, scope_flags);
+    _LOG(log, logtype::STACK, "\nstack:\n");
+    dump_stack(backtrace, log);
   }
 }
 
-static void dump_map(log_t* log, const backtrace_map_t* map, const char* what, int scope_flags) {
+static void dump_map(log_t* log, const backtrace_map_t* map, const char* what) {
   if (map != NULL) {
-    _LOG(log, scope_flags, "    %" PRIPTR "-%" PRIPTR " %c%c%c %s\n", map->start, map->end,
+    _LOG(log, logtype::MAPS, "    %" PRIPTR "-%" PRIPTR " %c%c%c %s\n", map->start, map->end,
          (map->flags & PROT_READ) ? 'r' : '-', (map->flags & PROT_WRITE) ? 'w' : '-',
          (map->flags & PROT_EXEC) ? 'x' : '-', map->name.c_str());
   } else {
-    _LOG(log, scope_flags, "    (no %s)\n", what);
+    _LOG(log, logtype::MAPS, "    (no %s)\n", what);
   }
 }
 
-static void dump_nearby_maps(BacktraceMap* map, log_t* log, pid_t tid, int scope_flags) {
-  scope_flags |= SCOPE_SENSITIVE;
+static void dump_nearby_maps(BacktraceMap* map, log_t* log, pid_t tid) {
   siginfo_t si;
   memset(&si, 0, sizeof(si));
   if (ptrace(PTRACE_GETSIGINFO, tid, 0, &si)) {
-    _LOG(log, scope_flags, "cannot get siginfo for %d: %s\n", tid, strerror(errno));
+    _LOG(log, logtype::MAPS, "cannot get siginfo for %d: %s\n", tid, strerror(errno));
     return;
   }
   if (!signal_has_si_addr(si.si_signo)) {
@@ -378,7 +370,7 @@
     return;
   }
 
-  _LOG(log, scope_flags, "\nmemory map around fault addr %" PRIPTR ":\n",
+  _LOG(log, logtype::MAPS, "\nmemory map around fault addr %" PRIPTR ":\n",
        reinterpret_cast<uintptr_t>(si.si_addr));
 
   // Search for a match, or for a hole where the match would be.  The list
@@ -400,27 +392,28 @@
   }
 
   // Show the map address in ascending order (like /proc/pid/maps).
-  dump_map(log, prev_map, "map below", scope_flags);
-  dump_map(log, cur_map, "map for address", scope_flags);
-  dump_map(log, next_map, "map above", scope_flags);
+  dump_map(log, prev_map, "map below");
+  dump_map(log, cur_map, "map for address");
+  dump_map(log, next_map, "map above");
 }
 
 static void dump_thread(
-    Backtrace* backtrace, log_t* log, int scope_flags, int* total_sleep_time_usec) {
+    Backtrace* backtrace, log_t* log, int* total_sleep_time_usec) {
+
   wait_for_stop(backtrace->Tid(), total_sleep_time_usec);
 
-  dump_registers(log, backtrace->Tid(), scope_flags);
-  dump_backtrace_and_stack(backtrace, log, scope_flags);
-  if (IS_AT_FAULT(scope_flags)) {
-    dump_memory_and_code(log, backtrace->Tid(), scope_flags);
-    dump_nearby_maps(backtrace->GetMap(), log, backtrace->Tid(), scope_flags);
-  }
+  dump_registers(log, backtrace->Tid());
+  dump_backtrace_and_stack(backtrace, log);
+
+  dump_memory_and_code(log, backtrace->Tid());
+  dump_nearby_maps(backtrace->GetMap(), log, backtrace->Tid());
 }
 
 // Return true if some thread is not detached cleanly
 static bool dump_sibling_thread_report(
     log_t* log, pid_t pid, pid_t tid, int* total_sleep_time_usec, BacktraceMap* map) {
   char task_path[64];
+
   snprintf(task_path, sizeof(task_path), "/proc/%d/task", pid);
 
   DIR* d = opendir(task_path);
@@ -447,19 +440,24 @@
 
     // Skip this thread if cannot ptrace it
     if (ptrace(PTRACE_ATTACH, new_tid, 0, 0) < 0) {
+      LOG_ERROR("ptrace attach to %d failed: %s\n", new_tid, strerror(errno));
       continue;
     }
 
-    _LOG(log, 0, "--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---\n");
-    dump_thread_info(log, pid, new_tid, 0);
+    _LOG(log, logtype::THREAD, "--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---\n");
+    dump_thread_info(log, pid, new_tid);
+
+    log->current_tid = new_tid;
 
     UniquePtr<Backtrace> backtrace(Backtrace::Create(pid, new_tid, map));
     if (backtrace->Unwind(0)) {
-      dump_thread(backtrace.get(), log, 0, total_sleep_time_usec);
+      dump_thread(backtrace.get(), log, total_sleep_time_usec);
     }
 
+    log->current_tid = log->crashed_tid;
+
     if (ptrace(PTRACE_DETACH, new_tid, 0, 0) != 0) {
-      LOG("ptrace detach from %d failed: %s\n", new_tid, strerror(errno));
+      LOG_ERROR("ptrace detach from %d failed: %s\n", new_tid, strerror(errno));
       detach_failed = true;
     }
   }
@@ -500,12 +498,12 @@
         // non-blocking EOF; we're done
         break;
       } else {
-        _LOG(log, 0, "Error while reading log: %s\n",
+        LOG_ERROR("Error while reading log: %s\n",
           strerror(-actual));
         break;
       }
     } else if (actual == 0) {
-      _LOG(log, 0, "Got zero bytes while reading log: %s\n",
+      LOG_ERROR("Got zero bytes while reading log: %s\n",
         strerror(errno));
       break;
     }
@@ -522,7 +520,7 @@
     }
 
     if (first) {
-      _LOG(log, 0, "--------- %slog %s\n",
+      _LOG(log, logtype::HEADER, "--------- %slog %s\n",
         tail ? "tail end of " : "", filename);
       first = false;
     }
@@ -552,7 +550,7 @@
       AndroidLogEntry e;
       char buf[512];
       android_log_processBinaryLogBuffer(entry, &e, g_eventTagMap, buf, sizeof(buf));
-      _LOG(log, 0, "%s.%03d %5d %5d %c %-8s: %s\n",
+      _LOG(log, logtype::LOGS, "%s.%03d %5d %5d %c %-8s: %s\n",
          timeBuf, entry->nsec / 1000000, entry->pid, entry->tid,
          'I', e.tag, e.message);
       continue;
@@ -579,7 +577,7 @@
         ++nl;
       }
 
-      _LOG(log, 0, "%s.%03d %5d %5d %c %-8s: %s\n",
+      _LOG(log, logtype::LOGS, "%s.%03d %5d %5d %c %-8s: %s\n",
          timeBuf, entry->nsec / 1000000, entry->pid, entry->tid,
          prioChar, tag, msg);
 
@@ -619,7 +617,7 @@
   }
   msg[sizeof(msg) - 1] = '\0';
 
-  _LOG(log, SCOPE_AT_FAULT, "Abort message: '%s'\n", msg);
+  _LOG(log, logtype::HEADER, "Abort message: '%s'\n", msg);
 }
 
 // Dumps all information about the specified pid to the tombstone.
@@ -641,10 +639,11 @@
     TEMP_FAILURE_RETRY( write(log->amfd, &datum, 4) );
   }
 
-  _LOG(log, SCOPE_AT_FAULT,
+  _LOG(log, logtype::HEADER,
        "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n");
   dump_header_info(log);
-  dump_thread_info(log, pid, tid, SCOPE_AT_FAULT);
+  dump_thread_info(log, pid, tid);
+
   if (signal) {
     dump_signal_info(log, tid, signal, si_code);
   }
@@ -653,7 +652,7 @@
   UniquePtr<Backtrace> backtrace(Backtrace::Create(pid, tid, map.get()));
   if (backtrace->Unwind(0)) {
     dump_abort_message(backtrace.get(), log, abort_msg_address);
-    dump_thread(backtrace.get(), log, SCOPE_AT_FAULT, total_sleep_time_usec);
+    dump_thread(backtrace.get(), log, total_sleep_time_usec);
   }
 
   if (want_logs) {
@@ -715,7 +714,7 @@
   }
 
   if (oldest < 0) {
-    LOG("Failed to find a valid tombstone, default to using tombstone 0.\n");
+    LOG_ERROR("Failed to find a valid tombstone, default to using tombstone 0.\n");
     oldest = 0;
   }
 
@@ -723,7 +722,7 @@
   snprintf(path, sizeof(path), TOMBSTONE_TEMPLATE, oldest);
   *fd = open(path, O_CREAT | O_TRUNC | O_WRONLY, 0600);
   if (*fd < 0) {
-    LOG("failed to open tombstone file '%s': %s\n", path, strerror(errno));
+    LOG_ERROR("failed to open tombstone file '%s': %s\n", path, strerror(errno));
     return NULL;
   }
   fchown(*fd, AID_SYSTEM, AID_SYSTEM);
@@ -763,12 +762,17 @@
 char* engrave_tombstone(pid_t pid, pid_t tid, int signal, int original_si_code,
                         uintptr_t abort_msg_address, bool dump_sibling_threads, bool quiet,
                         bool* detach_failed, int* total_sleep_time_usec) {
+
+  log_t log;
+  log.current_tid = tid;
+  log.crashed_tid = tid;
+
   if ((mkdir(TOMBSTONE_DIR, 0755) == -1) && (errno != EEXIST)) {
-    LOG("failed to create %s: %s\n", TOMBSTONE_DIR, strerror(errno));
+    LOG_ERROR("failed to create %s: %s\n", TOMBSTONE_DIR, strerror(errno));
   }
 
   if (chown(TOMBSTONE_DIR, AID_SYSTEM, AID_SYSTEM) == -1) {
-    LOG("failed to change ownership of %s: %s\n", TOMBSTONE_DIR, strerror(errno));
+    LOG_ERROR("failed to change ownership of %s: %s\n", TOMBSTONE_DIR, strerror(errno));
   }
 
   int fd = -1;
@@ -776,16 +780,15 @@
   if (selinux_android_restorecon(TOMBSTONE_DIR, 0) == 0) {
     path = find_and_open_tombstone(&fd);
   } else {
-    LOG("Failed to restore security context, not writing tombstone.\n");
+    LOG_ERROR("Failed to restore security context, not writing tombstone.\n");
   }
 
   if (fd < 0 && quiet) {
-    LOG("Skipping tombstone write, nothing to do.\n");
+    LOG_ERROR("Skipping tombstone write, nothing to do.\n");
     *detach_failed = false;
     return NULL;
   }
 
-  log_t log;
   log.tfd = fd;
   // Preserve amfd since it can be modified through the calls below without
   // being closed.
@@ -795,6 +798,8 @@
   *detach_failed = dump_crash(&log, pid, tid, signal, original_si_code, abort_msg_address,
                               dump_sibling_threads, total_sleep_time_usec);
 
+  ALOGI("\nTombstone written to: %s\n", path);
+
   // Either of these file descriptors can be -1, any error is ignored.
   close(amfd);
   close(fd);
diff --git a/debuggerd/utility.cpp b/debuggerd/utility.cpp
index d4c252f..a3acddf 100644
--- a/debuggerd/utility.cpp
+++ b/debuggerd/utility.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "DEBUG"
+
 #include "utility.h"
 
 #include <errno.h>
@@ -25,7 +27,6 @@
 
 #include <backtrace/Backtrace.h>
 #include <log/log.h>
-#include <log/logd.h>
 
 const int sleep_time_usec = 50000;         // 0.05 seconds
 const int max_total_sleep_usec = 10000000; // 10 seconds
@@ -36,7 +37,7 @@
     int written = TEMP_FAILURE_RETRY(write(fd, buf + len - to_write, to_write));
     if (written < 0) {
       // hard failure
-      LOG("AM write failure (%d / %s)\n", errno, strerror(errno));
+      LOG_ERROR("AM write failure (%d / %s)\n", errno, strerror(errno));
       return -1;
     }
     to_write -= written;
@@ -44,10 +45,22 @@
   return len;
 }
 
-void _LOG(log_t* log, int scopeFlags, const char* fmt, ...) {
-  bool want_tfd_write = log && log->tfd >= 0;
-  bool want_log_write = IS_AT_FAULT(scopeFlags) && (!log || !log->quiet);
-  bool want_amfd_write = IS_AT_FAULT(scopeFlags) && !IS_SENSITIVE(scopeFlags) && log && log->amfd >= 0;
+// Whitelist output desired in the logcat output.
+bool is_allowed_in_logcat(enum logtype ltype) {
+  if ((ltype == ERROR)
+   || (ltype == HEADER)
+   || (ltype == REGISTERS)
+   || (ltype == BACKTRACE)) {
+    return true;
+  }
+  return false;
+}
+
+void _LOG(log_t* log, enum logtype ltype, const char* fmt, ...) {
+  bool write_to_tombstone = log && log->tfd;
+  bool write_to_logcat = (!log || !log->quiet) && is_allowed_in_logcat(ltype)
+                        && (log && log->crashed_tid == log->current_tid);
+  bool write_to_activitymanager = log && log->amfd >= 0 && is_allowed_in_logcat(ltype);
 
   char buf[512];
   va_list ap;
@@ -60,13 +73,13 @@
     return;
   }
 
-  if (want_tfd_write) {
+  if (write_to_tombstone) {
     TEMP_FAILURE_RETRY(write(log->tfd, buf, len));
   }
 
-  if (want_log_write) {
-    __android_log_buf_write(LOG_ID_CRASH, ANDROID_LOG_INFO, "DEBUG", buf);
-    if (want_amfd_write) {
+  if (write_to_logcat) {
+    __android_log_buf_write(LOG_ID_CRASH, ANDROID_LOG_INFO, LOG_TAG, buf);
+    if (write_to_activitymanager) {
       int written = write_to_am(log->amfd, buf, len);
       if (written <= 0) {
         // timeout or other failure on write; stop informing the activity manager
@@ -83,20 +96,20 @@
     if (n < 0) {
       if (errno == EAGAIN)
         continue;
-      LOG("waitpid failed: %s\n", strerror(errno));
+      LOG_ERROR("waitpid failed: %s\n", strerror(errno));
       return -1;
     } else if (n > 0) {
       XLOG("waitpid: n=%d status=%08x\n", n, status);
       if (WIFSTOPPED(status)) {
         return WSTOPSIG(status);
       } else {
-        LOG("unexpected waitpid response: n=%d, status=%08x\n", n, status);
+        LOG_ERROR("unexpected waitpid response: n=%d, status=%08x\n", n, status);
         return -1;
       }
     }
 
     if (*total_sleep_time_usec > max_total_sleep_usec) {
-      LOG("timed out waiting for tid=%d to die\n", tid);
+      LOG_ERROR("timed out waiting for tid=%d to die\n", tid);
       return -1;
     }
 
@@ -111,7 +124,7 @@
   siginfo_t si;
   while (TEMP_FAILURE_RETRY(ptrace(PTRACE_GETSIGINFO, tid, 0, &si)) < 0 && errno == ESRCH) {
     if (*total_sleep_time_usec > max_total_sleep_usec) {
-      LOG("timed out waiting for tid=%d to stop\n", tid);
+      LOG_ERROR("timed out waiting for tid=%d to stop\n", tid);
       break;
     }
 
@@ -126,7 +139,7 @@
 #define DUMP_MEMORY_AS_ASCII 0
 #endif
 
-void dump_memory(log_t* log, pid_t tid, uintptr_t addr, int scope_flags) {
+void dump_memory(log_t* log, pid_t tid, uintptr_t addr) {
     char code_buffer[64];
     char ascii_buffer[32];
     uintptr_t p, end;
@@ -190,6 +203,6 @@
             p += sizeof(long);
         }
         *asc_out = '\0';
-        _LOG(log, scope_flags, "    %s %s\n", code_buffer, ascii_buffer);
+        _LOG(log, logtype::MEMORY, "    %s %s\n", code_buffer, ascii_buffer);
     }
 }
diff --git a/debuggerd/utility.h b/debuggerd/utility.h
index 0f88605..fdfb2ec 100644
--- a/debuggerd/utility.h
+++ b/debuggerd/utility.h
@@ -28,41 +28,36 @@
     int amfd;
     /* if true, does not log anything to the Android logcat or Activity Manager */
     bool quiet;
+    // The tid of the thread that crashed.
+    pid_t crashed_tid;
+    // The tid of the thread we are currently working with.
+    pid_t current_tid;
 } log_t;
 
-/* Log information onto the tombstone.  scopeFlags is a bitmask of the flags defined
- * here. */
-void _LOG(log_t* log, int scopeFlags, const char *fmt, ...)
+// List of types of logs to simplify the logging decision in _LOG
+enum logtype {
+  ERROR,
+  HEADER,
+  THREAD,
+  REGISTERS,
+  BACKTRACE,
+  MAPS,
+  MEMORY,
+  STACK,
+  LOGS
+};
+
+/* Log information onto the tombstone. */
+void _LOG(log_t* log, logtype ltype, const char *fmt, ...)
         __attribute__ ((format(printf, 3, 4)));
 
-/* The message pertains specifically to the faulting thread / process */
-#define SCOPE_AT_FAULT (1 << 0)
-/* The message contains sensitive information such as RAM contents */
-#define SCOPE_SENSITIVE  (1 << 1)
-
-#define IS_AT_FAULT(x)    (((x) & SCOPE_AT_FAULT) != 0)
-#define IS_SENSITIVE(x)    (((x) & SCOPE_SENSITIVE) != 0)
-
 /* Further helpful macros */
-#define LOG(fmt...) _LOG(NULL, SCOPE_AT_FAULT, fmt)
-
-/* Set to 1 for normal debug traces */
-#if 0
-#define XLOG(fmt...) _LOG(NULL, SCOPE_AT_FAULT, fmt)
-#else
+#define LOG_ERROR(fmt...) _LOG(NULL, logtype::ERROR, fmt)
 #define XLOG(fmt...) do {} while(0)
-#endif
-
-/* Set to 1 for chatty debug traces. Includes all resolved dynamic symbols */
-#if 0
-#define XLOG2(fmt...) _LOG(NULL, SCOPE_AT_FAULT, fmt)
-#else
-#define XLOG2(fmt...) do {} while(0)
-#endif
 
 int wait_for_signal(pid_t tid, int* total_sleep_time_usec);
 void wait_for_stop(pid_t tid, int* total_sleep_time_usec);
 
-void dump_memory(log_t* log, pid_t tid, uintptr_t addr, int scope_flags);
+void dump_memory(log_t* log, pid_t tid, uintptr_t addr);
 
 #endif // _DEBUGGERD_UTILITY_H
diff --git a/debuggerd/x86/machine.cpp b/debuggerd/x86/machine.cpp
index bcc217e..2d553fa 100644
--- a/debuggerd/x86/machine.cpp
+++ b/debuggerd/x86/machine.cpp
@@ -25,21 +25,21 @@
 #include "../utility.h"
 #include "../machine.h"
 
-void dump_memory_and_code(log_t*, pid_t, int) {
+void dump_memory_and_code(log_t*, pid_t) {
 }
 
-void dump_registers(log_t* log, pid_t tid, int scope_flags) {
+void dump_registers(log_t* log, pid_t tid) {
   struct pt_regs r;
   if (ptrace(PTRACE_GETREGS, tid, 0, &r) == -1) {
-    _LOG(log, scope_flags, "cannot get registers: %s\n", strerror(errno));
+    LOG_ERROR("cannot get registers: %s\n", strerror(errno));
     return;
   }
-  _LOG(log, scope_flags, "    eax %08lx  ebx %08lx  ecx %08lx  edx %08lx\n",
+  _LOG(log, logtype::REGISTERS, "    eax %08lx  ebx %08lx  ecx %08lx  edx %08lx\n",
        r.eax, r.ebx, r.ecx, r.edx);
-  _LOG(log, scope_flags, "    esi %08lx  edi %08lx\n",
+  _LOG(log, logtype::REGISTERS, "    esi %08lx  edi %08lx\n",
        r.esi, r.edi);
-  _LOG(log, scope_flags, "    xcs %08x  xds %08x  xes %08x  xfs %08x  xss %08x\n",
+  _LOG(log, logtype::REGISTERS, "    xcs %08x  xds %08x  xes %08x  xfs %08x  xss %08x\n",
        r.xcs, r.xds, r.xes, r.xfs, r.xss);
-  _LOG(log, scope_flags, "    eip %08lx  ebp %08lx  esp %08lx  flags %08lx\n",
+  _LOG(log, logtype::REGISTERS, "    eip %08lx  ebp %08lx  esp %08lx  flags %08lx\n",
        r.eip, r.ebp, r.esp, r.eflags);
 }
diff --git a/debuggerd/x86_64/machine.cpp b/debuggerd/x86_64/machine.cpp
index c8c7aa9..6cb0e8d 100755
--- a/debuggerd/x86_64/machine.cpp
+++ b/debuggerd/x86_64/machine.cpp
@@ -27,25 +27,25 @@
 #include "../utility.h"
 #include "../machine.h"
 
-void dump_memory_and_code(log_t*, pid_t, int) {
+void dump_memory_and_code(log_t*, pid_t) {
 }
 
-void dump_registers(log_t* log, pid_t tid, int scope_flags) {
+void dump_registers(log_t* log, pid_t tid) {
     struct user_regs_struct r;
     if (ptrace(PTRACE_GETREGS, tid, 0, &r) == -1) {
-        _LOG(log, scope_flags, "cannot get registers: %s\n", strerror(errno));
+        LOG_ERROR("cannot get registers: %s\n", strerror(errno));
         return;
     }
-    _LOG(log, scope_flags, "    rax %016lx  rbx %016lx  rcx %016lx  rdx %016lx\n",
+    _LOG(log, logtype::REGISTERS, "    rax %016lx  rbx %016lx  rcx %016lx  rdx %016lx\n",
          r.rax, r.rbx, r.rcx, r.rdx);
-    _LOG(log, scope_flags, "    rsi %016lx  rdi %016lx\n",
+    _LOG(log, logtype::REGISTERS, "    rsi %016lx  rdi %016lx\n",
          r.rsi, r.rdi);
-    _LOG(log, scope_flags, "    r8  %016lx  r9  %016lx  r10 %016lx  r11 %016lx\n",
+    _LOG(log, logtype::REGISTERS, "    r8  %016lx  r9  %016lx  r10 %016lx  r11 %016lx\n",
          r.r8, r.r9, r.r10, r.r11);
-    _LOG(log, scope_flags, "    r12 %016lx  r13 %016lx  r14 %016lx  r15 %016lx\n",
+    _LOG(log, logtype::REGISTERS, "    r12 %016lx  r13 %016lx  r14 %016lx  r15 %016lx\n",
          r.r12, r.r13, r.r14, r.r15);
-    _LOG(log, scope_flags, "    cs  %016lx  ss  %016lx\n",
+    _LOG(log, logtype::REGISTERS, "    cs  %016lx  ss  %016lx\n",
          r.cs, r.ss);
-    _LOG(log, scope_flags, "    rip %016lx  rbp %016lx  rsp %016lx  eflags %016lx\n",
+    _LOG(log, logtype::REGISTERS, "    rip %016lx  rbp %016lx  rsp %016lx  eflags %016lx\n",
          r.rip, r.rbp, r.rsp, r.eflags);
 }