4ea2661cbd
CQ_EXTRA_TRYBOTS=tryserver.skia:Build-Ubuntu13.10-GCC4.8-NaCl-Debug-Trybot BUG=skia: R=mtklein@google.com Author: mtklein@chromium.org Review URL: https://codereview.chromium.org/344603005
89 lines
2.3 KiB
C++
89 lines
2.3 KiB
C++
#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) && !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);
|
|
|
|
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_MAC) || (defined(SK_BUILD_FOR_UNIX) && !defined(SK_BUILD_FOR_NACL))
|
|
|
|
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
|