Properly print the backtrace and generate a core dump on both Windows/Unix

This commit is contained in:
smallmodel 2024-11-19 21:45:49 +01:00
parent 862af012cb
commit 01dfbcdbfe
No known key found for this signature in database
GPG key ID: 9F2D623CEDF08512
4 changed files with 49 additions and 8 deletions

View file

@ -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})

View file

@ -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]);
}
}
/*

View file

@ -23,6 +23,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "../sys_local.h"
#include <Windows.h>
#include <dbghelp.h>
#ifdef _MSC_VER
# ifdef _DEBUG_MEM
# include <crtdbg.h>
@ -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);
}
/*

View file

@ -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);