diff --git a/interop/src/cpp/common-interop.cc b/interop/src/cpp/common-interop.cc index 64a6595f67dc520a09b99976277bc5d27d92eb8f..26ca369a453b43f3136750e572dbef9bcaf4922e 100644 --- a/interop/src/cpp/common-interop.cc +++ b/interop/src/cpp/common-interop.cc @@ -19,6 +19,7 @@ #include "common-interop.h" #include "interop-logging.h" #include "dynamic-loader.h" +#include "crashdump.h" #if KOALA_INTEROP_PROFILER #include "profiler.h" @@ -296,3 +297,16 @@ void impl_NativeLog(const KStringPtr& str) { #endif } KOALA_INTEROP_V1(NativeLog, KStringPtr) + +void impl_InstallCrashHandlers() { + installCrashHandlers(); +} +KOALA_INTEROP_V0(InstallCrashHandlers) + +#if 0 +// Enable this code if you need to debug early crashes. +__attribute__((constructor)) +static void installCrashHandlersAtStartup() { + installCrashHandlers(); +} +#endif \ No newline at end of file diff --git a/interop/src/cpp/crashdump.h b/interop/src/cpp/crashdump.h index 128f7ba61715fd378f73511dede93f01cd38b7ec..96cbc06cbae875f7ff95b83e887513681aa6ccdb 100644 --- a/interop/src/cpp/crashdump.h +++ b/interop/src/cpp/crashdump.h @@ -20,19 +20,30 @@ #include #include -sighandler_t oldCrashHandler = nullptr; +static sighandler_t oldCrashHandlers[16] = { 0 }; static void onCrashHandler(int signo) { void* stack[20]; size_t size = backtrace(stack, 20); + fprintf(stderr, "FATAL: crash with signal %d\n", signo); backtrace_symbols_fd(stack, size, STDERR_FILENO); - if (oldCrashHandler) oldCrashHandler(signo); + if (signo < 16 && + oldCrashHandlers[signo] && + oldCrashHandlers[signo] != SIG_IGN && + oldCrashHandlers[signo] != SIG_DFL) { + oldCrashHandlers[signo](signo); + } else { + fprintf(stderr, "aborting\n"); + abort(); + } } static void installCrashHandlers() { static bool installed = false; if (!installed) { - oldCrashHandler = signal(SIGSEGV, onCrashHandler); + oldCrashHandlers[SIGSEGV] = signal(SIGSEGV, onCrashHandler); + oldCrashHandlers[SIGBUS] = signal(SIGBUS, onCrashHandler); + oldCrashHandlers[SIGILL] = signal(SIGILL, onCrashHandler); installed = true; } }