Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Unified Diff: tools/CrashHandler.cpp

Issue 340523007: CrashHandler for Windows. (Closed) Base URL: https://skia.googlesource.com/skia@master
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « include/core/SkPostConfig.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/CrashHandler.cpp
diff --git a/tools/CrashHandler.cpp b/tools/CrashHandler.cpp
index cd104a6859cc67c96ebc6de767e986128dc2f446..a82d14656854f1d804c169bd7f7ca7e367b9c8c3 100644
--- a/tools/CrashHandler.cpp
+++ b/tools/CrashHandler.cpp
@@ -2,9 +2,7 @@
#include "SkTypes.h"
-#include <stdio.h>
#include <stdlib.h>
-#include <signal.h>
#if defined(SK_BUILD_FOR_MAC)
@@ -20,7 +18,7 @@ static void handler(int sig) {
unw_cursor_t cursor;
unw_init_local(&cursor, &context);
- fprintf(stderr, "\nSignal %d:\n", sig);
+ SkDebugf("\nSignal %d:\n", sig);
while (unw_step(&cursor) > 0) {
static const size_t kMax = 256;
char mangled[kMax], demangled[kMax];
@@ -31,12 +29,12 @@ static void handler(int sig) {
size_t len = kMax;
abi::__cxa_demangle(mangled, demangled, &len, &ok);
- fprintf(stderr, "%s (+0x%zx)\n", ok == 0 ? demangled : mangled, (size_t)offset);
+ SkDebugf("%s (+0x%zx)\n", ok == 0 ? demangled : mangled, (size_t)offset);
}
- fprintf(stderr, "\n");
+ SkDebugf("\n");
// Exit NOW. Don't notify other threads, don't call anything registered with atexit().
- _Exit(sig);
+ _exit(sig);
}
#elif defined(SK_BUILD_FOR_UNIX) && !defined(SK_BUILD_FOR_NACL) // NACL doesn't have backtrace().
@@ -50,16 +48,17 @@ static void handler(int sig) {
void* stack[kMax];
const int count = backtrace(stack, kMax);
- fprintf(stderr, "\nSignal %d:\n", sig);
+ SkDebugf("\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);
+ _exit(sig);
}
#endif
#if defined(SK_BUILD_FOR_MAC) || (defined(SK_BUILD_FOR_UNIX) && !defined(SK_BUILD_FOR_NACL))
+#include <signal.h>
void SetupCrashHandler() {
static const int kSignals[] = {
@@ -79,7 +78,77 @@ void SetupCrashHandler() {
}
}
-// TODO: #elif defined(SK_BUILD_FOR_WIN) when I find a Windows machine to work from.
+#elif defined(SK_BUILD_FOR_WIN)
+
+#include <DbgHelp.h>
+
+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 _
+};
+
+static LONG WINAPI handler(EXCEPTION_POINTERS* e) {
+ const DWORD code = e->ExceptionRecord->ExceptionCode;
+ SkDebugf("\nCaught exception %u", code);
+ for (size_t i = 0; i < SK_ARRAY_COUNT(kExceptions); i++) {
+ if (kExceptions[i].code == code) {
+ SkDebugf(" %s", kExceptions[i].name);
+ }
+ }
+ SkDebugf("\n");
+
+ CONTEXT* c = e->ContextRecord;
+
+ HANDLE hProcess = GetCurrentProcess();
+ SymInitialize(hProcess, 0, true);
+ STACKFRAME64 frame;
+ sk_bzero(&frame, sizeof(frame));
+
+ frame.AddrPC.Offset = c->Eip;
bungeman-skia 2014/06/18 22:28:28 CONTEXT is a completely different struct on x86 an
+ frame.AddrPC.Mode = AddrModeFlat;
+ frame.AddrStack.Offset = c->Esp;
+ frame.AddrStack.Mode = AddrModeFlat;
+ frame.AddrFrame.Offset = c->Ebp;
+ frame.AddrFrame.Mode = AddrModeFlat;
+
+ while (StackWalk64(sizeof(void*) == 4 ? IMAGE_FILE_MACHINE_I386 : IMAGE_FILE_MACHINE_AMD64,
bungeman-skia 2014/06/18 22:28:28 Because it's what we're actually after here, we sh
+ GetCurrentProcess(),
+ GetCurrentThread(),
+ &frame,
+ c,
+ NULL,
+ SymFunctionTableAccess64,
+ SymGetModuleBase64,
+ NULL)) {
+ DWORD64 offset;
+ static const int kMaxNameLength = 1024;
+ uint8_t buffer[sizeof(IMAGEHLP_SYMBOL64) + kMaxNameLength];
+ sk_bzero(buffer, sizeof(buffer));
+ IMAGEHLP_SYMBOL64* symbol = reinterpret_cast<IMAGEHLP_SYMBOL64*>(&buffer);
+ symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
+ symbol->MaxNameLength = kMaxNameLength - 1;
+ SymGetSymFromAddr64(hProcess, frame.AddrPC.Offset, &offset, symbol);
+ SkDebugf("%s +%x\n", symbol->Name, offset);
+ }
+
+ // Exit NOW. Don't notify other threads, don't call anything registered with atexit().
+ _exit(1);
+
+ // The compiler wants us to return something. This is what we'd do if we didn't _exit().
+ return EXCEPTION_EXECUTE_HANDLER;
+}
+
+void SetupCrashHandler() {
+ SetUnhandledExceptionFilter(handler);
+}
#else
« no previous file with comments | « include/core/SkPostConfig.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698