Index: tools/CrashHandler.cpp |
diff --git a/tools/CrashHandler.cpp b/tools/CrashHandler.cpp |
index 174176e4ac3d0b24eb82e3d111010926980a0da0..7355f20bc05c35cbd650f1ba490d577dfab6b91e 100644 |
--- a/tools/CrashHandler.cpp |
+++ b/tools/CrashHandler.cpp |
@@ -4,169 +4,178 @@ |
#include <stdlib.h> |
-#if defined(SK_BUILD_FOR_MAC) |
- |
-// We only use local unwinding, so we can define this to select a faster implementation. |
-#define UNW_LOCAL_ONLY |
-#include <libunwind.h> |
-#include <cxxabi.h> |
- |
-static void handler(int sig) { |
- unw_context_t context; |
- unw_getcontext(&context); |
- |
- unw_cursor_t cursor; |
- unw_init_local(&cursor, &context); |
- |
- SkDebugf("\nSignal %d:\n", sig); |
- while (unw_step(&cursor) > 0) { |
- static const size_t kMax = 256; |
- char mangled[kMax], demangled[kMax]; |
- unw_word_t offset; |
- unw_get_proc_name(&cursor, mangled, kMax, &offset); |
- |
- int ok; |
- size_t len = kMax; |
- abi::__cxa_demangle(mangled, demangled, &len, &ok); |
- |
- SkDebugf("%s (+0x%zx)\n", ok == 0 ? demangled : mangled, (size_t)offset); |
- } |
- SkDebugf("\n"); |
- |
- // Exit NOW. Don't notify other threads, don't call anything registered with atexit(). |
- _Exit(sig); |
-} |
- |
-#elif defined(SK_BUILD_FOR_UNIX) && !defined(SK_BUILD_FOR_NACL) // NACL doesn't have backtrace(). |
- |
-// We'd use libunwind here too, but it's a pain to get installed for both 32 and 64 bit on bots. |
-// Doesn't matter much: catchsegv is best anyway. |
-#include <execinfo.h> |
- |
-static void handler(int sig) { |
- static const int kMax = 64; |
- void* stack[kMax]; |
- const int count = backtrace(stack, kMax); |
- |
- SkDebugf("\nSignal %d [%s]:\n", sig, strsignal(sig)); |
- backtrace_symbols_fd(stack, count, 2/*stderr*/); |
- |
- // Exit NOW. Don't notify other threads, don't call anything registered with atexit(). |
- _Exit(sig); |
-} |
- |
-#endif |
- |
-#if defined(SK_BUILD_FOR_MAC) || (defined(SK_BUILD_FOR_UNIX) && !defined(SK_BUILD_FOR_NACL)) |
-#include <signal.h> |
- |
-void SetupCrashHandler() { |
- static const int kSignals[] = { |
- SIGABRT, |
- SIGBUS, |
- SIGFPE, |
- SIGILL, |
- SIGSEGV, |
- }; |
- |
- for (size_t i = 0; i < sizeof(kSignals) / sizeof(kSignals[0]); i++) { |
- // Register our signal handler unless something's already done so (e.g. catchsegv). |
- void (*prev)(int) = signal(kSignals[i], handler); |
- if (prev != SIG_DFL) { |
- signal(kSignals[i], prev); |
+// Disable SetupCrashHandler() unless SK_CRASH_HANDLER is defined. |
+#ifndef SK_CRASH_HANDLER |
+ void SetupCrashHandler() { } |
+ |
+#else |
+ |
+ #if defined(SK_BUILD_FOR_MAC) |
+ |
+ // We only use local unwinding, so we can define this to select a faster implementation. |
+ #define UNW_LOCAL_ONLY |
+ #include <libunwind.h> |
+ #include <cxxabi.h> |
+ |
+ static void handler(int sig) { |
+ unw_context_t context; |
+ unw_getcontext(&context); |
+ |
+ unw_cursor_t cursor; |
+ unw_init_local(&cursor, &context); |
+ |
+ SkDebugf("\nSignal %d:\n", sig); |
+ while (unw_step(&cursor) > 0) { |
+ static const size_t kMax = 256; |
+ char mangled[kMax], demangled[kMax]; |
+ unw_word_t offset; |
+ unw_get_proc_name(&cursor, mangled, kMax, &offset); |
+ |
+ int ok; |
+ size_t len = kMax; |
+ abi::__cxa_demangle(mangled, demangled, &len, &ok); |
+ |
+ SkDebugf("%s (+0x%zx)\n", ok == 0 ? demangled : mangled, (size_t)offset); |
+ } |
+ SkDebugf("\n"); |
+ |
+ // Exit NOW. Don't notify other threads, don't call anything registered with atexit(). |
+ _Exit(sig); |
+ } |
+ |
+ #elif defined(SK_BUILD_FOR_UNIX) && !defined(SK_BUILD_FOR_NACL) // NACL doesn't have backtrace. |
+ |
+ // We'd use libunwind here too, but it's a pain to get installed for |
+ // both 32 and 64 bit on bots. Doesn't matter much: catchsegv is best anyway. |
+ #include <execinfo.h> |
+ |
+ static void handler(int sig) { |
+ static const int kMax = 64; |
+ void* stack[kMax]; |
+ const int count = backtrace(stack, kMax); |
+ |
+ SkDebugf("\nSignal %d [%s]:\n", sig, strsignal(sig)); |
+ backtrace_symbols_fd(stack, count, 2/*stderr*/); |
+ |
+ // Exit NOW. Don't notify other threads, don't call anything registered with atexit(). |
+ _Exit(sig); |
} |
- } |
-} |
- |
-#elif defined(SK_BUILD_FOR_WIN) |
- |
-#include <DbgHelp.h> |
- |
-static const struct { |
- const char* name; |
- int code; |
-} kExceptions[] = { |
-#define _(E) {#E, E} |
- _(EXCEPTION_ACCESS_VIOLATION), |
- _(EXCEPTION_BREAKPOINT), |
- _(EXCEPTION_INT_DIVIDE_BY_ZERO), |
- _(EXCEPTION_STACK_OVERFLOW), |
- // TODO: more? |
-#undef _ |
-}; |
- |
-static LONG WINAPI handler(EXCEPTION_POINTERS* e) { |
- const DWORD code = e->ExceptionRecord->ExceptionCode; |
- SkDebugf("\nCaught exception %u", code); |
- for (size_t i = 0; i < SK_ARRAY_COUNT(kExceptions); i++) { |
- if (kExceptions[i].code == code) { |
- SkDebugf(" %s", kExceptions[i].name); |
+ |
+ #endif |
+ |
+ #if (defined(SK_BUILD_FOR_MAC) || (defined(SK_BUILD_FOR_UNIX) && !defined(SK_BUILD_FOR_NACL))) |
+ #include <signal.h> |
+ |
+ void SetupCrashHandler() { |
+ static const int kSignals[] = { |
+ SIGABRT, |
+ SIGBUS, |
+ SIGFPE, |
+ SIGILL, |
+ SIGSEGV, |
+ }; |
+ |
+ for (size_t i = 0; i < sizeof(kSignals) / sizeof(kSignals[0]); i++) { |
+ // Register our signal handler unless something's already done so (e.g. catchsegv). |
+ void (*prev)(int) = signal(kSignals[i], handler); |
+ if (prev != SIG_DFL) { |
+ signal(kSignals[i], prev); |
+ } |
+ } |
} |
- } |
- SkDebugf("\n"); |
- |
- // We need to run SymInitialize before doing any of the stack walking below. |
- HANDLE hProcess = GetCurrentProcess(); |
- SymInitialize(hProcess, 0, true); |
- |
- STACKFRAME64 frame; |
- sk_bzero(&frame, sizeof(frame)); |
- // Start frame off from the frame that triggered the exception. |
- CONTEXT* c = e->ContextRecord; |
- frame.AddrPC.Mode = AddrModeFlat; |
- frame.AddrStack.Mode = AddrModeFlat; |
- frame.AddrFrame.Mode = AddrModeFlat; |
-#if defined(_X86_) |
- frame.AddrPC.Offset = c->Eip; |
- frame.AddrStack.Offset = c->Esp; |
- frame.AddrFrame.Offset = c->Ebp; |
- const DWORD machineType = IMAGE_FILE_MACHINE_I386; |
-#elif defined(_AMD64_) |
- frame.AddrPC.Offset = c->Rip; |
- frame.AddrStack.Offset = c->Rsp; |
- frame.AddrFrame.Offset = c->Rbp; |
- const DWORD machineType = IMAGE_FILE_MACHINE_AMD64; |
-#endif |
- |
- while (StackWalk64(machineType, |
- GetCurrentProcess(), |
- GetCurrentThread(), |
- &frame, |
- c, |
- NULL, |
- SymFunctionTableAccess64, |
- SymGetModuleBase64, |
- NULL)) { |
- // Buffer to store symbol name in. |
- static const int kMaxNameLength = 1024; |
- uint8_t buffer[sizeof(IMAGEHLP_SYMBOL64) + kMaxNameLength]; |
- sk_bzero(buffer, sizeof(buffer)); |
- |
- // We have to place IMAGEHLP_SYMBOL64 at the front, and fill in how much space it can use. |
- IMAGEHLP_SYMBOL64* symbol = reinterpret_cast<IMAGEHLP_SYMBOL64*>(&buffer); |
- symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64); |
- symbol->MaxNameLength = kMaxNameLength - 1; |
- |
- // Translate the current PC into a symbol and byte offset from the symbol. |
- DWORD64 offset; |
- SymGetSymFromAddr64(hProcess, frame.AddrPC.Offset, &offset, symbol); |
- |
- SkDebugf("%s +%x\n", symbol->Name, offset); |
- } |
- |
- // Exit NOW. Don't notify other threads, don't call anything registered with atexit(). |
- _exit(1); |
- |
- // The compiler wants us to return something. This is what we'd do if we didn't _exit(). |
- return EXCEPTION_EXECUTE_HANDLER; |
-} |
- |
-void SetupCrashHandler() { |
- SetUnhandledExceptionFilter(handler); |
-} |
-#else |
+ #elif defined(SK_CRASH_HANDLER) && defined(SK_BUILD_FOR_WIN) |
+ |
+ #include <DbgHelp.h> |
+ |
+ static const struct { |
+ const char* name; |
+ int code; |
+ } kExceptions[] = { |
+ #define _(E) {#E, E} |
+ _(EXCEPTION_ACCESS_VIOLATION), |
+ _(EXCEPTION_BREAKPOINT), |
+ _(EXCEPTION_INT_DIVIDE_BY_ZERO), |
+ _(EXCEPTION_STACK_OVERFLOW), |
+ // TODO: more? |
+ #undef _ |
+ }; |
+ |
+ static LONG WINAPI handler(EXCEPTION_POINTERS* e) { |
+ const DWORD code = e->ExceptionRecord->ExceptionCode; |
+ SkDebugf("\nCaught exception %u", code); |
+ for (size_t i = 0; i < SK_ARRAY_COUNT(kExceptions); i++) { |
+ if (kExceptions[i].code == code) { |
+ SkDebugf(" %s", kExceptions[i].name); |
+ } |
+ } |
+ SkDebugf("\n"); |
+ |
+ // We need to run SymInitialize before doing any of the stack walking below. |
+ HANDLE hProcess = GetCurrentProcess(); |
+ SymInitialize(hProcess, 0, true); |
+ |
+ STACKFRAME64 frame; |
+ sk_bzero(&frame, sizeof(frame)); |
+ // Start frame off from the frame that triggered the exception. |
+ CONTEXT* c = e->ContextRecord; |
+ frame.AddrPC.Mode = AddrModeFlat; |
+ frame.AddrStack.Mode = AddrModeFlat; |
+ frame.AddrFrame.Mode = AddrModeFlat; |
+ #if defined(_X86_) |
+ frame.AddrPC.Offset = c->Eip; |
+ frame.AddrStack.Offset = c->Esp; |
+ frame.AddrFrame.Offset = c->Ebp; |
+ const DWORD machineType = IMAGE_FILE_MACHINE_I386; |
+ #elif defined(_AMD64_) |
+ frame.AddrPC.Offset = c->Rip; |
+ frame.AddrStack.Offset = c->Rsp; |
+ frame.AddrFrame.Offset = c->Rbp; |
+ const DWORD machineType = IMAGE_FILE_MACHINE_AMD64; |
+ #endif |
+ |
+ while (StackWalk64(machineType, |
+ GetCurrentProcess(), |
+ GetCurrentThread(), |
+ &frame, |
+ c, |
+ NULL, |
+ SymFunctionTableAccess64, |
+ SymGetModuleBase64, |
+ NULL)) { |
+ // Buffer to store symbol name in. |
+ static const int kMaxNameLength = 1024; |
+ uint8_t buffer[sizeof(IMAGEHLP_SYMBOL64) + kMaxNameLength]; |
+ sk_bzero(buffer, sizeof(buffer)); |
+ |
+ // We have to place IMAGEHLP_SYMBOL64 at the front, and fill in |
+ // how much space it can use. |
+ IMAGEHLP_SYMBOL64* symbol = reinterpret_cast<IMAGEHLP_SYMBOL64*>(&buffer); |
+ symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64); |
+ symbol->MaxNameLength = kMaxNameLength - 1; |
+ |
+ // Translate the current PC into a symbol and byte offset from the symbol. |
+ DWORD64 offset; |
+ SymGetSymFromAddr64(hProcess, frame.AddrPC.Offset, &offset, symbol); |
+ |
+ SkDebugf("%s +%x\n", symbol->Name, offset); |
+ } |
+ |
+ // Exit NOW. Don't notify other threads, don't call anything registered with atexit(). |
+ _exit(1); |
+ |
+ // The compiler wants us to return something. This is what we'd do |
+ // if we didn't _exit(). |
+ return EXCEPTION_EXECUTE_HANDLER; |
+ } |
+ |
+ void SetupCrashHandler() { |
+ SetUnhandledExceptionFilter(handler); |
+ } |
+ |
+ #else // We asked for SK_CRASH_HANDLER, but it's not Mac, Linux, or Windows. Sorry! |
-void SetupCrashHandler() { } |
+ void SetupCrashHandler() { } |
-#endif |
+ #endif |
+#endif // SK_CRASH_HANDLER |