aboutsummaryrefslogtreecommitdiffhomepage
path: root/dm
diff options
context:
space:
mode:
authorGravatar mtklein <mtklein@chromium.org>2016-02-29 06:35:28 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2016-02-29 06:35:29 -0800
commitf85572956473efd8298522acb4bf0ee75cbdb86b (patch)
tree14d8f39f2cb2cc488a40a30b155557ac7554d6ca /dm
parent08fc80704d369508276c0bd9d34eb4f8cb2c2f54 (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.cpp46
1 files changed, 41 insertions, 5 deletions
diff --git a/dm/DM.cpp b/dm/DM.cpp
index df93bfcf1c..48aaea7e4e 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);
});
}
}