Switch completely over to libcorkscrew for Mac OS.

(This patch requires my Darwin libcorkscrew changes.)

Change-Id: I8d8abe22231418791f9f2956ccdc1bd738e87097
diff --git a/build/Android.libart.mk b/build/Android.libart.mk
index 4b882b6..6ad1e47 100644
--- a/build/Android.libart.mk
+++ b/build/Android.libart.mk
@@ -95,18 +95,15 @@
     LOCAL_STATIC_LIBRARIES += librsloader libLLVMSupport
   endif
   LOCAL_SHARED_LIBRARIES := liblog libnativehelper
+  LOCAL_SHARED_LIBRARIES += libcorkscrew # native stack trace support
   ifeq ($$(art_target_or_host),target)
     LOCAL_SHARED_LIBRARIES += libcutils libstlport libz libdl
     LOCAL_SHARED_LIBRARIES += libdynamic_annotations # tsan support
-    LOCAL_SHARED_LIBRARIES += libcorkscrew # native stack trace support
   else # host
     LOCAL_STATIC_LIBRARIES += libcutils
     LOCAL_SHARED_LIBRARIES += libz-host
     LOCAL_SHARED_LIBRARIES += libdynamic_annotations-host # tsan support
     LOCAL_LDLIBS += -ldl -lpthread
-    ifneq ($(HOST_OS),darwin)
-      LOCAL_SHARED_LIBRARIES += libcorkscrew # native stack trace support
-    endif
     ifeq ($(HOST_OS),linux)
       LOCAL_LDLIBS += -lrt
     endif
diff --git a/src/runtime.cc b/src/runtime.cc
index e033059..0de977f 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -307,9 +307,6 @@
   parsed->hook_vfprintf_ = vfprintf;
   parsed->hook_exit_ = exit;
   parsed->hook_abort_ = NULL; // We don't call abort(3) by default; see Runtime::Abort.
-#if defined(__APPLE__)
-  parsed->hook_abort_ = abort; // On the Mac, abort(3) gives better results; see Runtime::InitPlatformSignalHandlers.
-#endif
 
 //  gLogVerbosity.class_linker = true; // TODO: don't check this in!
 //  gLogVerbosity.compiler = true; // TODO: don't check this in!
diff --git a/src/runtime_linux.cc b/src/runtime_linux.cc
index 1717bc9..039f3f4 100644
--- a/src/runtime_linux.cc
+++ b/src/runtime_linux.cc
@@ -18,6 +18,7 @@
 
 #include <signal.h>
 #include <string.h>
+#include <sys/utsname.h>
 
 #include "logging.h"
 #include "stringprintf.h"
@@ -31,6 +32,16 @@
   }
 };
 
+struct OS {
+  void Dump(std::ostream& os) {
+    utsname info;
+    uname(&info);
+    // Linux 2.6.38.8-gg784 (x86_64)
+    // Darwin 11.4.0 (x86_64)
+    os << info.sysname << " " << info.release << " (" << info.machine << ")";
+  }
+};
+
 static const char* GetSignalName(int signal_number) {
   switch (signal_number) {
     case SIGABRT: return "SIGABRT";
@@ -218,6 +229,7 @@
   bool has_address = (signal_number == SIGILL || signal_number == SIGBUS ||
                       signal_number == SIGFPE || signal_number == SIGSEGV);
 
+  OS os_info;
   UContext thread_context(raw_context);
   Backtrace thread_backtrace;
 
@@ -227,6 +239,7 @@
                                       info->si_code,
                                       GetSignalCodeName(signal_number, info->si_code))
                       << (has_address ? StringPrintf(" fault addr %p", info->si_addr) : "") << "\n"
+                      << "OS: " << Dumpable<OS>(os_info) << "\n"
                       << "Registers:\n" << Dumpable<UContext>(thread_context) << "\n"
                       << "Backtrace:\n" << Dumpable<Backtrace>(thread_backtrace);
 
@@ -253,25 +266,20 @@
   action.sa_flags |= SA_SIGINFO;
   // Remove ourselves as signal handler for this signal, in case of recursion.
   action.sa_flags |= SA_RESETHAND;
+  // Use the alternate signal stack so we can catch stack overflows.
+  action.sa_flags |= SA_ONSTACK;
 
   int rc = 0;
-  rc += sigaction(SIGILL, &action, NULL);
-  rc += sigaction(SIGTRAP, &action, NULL);
   rc += sigaction(SIGABRT, &action, NULL);
   rc += sigaction(SIGBUS, &action, NULL);
   rc += sigaction(SIGFPE, &action, NULL);
+  rc += sigaction(SIGILL, &action, NULL);
+  rc += sigaction(SIGPIPE, &action, NULL);
+  rc += sigaction(SIGSEGV, &action, NULL);
 #if defined(SIGSTKFLT)
   rc += sigaction(SIGSTKFLT, &action, NULL);
 #endif
-  rc += sigaction(SIGPIPE, &action, NULL);
-
-  // Use the alternate signal stack so we can catch stack overflows.
-  // On Mac OS 10.7, backtrace(3) is broken and will return no frames when called from the alternate stack,
-  // so we only use the alternate stack for SIGSEGV so that we at least get backtraces for other signals.
-  // (glibc does the right thing, so we could use the alternate stack for all signals there.)
-  action.sa_flags |= SA_ONSTACK;
-  rc += sigaction(SIGSEGV, &action, NULL);
-
+  rc += sigaction(SIGTRAP, &action, NULL);
   CHECK_EQ(rc, 0);
 }
 
