Switch completely over to libcorkscrew for Mac OS.
(This patch requires my Darwin libcorkscrew changes.)
(cherry picked from commit 51e916f5b7baf0b0391f55a314a97b12279fe0d5)
Conflicts:
src/runtime_linux.cc
Change-Id: Ife7789597402989e6b8282cc0c0cc1d1832b044a
diff --git a/src/runtime.cc b/src/runtime.cc
index e1c3099..2dfbefd 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -319,9 +319,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 80a8643..95f183f 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";
@@ -221,6 +232,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;
@@ -230,6 +242,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);
@@ -262,29 +275,20 @@
action.sa_sigaction = HandleUnexpectedSignal;
// Use the three-argument sa_sigaction handler.
action.sa_flags |= SA_SIGINFO;
-#if !defined(__APPLE__)
// Use the alternate signal stack so we can catch stack overflows.
action.sa_flags |= SA_ONSTACK;
-#endif
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;