diff options
author | 2016-02-29 06:35:28 -0800 | |
---|---|---|
committer | 2016-02-29 06:35:29 -0800 | |
commit | f85572956473efd8298522acb4bf0ee75cbdb86b (patch) | |
tree | 14d8f39f2cb2cc488a40a30b155557ac7554d6ca /dm | |
parent | 08fc80704d369508276c0bd9d34eb4f8cb2c2f54 (diff) |
DM crash handler tweaks
- try to guard against reentrant signals.
- re-raise the signal with the default handler when done printing.
- support Windows
BUG=589654
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1744553002
Review URL: https://codereview.chromium.org/1744553002
Diffstat (limited to 'dm')
-rw-r--r-- | dm/DM.cpp | 46 |
1 files changed, 41 insertions, 5 deletions
@@ -129,20 +129,56 @@ static void print_status() { } } +// Yo dawg, I heard you like signals so I caught a signal in your +// signal handler so you can handle signals while you handle signals. +// Let's not get into that situation. Only print if we're the first ones to get a crash signal. +static std::atomic<bool> in_signal_handler{false}; + #if defined(SK_BUILD_FOR_WIN32) - static void setup_crash_handler() { - // TODO: custom crash handler like below to print out what was running - SetupCrashHandler(); + static LONG WINAPI handler(EXCEPTION_POINTERS* e) { + 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 _ + }; + + if (!in_signal_handler.exchange(true)) { + const DWORD code = e->ExceptionRecord->ExceptionCode; + SkDebugf("\nCaught exception %u", code); + for (const auto& exception : kExceptions) { + if (exception.code == code) { + SkDebugf(" %s", exception.name); + } + } + SkDebugf("\n"); + print_status(); + } + // Execute default exception handler... hopefully, exit. + return EXCEPTION_EXECUTE_HANDLER; } + static void setup_crash_handler() { SetUnhandledExceptionFilter(handler); } #else #include <signal.h> + static void setup_crash_handler() { const int kSignals[] = { SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV }; for (int sig : kSignals) { signal(sig, [](int sig) { - SkDebugf("\nCaught signal %d [%s].\n", sig, strsignal(sig)); - print_status(); + if (!in_signal_handler.exchange(true)) { + SkDebugf("\nCaught signal %d [%s].\n", sig, strsignal(sig)); + print_status(); + } + // Reraise this signal to the default handler... hopefully, exit. + signal(sig, SIG_DFL); + raise(sig); }); } } |