diff --git a/src/utils.cc b/src/utils.cc
index 7dea110..2a1e5a1 100644
--- a/src/utils.cc
+++ b/src/utils.cc
@@ -41,16 +41,12 @@
 #if defined(__APPLE__)
 #include "AvailabilityMacros.h" // For MAC_OS_X_VERSION_MAX_ALLOWED
 #include <sys/syscall.h>
-
-#include <cxxabi.h> // For DumpNativeStack.
-#include <execinfo.h> // For DumpNativeStack.
-
 #endif
 
-#if defined(__linux__)
 #include <corkscrew/backtrace.h> // For DumpNativeStack.
 #include <corkscrew/demangle.h> // For DumpNativeStack.
 
+#if defined(__linux__)
 #include <linux/unistd.h>
 #endif
 
@@ -913,87 +909,6 @@
   return "";
 }
 
-#if defined(__APPLE__)
-
-static std::string Demangle(const std::string& mangled_name) {
-  if (mangled_name.empty()) {
-    return "??";
-  }
-
-  // http://gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html
-  int status;
-  char* name(abi::__cxa_demangle(mangled_name.c_str(), NULL, NULL, &status));
-  if (name != NULL) {
-    std::string result(name);
-    free(name);
-    return result;
-  }
-
-  return mangled_name;
-}
-
-// TODO: port libcorkscrew to Mac OS (or find an equivalent).
-void DumpNativeStack(std::ostream& os, pid_t tid, const char* prefix, bool include_count) {
-  if (tid != GetTid()) {
-    // backtrace(3) only works for the current thread.
-    return;
-  }
-
-  // Get the raw stack frames.
-  size_t MAX_STACK_FRAMES = 128;
-  void* frames[MAX_STACK_FRAMES];
-  size_t frame_count = backtrace(frames, MAX_STACK_FRAMES);
-  if (frame_count == 0) {
-    os << prefix << "--- backtrace(3) returned no frames";
-    return;
-  }
-
-  // Turn them into something human-readable with symbols.
-  char** symbols = backtrace_symbols(frames, frame_count);
-  if (symbols == NULL) {
-    os << prefix << "--- backtrace_symbols(3) failed";
-    return;
-  }
-
-  // Parse the backtrace strings and demangle, so we can produce output like this:
-  // ]    #00 art::Runtime::Abort(char const*, int)+0x15b [0xf770dd51] (libartd.so)
-  for (size_t i = 0; i < frame_count; ++i) {
-    std::string text(symbols[i]);
-    std::string filename("???");
-    std::string function_name;
-
-    // backtrace_symbols(3) gives us lines like this on Mac OS:
-    // "0   libartd.dylib                       0x001cd29a _ZN3art9Backtrace4DumpERSo + 40>"
-    // "3   ???                                 0xffffffff 0x0 + 4294967295>"
-    text.erase(0, 4);
-    size_t index = text.find(' ');
-    filename = text.substr(0, index);
-    text.erase(0, 40 - 4);
-    index = text.find(' ');
-    std::string address(text.substr(0, index));
-    text.erase(0, index + 1);
-    index = text.find(' ');
-    function_name = Demangle(text.substr(0, index));
-    text.erase(0, index);
-    text += " [" + address + "]";
-
-    const char* last_slash = strrchr(filename.c_str(), '/');
-    const char* so_name = (last_slash == NULL) ? filename.c_str() : last_slash + 1;
-    os << prefix;
-    if (include_count) {
-      os << StringPrintf("\t#%02zd ", i);
-    }
-    os << function_name << text << " (" << so_name << ")\n";
-  }
-
-  free(symbols);
-}
-
-// TODO: is there any way to get the kernel stack on Mac OS?
-void DumpKernelStack(std::ostream&, pid_t, const char*, bool) {}
-
-#else
-
 static const char* CleanMapName(const backtrace_symbol_t* symbol) {
   const char* map_name = symbol->map_name;
   if (map_name == NULL) {
@@ -1040,10 +955,10 @@
   UniquePtr<backtrace_frame_t[]> frames(new backtrace_frame_t[MAX_DEPTH]);
   ssize_t frame_count = unwind_backtrace_thread(tid, frames.get(), 0, MAX_DEPTH);
   if (frame_count == -1) {
-    os << prefix << "(unwind_backtrace_thread failed for thread " << tid << ".)";
+    os << prefix << "(unwind_backtrace_thread failed for thread " << tid << ")\n";
     return;
   } else if (frame_count == 0) {
-    os << prefix << "(no native stack frames)";
+    os << prefix << "(no native stack frames)\n";
     return;
   }
 
@@ -1085,11 +1000,18 @@
   free_backtrace_symbols(backtrace_symbols.get(), frame_count);
 }
 
+#if defined(__APPLE__)
+
+// TODO: is there any way to get the kernel stack on Mac OS?
+void DumpKernelStack(std::ostream&, pid_t, const char*, bool) {}
+
+#else
+
 void DumpKernelStack(std::ostream& os, pid_t tid, const char* prefix, bool include_count) {
   std::string kernel_stack_filename(StringPrintf("/proc/self/task/%d/stack", tid));
   std::string kernel_stack;
   if (!ReadFileToString(kernel_stack_filename, &kernel_stack)) {
-    os << "  (couldn't read " << kernel_stack_filename << ")";
+    os << prefix << "(couldn't read " << kernel_stack_filename << ")\n";
   }
 
   std::vector<std::string> kernel_stack_frames;