Merge "Enable host multilib for ART testing."
diff --git a/adb/usb_vendors.c b/adb/usb_vendors.c
index c7e0ad5..705f02b 100755
--- a/adb/usb_vendors.c
+++ b/adb/usb_vendors.c
@@ -74,6 +74,8 @@
 #define VENDOR_ID_GIGABYTE      0x0414
 // Gigaset's USB Vendor ID
 #define VENDOR_ID_GIGASET       0x1E85
+// GIONEE's USB Vendor ID
+#define VENDOR_ID_GIONEE        0x271D
 // Google's USB Vendor ID
 #define VENDOR_ID_GOOGLE        0x18d1
 // Haier's USB Vendor ID
@@ -210,6 +212,7 @@
     VENDOR_ID_GARMIN_ASUS,
     VENDOR_ID_GIGABYTE,
     VENDOR_ID_GIGASET,
+    VENDOR_ID_GIONEE,
     VENDOR_ID_GOOGLE,
     VENDOR_ID_HAIER,
     VENDOR_ID_HARRIS,
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);
 }
diff --git a/init/devices.c b/init/devices.c
index 3119e8e..02698ef 100644
--- a/init/devices.c
+++ b/init/devices.c
@@ -196,7 +196,8 @@
 
 static void make_device(const char *path,
                         const char *upath UNUSED,
-                        int block, int major, int minor)
+                        int block, int major, int minor,
+                        const char **links)
 {
     unsigned uid;
     unsigned gid;
@@ -207,7 +208,7 @@
     mode = get_device_perm(path, &uid, &gid) | (block ? S_IFBLK : S_IFCHR);
 
     if (sehandle) {
-        selabel_lookup(sehandle, &secontext, path, mode);
+        selabel_lookup_best_match(sehandle, &secontext, path, links, mode);
         setfscreatecon(secontext);
     }
 
@@ -523,7 +524,7 @@
     int i;
 
     if(!strcmp(action, "add")) {
-        make_device(devpath, path, block, major, minor);
+        make_device(devpath, path, block, major, minor, (const char **)links);
         if (links) {
             for (i = 0; links[i]; i++)
                 make_link(devpath, links[i]);