More libbacktrace fixes.

Included in minor fix ups is the addition of a warning macro to replace
all of the ALOGW calls.

Fix a race where multiple threads could be attempting to unwind the threads
of the current process at the same time.

Bug: 8410085

Change-Id: I02a65dc778dde690e5f95fc8ff069a32d0832fd1
diff --git a/libbacktrace/BacktraceThread.cpp b/libbacktrace/BacktraceThread.cpp
index 6c3641e..8e664c4 100644
--- a/libbacktrace/BacktraceThread.cpp
+++ b/libbacktrace/BacktraceThread.cpp
@@ -31,55 +31,55 @@
 // ThreadEntry implementation.
 //-------------------------------------------------------------------------
 static ThreadEntry* g_list = NULL;
-static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t g_entry_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t g_sigaction_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 ThreadEntry::ThreadEntry(
     BacktraceThreadInterface* intf, pid_t pid, pid_t tid, size_t num_ignore_frames)
-    : thread_intf_(intf), pid_(pid), tid_(tid), next_(NULL), prev_(NULL),
-      state_(STATE_WAITING), num_ignore_frames_(num_ignore_frames) {
+    : thread_intf(intf), pid(pid), tid(tid), next(NULL), prev(NULL),
+      state(STATE_WAITING), num_ignore_frames(num_ignore_frames) {
 }
 
 ThreadEntry::~ThreadEntry() {
-  pthread_mutex_lock(&g_mutex);
+  pthread_mutex_lock(&g_entry_mutex);
   if (g_list == this) {
-    g_list = next_;
+    g_list = next;
   } else {
-    if (next_) {
-      next_->prev_ = prev_;
+    if (next) {
+      next->prev = prev;
     }
-    prev_->next_ = next_;
+    prev->next = next;
   }
-  pthread_mutex_unlock(&g_mutex);
+  pthread_mutex_unlock(&g_entry_mutex);
 
-  next_ = NULL;
-  prev_ = NULL;
+  next = NULL;
+  prev = NULL;
 }
 
 ThreadEntry* ThreadEntry::AddThreadToUnwind(
     BacktraceThreadInterface* intf, pid_t pid, pid_t tid, size_t num_ignore_frames) {
   ThreadEntry* entry = new ThreadEntry(intf, pid, tid, num_ignore_frames);
 
-  pthread_mutex_lock(&g_mutex);
+  pthread_mutex_lock(&g_entry_mutex);
   ThreadEntry* cur_entry = g_list;
   while (cur_entry != NULL) {
     if (cur_entry->Match(pid, tid)) {
       // There is already an entry for this pid/tid, this is bad.
-      ALOGW("%s::%s(): Entry for pid %d tid %d already exists.\n",
-            __FILE__, __FUNCTION__, pid, tid);
+      BACK_LOGW("Entry for pid %d tid %d already exists.", pid, tid);
 
-      pthread_mutex_unlock(&g_mutex);
+      pthread_mutex_unlock(&g_entry_mutex);
       return NULL;
     }
-    cur_entry = cur_entry->next_;
+    cur_entry = cur_entry->next;
   }
 
   // Add the entry to the list.
-  entry->next_ = g_list;
+  entry->next = g_list;
   if (g_list) {
-    g_list->prev_ = entry;
+    g_list->prev = entry;
   }
   g_list = entry;
-  pthread_mutex_unlock(&g_mutex);
+  pthread_mutex_unlock(&g_entry_mutex);
 
   return entry;
 }
@@ -89,7 +89,7 @@
 //-------------------------------------------------------------------------
 static void SignalHandler(int n __attribute__((unused)), siginfo_t* siginfo,
                           void* sigcontext) {
-  if (pthread_mutex_lock(&g_mutex) == 0) {
+  if (pthread_mutex_lock(&g_entry_mutex) == 0) {
     pid_t pid = getpid();
     pid_t tid = gettid();
     ThreadEntry* cur_entry = g_list;
@@ -97,20 +97,19 @@
       if (cur_entry->Match(pid, tid)) {
         break;
       }
-      cur_entry = cur_entry->next_;
+      cur_entry = cur_entry->next;
     }
-    pthread_mutex_unlock(&g_mutex);
+    pthread_mutex_unlock(&g_entry_mutex);
     if (!cur_entry) {
-      ALOGW("%s::%s(): Unable to find pid %d tid %d information\n",
-            __FILE__, __FUNCTION__, pid, tid);
+      BACK_LOGW("Unable to find pid %d tid %d information", pid, tid);
       return;
     }
 
-    if (android_atomic_acquire_cas(STATE_WAITING, STATE_DUMPING, &cur_entry->state_) == 0) {
-      cur_entry->thread_intf_->ThreadUnwind(siginfo, sigcontext,
-                                            cur_entry->num_ignore_frames_);
+    if (android_atomic_acquire_cas(STATE_WAITING, STATE_DUMPING, &cur_entry->state) == 0) {
+      cur_entry->thread_intf->ThreadUnwind(siginfo, sigcontext,
+                                           cur_entry->num_ignore_frames);
     }
-    android_atomic_release_store(STATE_DONE, &cur_entry->state_);
+    android_atomic_release_store(STATE_DONE, &cur_entry->state);
   }
 }
 
@@ -143,18 +142,18 @@
 }
 
 bool BacktraceThread::TriggerUnwindOnThread(ThreadEntry* entry) {
-  entry->state_ = STATE_WAITING;
+  entry->state = STATE_WAITING;
 
   if (tgkill(Pid(), Tid(), SIGURG) != 0) {
-    ALOGW("%s::%s(): tgkill failed %s\n", __FILE__, __FUNCTION__, strerror(errno));
+    BACK_LOGW("tgkill failed %s", strerror(errno));
     return false;
   }
 
-  // Allow up to a second for the dump to occur.
-  int wait_millis = 1000;
+  // Allow up to ten seconds for the dump to start.
+  int wait_millis = 10000;
   int32_t state;
   while (true) {
-    state = android_atomic_acquire_load(&entry->state_);
+    state = android_atomic_acquire_load(&entry->state);
     if (state != STATE_WAITING) {
       break;
     }
@@ -167,24 +166,22 @@
 
   bool cancelled = false;
   if (state == STATE_WAITING) {
-    if (android_atomic_acquire_cas(state, STATE_CANCEL, &entry->state_) == 0) {
-      ALOGW("%s::%s(): Cancelled dump of thread %d\n", __FILE__, __FUNCTION__,
-            entry->tid_);
+    if (android_atomic_acquire_cas(state, STATE_CANCEL, &entry->state) == 0) {
+      BACK_LOGW("Cancelled dump of thread %d", entry->tid);
       state = STATE_CANCEL;
       cancelled = true;
     } else {
-      state = android_atomic_acquire_load(&entry->state_);
+      state = android_atomic_acquire_load(&entry->state);
     }
   }
 
-  // Wait for at most one minute for the dump to finish.
-  wait_millis = 60000;
-  while (android_atomic_acquire_load(&entry->state_) != STATE_DONE) {
+  // Wait for at most ten seconds for the cancel or dump to finish.
+  wait_millis = 10000;
+  while (android_atomic_acquire_load(&entry->state) != STATE_DONE) {
     if (wait_millis--) {
       usleep(1000);
     } else {
-      ALOGW("%s::%s(): Didn't finish thread unwind in 60 seconds.\n",
-            __FILE__, __FUNCTION__);
+      BACK_LOGW("Didn't finish thread unwind in 60 seconds.");
       break;
     }
   }
@@ -202,17 +199,24 @@
     return false;
   }
 
+  // Prevent multiple threads trying to set the trigger action on different
+  // threads at the same time.
   bool retval = false;
-  struct sigaction act, oldact;
-  memset(&act, 0, sizeof(act));
-  act.sa_sigaction = SignalHandler;
-  act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
-  sigemptyset(&act.sa_mask);
-  if (sigaction(SIGURG, &act, &oldact) == 0) {
-    retval = TriggerUnwindOnThread(entry);
-    sigaction(SIGURG, &oldact, NULL);
+  if (pthread_mutex_lock(&g_sigaction_mutex) == 0) {
+    struct sigaction act, oldact;
+    memset(&act, 0, sizeof(act));
+    act.sa_sigaction = SignalHandler;
+    act.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK;
+    sigemptyset(&act.sa_mask);
+    if (sigaction(SIGURG, &act, &oldact) == 0) {
+      retval = TriggerUnwindOnThread(entry);
+      sigaction(SIGURG, &oldact, NULL);
+    } else {
+      BACK_LOGW("sigaction failed %s", strerror(errno));
+    }
+    pthread_mutex_unlock(&g_sigaction_mutex);
   } else {
-    ALOGW("%s::%s(): sigaction failed %s\n", __FILE__, __FUNCTION__, strerror(errno));
+    BACK_LOGW("unable to acquire sigaction mutex.");
   }
 
   if (retval) {