Prevent hang due to HandleUnexpectedSignal reentry

Change-Id: I0fe6a9b642e8d866aba893906c36bca6f1a4334e
diff --git a/src/logging.cc b/src/logging.cc
index 9dde963..12d1fa4 100644
--- a/src/logging.cc
+++ b/src/logging.cc
@@ -94,6 +94,15 @@
   }
 }
 
+LogMessageData::LogMessageData(const char* file, int line, LogSeverity severity, int error)
+    : file(file),
+      line_number(line),
+      severity(severity),
+      error(error) {
+  const char* last_slash = strrchr(file, '/');
+  file = (last_slash == NULL) ? file : last_slash + 1;
+}
+
 LogMessage::~LogMessage() {
   if (data_->severity < gMinimumLogSeverity) {
     return; // No need to format something we're not going to output.
@@ -109,14 +118,14 @@
   {
     MutexLock mu(Thread::Current(), *Locks::logging_lock_);
     if (msg.find('\n') == std::string::npos) {
-      LogLine(msg.c_str());
+      LogLine(*data_, msg.c_str());
     } else {
       msg += '\n';
       size_t i = 0;
       while (i < msg.size()) {
         size_t nl = msg.find('\n', i);
         msg[nl] = '\0';
-        LogLine(&msg[i]);
+        LogLine(*data_, &msg[i]);
         i = nl + 1;
       }
     }
diff --git a/src/logging.h b/src/logging.h
index d0d35ea..1c04b2c 100644
--- a/src/logging.h
+++ b/src/logging.h
@@ -21,6 +21,7 @@
 #include <cstring>
 #include <iostream>  // NOLINT
 #include <sstream>
+#include <signal.h>
 #include "log_severity.h"
 #include "macros.h"
 
@@ -167,13 +168,7 @@
 // lots of checks/logging in a function.
 struct LogMessageData {
  public:
-  LogMessageData(int line, LogSeverity severity, int error)
-      : file(NULL),
-        line_number(line),
-        severity(severity),
-        error(error) {
-  }
-
+  LogMessageData(const char* file, int line, LogSeverity severity, int error);
   std::ostringstream buffer;
   const char* file;
   int line_number;
@@ -186,15 +181,18 @@
 
 class LogMessage {
  public:
-  LogMessage(const char* file, int line, LogSeverity severity, int error);
+  LogMessage(const char* file, int line, LogSeverity severity, int error)
+    : data_(new LogMessageData(file, line, severity, error)) {
+  }
   ~LogMessage() LOCKS_EXCLUDED(Locks::logging_lock_);
   std::ostream& stream();
 
  private:
-  void LogLine(const char*);
+  static void LogLine(const LogMessageData& data, const char*);
 
   LogMessageData* data_;
 
+  friend void HandleUnexpectedSignal(int signal_number, siginfo_t* info, void* raw_context);
   DISALLOW_COPY_AND_ASSIGN(LogMessage);
 };
 
diff --git a/src/logging_android.cc b/src/logging_android.cc
index 7007d7a..0acf5f9 100644
--- a/src/logging_android.cc
+++ b/src/logging_android.cc
@@ -29,17 +29,11 @@
   ANDROID_LOG_ERROR, ANDROID_LOG_FATAL, ANDROID_LOG_FATAL
 };
 
-LogMessage::LogMessage(const char* file, int line, LogSeverity severity, int error)
-    : data_(new LogMessageData(line, severity, error)) {
-  const char* last_slash = strrchr(file, '/');
-  data_->file = (last_slash == NULL) ? file : last_slash + 1;
-}
-
-void LogMessage::LogLine(const char* message) {
+void LogMessage::LogLine(const LogMessageData& data, const char* message) {
   const char* tag = ProgramInvocationShortName();
-  int priority = kLogSeverityToAndroidLogPriority[data_->severity];
+  int priority = kLogSeverityToAndroidLogPriority[data.severity];
   if (priority == ANDROID_LOG_FATAL) {
-    LOG_PRI(priority, tag, "%s:%d] %s", data_->file, data_->line_number, message);
+    LOG_PRI(priority, tag, "%s:%d] %s", data.file, data.line_number, message);
   } else {
     LOG_PRI(priority, tag, "%s", message);
   }
diff --git a/src/logging_linux.cc b/src/logging_linux.cc
index 0d7fc0b..789c083 100644
--- a/src/logging_linux.cc
+++ b/src/logging_linux.cc
@@ -27,17 +27,11 @@
 
 namespace art {
 
-LogMessage::LogMessage(const char* file, int line, LogSeverity severity, int error)
-    : data_(new LogMessageData(line, severity, error)) {
-  const char* last_slash = strrchr(file, '/');
-  data_->file = (last_slash == NULL) ? file : last_slash + 1;
-}
-
-void LogMessage::LogLine(const char* message) {
-  char severity = "VDIWEFF"[data_->severity];
+void LogMessage::LogLine(const LogMessageData& data, const char* message) {
+  char severity = "VDIWEFF"[data.severity];
   fprintf(stderr, "%s %c %5d %5d %s:%d] %s\n",
           ProgramInvocationShortName(), severity, getpid(), ::art::GetTid(),
-          data_->file, data_->line_number, message);
+          data.file, data.line_number, message);
 }
 
 }  // namespace art
diff --git a/src/runtime_linux.cc b/src/runtime_linux.cc
index 430c70f..72989a6 100644
--- a/src/runtime_linux.cc
+++ b/src/runtime_linux.cc
@@ -227,7 +227,15 @@
   mcontext_t& context;
 };
 
-static void HandleUnexpectedSignal(int signal_number, siginfo_t* info, void* raw_context) {
+void HandleUnexpectedSignal(int signal_number, siginfo_t* info, void* raw_context) {
+  static bool handlingUnexpectedSignal = false;
+  if (handlingUnexpectedSignal) {
+    LogMessageData data(__FILE__, __LINE__, INTERNAL_FATAL, -1);
+    LogMessage::LogLine(data, "HandleUnexpectedSignal reentered\n");
+    _exit(1);
+  }
+  handlingUnexpectedSignal = true;
+
   gAborting = true;  // set before taking any locks
   MutexLock mu(Thread::Current(), *Locks::unexpected_signal_lock_);