From: Cloudwalk Date: Sat, 17 Apr 2021 17:14:38 +0000 (-0400) Subject: sys_sdl: Implement a basic segfault handler X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=refs%2Fheads%2FCloudwalk%2Fcrash-handler;p=xonotic%2Fdarkplaces.git sys_sdl: Implement a basic segfault handler --- diff --git a/sys_sdl.c b/sys_sdl.c index 50cca9d9..7a893917 100644 --- a/sys_sdl.c +++ b/sys_sdl.c @@ -7,6 +7,7 @@ #include #include #include +#include #endif #ifdef __ANDROID__ @@ -14,6 +15,7 @@ #endif #include +#include #include @@ -66,6 +68,60 @@ void Sys_Error (const char *error, ...) exit (1); } +static const char *segfault_witty_comments[] = +{ + "Oh no!", + "It's gonna be okay.", + "Oops...", + "I'm sorry :(", + "Ooh that's gotta hurt.", + "I wish there was more I could do.", + "I blame Cloudwalk.", + "I blame LadyHavoc.", + "I blame divVerent.", + "Hi, I'm Null Pointer. Welcome to Jackass!", + "I meant to do that!", + "Ow.", + "Totally not copying that one voxel game with these witty comments.", + NULL +}; + +static const int segfault_witty_max = 12; +static qbool segfaulted = false; + +static void Sys_HandleSegfault(int signal) +{ + void *bt[20]; + char **btstrings; + char crash_report[32768]; + int numptrs, i, j; + time_t t; + struct tm t2; + + if(signal != SIGSEGV) + Sys_Error("Sys_HandleSegfault: Called without SIGSEGV?!"); + + if(segfaulted) + exit(1); + + segfaulted = true; + + srand(time(0)); + + t = time(NULL); + t2 = *localtime(&t); + + numptrs = backtrace(bt, 20); + btstrings = backtrace_symbols(bt, numptrs); + + j = dpsnprintf(crash_report, sizeof(crash_report), "DarkPlaces Crash Report -- %d-%02d-%02d %02d:%02d:%02d\n\n// %s\n\nBacktrace:\n", t2.tm_year + 1900, t2.tm_mon + 1, t2.tm_mday, t2.tm_hour, t2.tm_min, t2.tm_sec, segfault_witty_comments[rand() % (segfault_witty_max + 1)]); + + for(i = 0; i < numptrs && j != -1; i++) + j += dpsnprintf(&crash_report[j], sizeof(crash_report) - j, "%s\n", btstrings[i]); + + Sys_Error("DarkPlaces has crashed. Please report this to a developer.\n\n--CUT HERE--\n%s\n--CUT HERE--", crash_report); +} + void Sys_PrintToTerminal(const char *text) { #ifdef __ANDROID__ @@ -181,6 +237,8 @@ void Sys_InitConsole (void) int main (int argc, char *argv[]) { + struct sigaction sa; + signal(SIGFPE, SIG_IGN); #ifdef __ANDROID__ @@ -191,6 +249,11 @@ int main (int argc, char *argv[]) sys.argc = argc; sys.argv = (const char **)argv; + sa.sa_flags = SA_NODEFER; + sa.sa_handler = Sys_HandleSegfault; + + sigaction(SIGSEGV, &sa, NULL); + // Sys_Error this early in startup might screw with automated // workflows or something if we show the dialog by default. nocrashdialog = true;