diff --git a/code/sys/CMakeLists.txt b/code/sys/CMakeLists.txt index ed9f31d0..0ec654ed 100644 --- a/code/sys/CMakeLists.txt +++ b/code/sys/CMakeLists.txt @@ -44,6 +44,7 @@ target_link_libraries(syslib INTERFACE qcommon) if(WIN32) target_link_libraries(syslib INTERFACE wsock32 ws2_32) target_link_libraries(syslib INTERFACE winmm) + target_link_libraries(syslib INTERFACE dbghelp) elseif(UNIX) find_package(Threads) target_link_libraries(syslib INTERFACE ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) diff --git a/code/sys/new/sys_unix_new.c b/code/sys/new/sys_unix_new.c index 023e9429..3939fd30 100644 --- a/code/sys/new/sys_unix_new.c +++ b/code/sys/new/sys_unix_new.c @@ -49,14 +49,18 @@ Sys_PrintBackTrace ================== */ void Sys_PrintBackTrace() { - void* backtrace_arr[64]; + void* backtrace_arr[128]; + char** backtrace_symbols_arr; size_t backtrace_size; + size_t i; - printf("----\nBacktrace:\n"); - // get void*'s for all entries on the stack - backtrace_size = backtrace(backtrace_arr, sizeof(backtrace_arr) / sizeof(backtrace_arr[0])); - backtrace_symbols_fd(backtrace_arr, backtrace_size, STDERR_FILENO); - printf("----\n"); + // Fetch the backtrace starting from the current function + backtrace_size = backtrace(backtrace_arr, ARRAY_LEN(backtrace_arr)); + backtrace_symbols_arr = backtrace_symbols(backtrace_arr, ARRAY_LEN(backtrace_arr)); + + for (i = 0; i < backtrace_size; i++) { + fprintf(stderr, "=> %s\n", backtrace_symbols_arr[i]); + } } /* diff --git a/code/sys/new/sys_win32_new.c b/code/sys/new/sys_win32_new.c index afdc01dd..ea581328 100644 --- a/code/sys/new/sys_win32_new.c +++ b/code/sys/new/sys_win32_new.c @@ -23,6 +23,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "../sys_local.h" #include +#include + #ifdef _MSC_VER # ifdef _DEBUG_MEM # include @@ -51,6 +53,34 @@ Sys_PrintBackTrace ============== */ void Sys_PrintBackTrace() { + void* backtrace[128]; + SYMBOL_INFO* symbol; + HANDLE hProcess; + unsigned int i; + unsigned short frames; + + hProcess = GetCurrentProcess(); + + // Initialize the symbol handler + SymInitialize(hProcess, NULL, TRUE); + + // Gather the list of frames + frames = CaptureStackBackTrace(0, ARRAY_LEN(backtrace), backtrace, NULL); + // Allocate a symbol structure to get the name of each symbol + // with a maximum of 127 characters per symbol + symbol = (SYMBOL_INFO*)malloc(sizeof(SYMBOL_INFO) + 128 * sizeof(char)); + symbol->MaxNameLen = 127; + symbol->SizeOfStruct = sizeof(SYMBOL_INFO); + + for (i = 0; i < frames; i++) + { + // Try to translate the address to a symbol with a name + SymFromAddr(hProcess, (DWORD64)(backtrace[i]), 0, symbol); + + fprintf(stderr, "=> %s[0x%p]\n", symbol->Name, (void*)symbol->Address); + } + + free(symbol); } /* diff --git a/code/sys/sys_main.c b/code/sys/sys_main.c index db1fd2cc..74939be8 100644 --- a/code/sys/sys_main.c +++ b/code/sys/sys_main.c @@ -715,7 +715,7 @@ char *Sys_ParseProtocolUri( const char *uri ) Sys_SigHandler ================= */ -void Sys_SigHandler( int signal ) +void Sys_SigHandler( int signum ) { static qboolean signalcaught = qfalse; @@ -727,7 +727,13 @@ void Sys_SigHandler( int signal ) else { signalcaught = qtrue; - Sys_PrintBackTrace(); + + printf("----\nBacktrace:\n"); + Sys_PrintBackTrace(); + printf("----\n"); + // Call the default signal handler to generate a core dump + SIG_DFL(signum); + VM_Forced_Unload_Start(); #ifndef DEDICATED CL_Shutdown(va("Received signal %d", signal), qtrue, qtrue);