| Index: dm/DM.cpp
|
| diff --git a/dm/DM.cpp b/dm/DM.cpp
|
| index df93bfcf1c6e4fea22b02af13b13ed238e18669b..48aaea7e4e0efc9f49308dcc3fb2c4fc9c6d168a 100644
|
| --- a/dm/DM.cpp
|
| +++ b/dm/DM.cpp
|
| @@ -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);
|
| });
|
| }
|
| }
|
|
|