| Index: tools/CrashHandler.cpp
|
| diff --git a/tools/CrashHandler.cpp b/tools/CrashHandler.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..193e1af0b251a2053482ca3c0c892fde9e027e50
|
| --- /dev/null
|
| +++ b/tools/CrashHandler.cpp
|
| @@ -0,0 +1,88 @@
|
| +#include "CrashHandler.h"
|
| +
|
| +#include "SkTypes.h"
|
| +
|
| +#include <stdio.h>
|
| +#include <stdlib.h>
|
| +#include <signal.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);
|
| +
|
| + fprintf(stderr, "\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);
|
| +
|
| + fprintf(stderr, "%s (+0x%zx)\n", ok == 0 ? demangled : mangled, (size_t)offset);
|
| + }
|
| + fprintf(stderr, "\n");
|
| +
|
| + // Exit NOW. Don't notify other threads, don't call anything registered with atexit().
|
| + _Exit(sig);
|
| +}
|
| +
|
| +#elif defined(SK_BUILD_FOR_UNIX)
|
| +
|
| +// 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);
|
| +
|
| + fprintf(stderr, "\nSignal %d:\n", 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_UNIX) || defined(SK_BUILD_FOR_MAC)
|
| +
|
| +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);
|
| + }
|
| + }
|
| +}
|
| +
|
| +// TODO: #elif defined(SK_BUILD_FOR_WIN) when I find a Windows machine to work from.
|
| +
|
| +#else
|
| +
|
| +void SetupCrashHandler() { }
|
| +
|
| +#endif
|
|
|