print out call stacks on crashes

This commit is contained in:
Nikita Smith
2025-11-07 14:39:46 -08:00
committed by Ryan Fleury
parent 69fe51ec94
commit b00d3d9041
3 changed files with 74 additions and 4 deletions
+2 -2
View File
@@ -19,12 +19,12 @@ git_hash=$(git describe --always --dirty)
git_hash_full=$(git rev-parse HEAD) git_hash_full=$(git rev-parse HEAD)
# --- Compile/Link Line Definitions ------------------------------------------- # --- Compile/Link Line Definitions -------------------------------------------
clang_common="-I../src/ -I/usr/include/freetype2/ -I../local/ -g -DBUILD_GIT_HASH=\"$git_hash\" -DBUILD_GIT_HASH_FULL=\"$git_hash_full\" -Wno-unknown-warning-option -fdiagnostics-absolute-paths -Wall -Wno-missing-braces -Wno-unused-function -Wno-writable-strings -Wno-unused-value -Wno-unused-variable -Wno-unused-local-typedef -Wno-deprecated-register -Wno-deprecated-declarations -Wno-unused-but-set-variable -Wno-single-bit-bitfield-constant-conversion -Wno-compare-distinct-pointer-types -Wno-initializer-overrides -Wno-incompatible-pointer-types-discards-qualifiers -Wno-for-loop-analysis -Xclang -flto-visibility-public-std -D_USE_MATH_DEFINES -Dstrdup=_strdup -Dgnu_printf=printf" clang_common="-I../src/ -I/usr/include/freetype2/ -I../local/ -D_GNU_SOURCE -g -DBUILD_GIT_HASH=\"$git_hash\" -DBUILD_GIT_HASH_FULL=\"$git_hash_full\" -Wno-unknown-warning-option -fdiagnostics-absolute-paths -Wall -Wno-missing-braces -Wno-unused-function -Wno-writable-strings -Wno-unused-value -Wno-unused-variable -Wno-unused-local-typedef -Wno-deprecated-register -Wno-deprecated-declarations -Wno-unused-but-set-variable -Wno-single-bit-bitfield-constant-conversion -Wno-compare-distinct-pointer-types -Wno-initializer-overrides -Wno-incompatible-pointer-types-discards-qualifiers -Wno-for-loop-analysis -Xclang -flto-visibility-public-std -D_USE_MATH_DEFINES -Dstrdup=_strdup -Dgnu_printf=printf"
clang_debug="$compiler -g -O0 -DBUILD_DEBUG=1 ${clang_common} ${auto_compile_flags}" clang_debug="$compiler -g -O0 -DBUILD_DEBUG=1 ${clang_common} ${auto_compile_flags}"
clang_release="$compiler -g -O2 -DBUILD_DEBUG=0 ${clang_common} ${auto_compile_flags}" clang_release="$compiler -g -O2 -DBUILD_DEBUG=0 ${clang_common} ${auto_compile_flags}"
clang_link="-lpthread -lm -lrt -ldl" clang_link="-lpthread -lm -lrt -ldl"
clang_out="-o" clang_out="-o"
gcc_common="-I../src/ -I../local/ -g -DBUILD_GIT_HASH=\"$git_hash\" -DBUILD_GIT_HASH_FULL=\"$git_hash_full\" -Wno-unknown-warning-option -Wall -Wno-missing-braces -Wno-unused-function -Wno-attributes -Wno-unused-value -Wno-unused-variable -Wno-unused-local-typedef -Wno-deprecated-declarations -Wno-unused-but-set-variable -Wno-compare-distinct-pointer-types -D_USE_MATH_DEFINES -Dstrdup=_strdup -Dgnu_printf=printf" gcc_common="-I../src/ -I../local/ -g -D_GNU_SOURCE -DBUILD_GIT_HASH=\"$git_hash\" -DBUILD_GIT_HASH_FULL=\"$git_hash_full\" -Wno-unknown-warning-option -Wall -Wno-missing-braces -Wno-unused-function -Wno-attributes -Wno-unused-value -Wno-unused-variable -Wno-unused-local-typedef -Wno-deprecated-declarations -Wno-unused-but-set-variable -Wno-compare-distinct-pointer-types -D_USE_MATH_DEFINES -Dstrdup=_strdup -Dgnu_printf=printf"
gcc_debug="$compiler -g -O0 -DBUILD_DEBUG=1 ${gcc_common} ${auto_compile_flags}" gcc_debug="$compiler -g -O0 -DBUILD_DEBUG=1 ${gcc_common} ${auto_compile_flags}"
gcc_release="$compiler -g -O2 -DBUILD_DEBUG=0 ${gcc_common} ${auto_compile_flags}" gcc_release="$compiler -g -O2 -DBUILD_DEBUG=0 ${gcc_common} ${auto_compile_flags}"
gcc_link="-lpthread -lm -lrt -ldl" gcc_link="-lpthread -lm -lrt -ldl"
+69
View File
@@ -1399,9 +1399,78 @@ os_make_guid(void)
//////////////////////////////// ////////////////////////////////
//~ rjf: @os_hooks Entry Points (Implemented Per-OS) //~ rjf: @os_hooks Entry Points (Implemented Per-OS)
internal void
lnx_signal_handler(int sig, siginfo_t *info, void *arg)
{
local_persist volatile U32 first = 0;
if (ins_atomic_u32_eval_cond_assign(&first, 1, 0) != 0)
{
for(;;)
{
sleep(UINT32_MAX);
}
}
local_persist void *ips[4096];
int ips_count = backtrace(ips, ArrayCount(ips));
fprintf(stderr, "A fatal signal was received: %s (%d). The process is terminating.\n", strsignal(sig), sig);
fprintf(stderr, "Create a new issue with this report at %s.\n\n", BUILD_ISSUES_LINK_STRING_LITERAL);
fprintf(stderr, "Callstack:\n");
for EachIndex(i, ips_count)
{
Dl_info info = {0};
dladdr(ips[i], &info);
char cmd[2048];
snprintf(cmd, sizeof(cmd), "llvm-symbolizer --relative-address -f -e %s %lu", info.dli_fname, (unsigned long)ips[i] - (unsigned long)info.dli_fbase);
FILE *f = popen(cmd, "r");
if(f)
{
char func_name[256], file_name[256];
if(fgets(func_name, sizeof(func_name), f) && fgets(file_name, sizeof(file_name), f))
{
String8 func = str8_cstring(func_name);
if(func.size > 0) func.size -= 1;
String8 module = str8_skip_last_slash(str8_cstring(info.dli_fname));
String8 file = str8_skip_last_slash(str8_cstring_capped(file_name, file_name + sizeof(file_name)));
if(file.size > 0) file.size -= 1;
B32 no_func = str8_match(func, str8_lit("??"), StringMatchFlag_RightSideSloppy);
B32 no_file = str8_match(file, str8_lit("??"), StringMatchFlag_RightSideSloppy);
if(no_func) { func = str8_zero(); }
if(no_file) { file = str8_zero(); }
fprintf(stderr, "%ld. [0x%016lx] %.*s%s%.*s %.*s\n", i+1, (unsigned long)ips[i], (int)module.size, module.str, (!no_func || !no_file) ? ", " : "", (int)func.size, func.str, (int)file.size, file.str);
}
pclose(f);
}
else
{
fprintf(stderr, "%ld. [0x%016lx] %s\n", i+1, (unsigned long)ips[i], info.dli_fname);
}
}
fprintf(stderr, "\nVersion: %s%s\n\n", BUILD_VERSION_STRING_LITERAL, BUILD_GIT_HASH_STRING_LITERAL_APPEND);
_exit(0);
}
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
// install signal handler for the crash call stacks
{
struct sigaction handler = { .sa_sigaction = lnx_signal_handler, .sa_flags = SA_SIGINFO, };
sigfillset(&handler.sa_mask);
sigaction(SIGILL, &handler, NULL);
sigaction(SIGTRAP, &handler, NULL);
sigaction(SIGABRT, &handler, NULL);
sigaction(SIGFPE, &handler, NULL);
sigaction(SIGBUS, &handler, NULL);
sigaction(SIGSEGV, &handler, NULL);
sigaction(SIGQUIT, &handler, NULL);
}
//- rjf: set up OS layer //- rjf: set up OS layer
{ {
//- rjf: get statically-allocated system/process info //- rjf: get statically-allocated system/process info
+3 -2
View File
@@ -7,7 +7,6 @@
//////////////////////////////// ////////////////////////////////
//~ rjf: Includes //~ rjf: Includes
#define _GNU_SOURCE
#include <dirent.h> #include <dirent.h>
#include <dlfcn.h> #include <dlfcn.h>
#include <errno.h> #include <errno.h>
@@ -17,6 +16,7 @@
#include <pthread.h> #include <pthread.h>
#include <semaphore.h> #include <semaphore.h>
#include <signal.h> #include <signal.h>
#include <spawn.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/random.h> #include <sys/random.h>
@@ -27,7 +27,8 @@
#include <sys/types.h> #include <sys/types.h>
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#include <spawn.h> #include <execinfo.h>
#include <dlfcn.h>
pid_t gettid(void); pid_t gettid(void);
int pthread_setname_np(pthread_t thread, const char *name); int pthread_setname_np(pthread_t thread, const char *name);