@@ -1399,9 +1399,78 @@ os_make_guid(void)
13991399////////////////////////////////
14001400//~ rjf: @os_hooks Entry Points (Implemented Per-OS)
14011401
1402+ internal void
1403+ lnx_signal_handler (int sig , siginfo_t * info , void * arg )
1404+ {
1405+ local_persist volatile U32 first = 0 ;
1406+ if (ins_atomic_u32_eval_cond_assign (& first , 1 , 0 ) != 0 )
1407+ {
1408+ for (;;)
1409+ {
1410+ sleep (UINT32_MAX );
1411+ }
1412+ }
1413+
1414+ local_persist void * ips [4096 ];
1415+ int ips_count = backtrace (ips , ArrayCount (ips ));
1416+
1417+ fprintf (stderr , "A fatal signal was received: %s (%d). The process is terminating.\n" , strsignal (sig ), sig );
1418+ fprintf (stderr , "Create a new issue with this report at %s.\n\n" , BUILD_ISSUES_LINK_STRING_LITERAL );
1419+ fprintf (stderr , "Callstack:\n" );
1420+ for EachIndex (i , ips_count )
1421+ {
1422+ Dl_info info = {0 };
1423+ dladdr (ips [i ], & info );
1424+
1425+ char cmd [2048 ];
1426+ snprintf (cmd , sizeof (cmd ), "llvm-symbolizer --relative-address -f -e %s %lu" , info .dli_fname , (unsigned long )ips [i ] - (unsigned long )info .dli_fbase );
1427+ FILE * f = popen (cmd , "r" );
1428+ if (f )
1429+ {
1430+ char func_name [256 ], file_name [256 ];
1431+ if (fgets (func_name , sizeof (func_name ), f ) && fgets (file_name , sizeof (file_name ), f ))
1432+ {
1433+ String8 func = str8_cstring (func_name );
1434+ if (func .size > 0 ) func .size -= 1 ;
1435+ String8 module = str8_skip_last_slash (str8_cstring (info .dli_fname ));
1436+ String8 file = str8_skip_last_slash (str8_cstring_capped (file_name , file_name + sizeof (file_name )));
1437+ if (file .size > 0 ) file .size -= 1 ;
1438+
1439+ B32 no_func = str8_match (func , str8_lit ("??" ), StringMatchFlag_RightSideSloppy );
1440+ B32 no_file = str8_match (file , str8_lit ("??" ), StringMatchFlag_RightSideSloppy );
1441+ if (no_func ) { func = str8_zero (); }
1442+ if (no_file ) { file = str8_zero (); }
1443+
1444+ 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 );
1445+ }
1446+ pclose (f );
1447+ }
1448+ else
1449+ {
1450+ fprintf (stderr , "%ld. [0x%016lx] %s\n" , i + 1 , (unsigned long )ips [i ], info .dli_fname );
1451+ }
1452+ }
1453+ fprintf (stderr , "\nVersion: %s%s\n\n" , BUILD_VERSION_STRING_LITERAL , BUILD_GIT_HASH_STRING_LITERAL_APPEND );
1454+
1455+ _exit (0 );
1456+ }
1457+
14021458int
14031459main (int argc , char * * argv )
14041460{
1461+ // install signal handler for the crash call stacks
1462+ {
1463+ struct sigaction handler = { .sa_sigaction = lnx_signal_handler , .sa_flags = SA_SIGINFO , };
1464+ sigfillset (& handler .sa_mask );
1465+ sigaction (SIGILL , & handler , NULL );
1466+ sigaction (SIGTRAP , & handler , NULL );
1467+ sigaction (SIGABRT , & handler , NULL );
1468+ sigaction (SIGFPE , & handler , NULL );
1469+ sigaction (SIGBUS , & handler , NULL );
1470+ sigaction (SIGSEGV , & handler , NULL );
1471+ sigaction (SIGQUIT , & handler , NULL );
1472+ }
1473+
14051474 //- rjf: set up OS layer
14061475 {
14071476 //- rjf: get statically-allocated system/process info
0 commit comments