/* * Apple // emulator for *ix * * This software package is subject to the GNU General Public License * version 3 or later (your choice) as published by the Free Software * Foundation. * * Copyright 2013-2015 Aaron Culliney * */ // Breakpad crash handling #if !defined(__cplusplus) #error Breakpad requires C++ #endif #include "common.h" #include "client/linux/handler/exception_handler.h" #if EMBEDDED_STACKWALKER # include "processor/stackwalk_common.h" #endif static CrashHandler_s breakpadHandler = { 0 }; static google_breakpad::ExceptionHandler *eh = nullptr; static bool dumpCallback(const google_breakpad::MinidumpDescriptor& descriptor, void* context, bool succeeded) { // WARNING : should only do minimal work from within a crashing context ... LOG("Dump path: %s", descriptor.path()); return succeeded; } extern "C" { static void initBreakpadHandler(const char *dumpDir) { LOG("Initializing Breakpad with dump dir : %s", dumpDir); google_breakpad::MinidumpDescriptor descriptor(dumpDir); eh = new google_breakpad::ExceptionHandler(descriptor, NULL, dumpCallback, NULL, true, -1); } __attribute__((destructor(255))) static void shutdownBreakpadHandler(void) { if (eh) { delete eh; eh = nullptr; LOG("Unregistering Breakpad..."); } } static bool processCrashWithBreakpad(const char *crash, const char *symbolsPath, const FILE *outputFile) { #if EMBEDDED_STACKWALKER LOG("Running breakpad stackwalker on crash ..."); stackwalker_setOutputFile(outputFile); int err = stackwalker_main(crash, symbolsPath, /*machineReadable:*/true); stackwalker_setOutputFile(NULL); return err == 0; #else #warning NOT COMPILING WITH EMBEDDED STACKWALKER return false; #endif } __attribute__((constructor(CTOR_PRIORITY_EARLY))) static void _breakpad_registration(void) { LOG("Registering Breakpad as native crash handler"); breakpadHandler.init = &initBreakpadHandler; breakpadHandler.shutdown = &shutdownBreakpadHandler; breakpadHandler.processCrash = &processCrashWithBreakpad; crashHandler = &breakpadHandler; } }