Add cpptrace in I_Error on windows, minidumps, stricter warnings, optimized drawers in debug

This commit is contained in:
Eidolon 2025-09-21 14:08:15 -05:00
parent c1b22c0c73
commit 94ef03dcd2
11 changed files with 294 additions and 99 deletions

View file

@ -125,6 +125,9 @@ find_package(PNG REQUIRED)
find_package(SDL2 CONFIG REQUIRED)
find_package(CURL REQUIRED)
find_package(Opus REQUIRED)
if(WIN32 AND NOT MINGW)
find_package(cpptrace CONFIG REQUIRED)
endif()
# Use the one in thirdparty/fmt to guarantee a minimum version
#find_package(FMT CONFIG REQUIRED)

View file

@ -54,8 +54,8 @@
"name": "__develop-cl",
"hidden": true,
"cacheVariables": {
"CMAKE_C_FLAGS_RELWITHDEBINFO": "/MD /O2 /Ob2 /DNDEBUG",
"CMAKE_CXX_FLAGS_RELWITHDEBINFO": "/MD /O2 /Ob2 /DNDEBUG",
"CMAKE_C_FLAGS_RELWITHDEBINFO": "/MD /Zi /O2 /Ob2 /DNDEBUG",
"CMAKE_CXX_FLAGS_RELWITHDEBINFO": "/MD /Zi /O2 /Ob2 /DNDEBUG",
"SRB2_CONFIG_DEV_BUILD": "ON",
"CMAKE_BUILD_TYPE": "RelWithDebInfo"
}
@ -64,8 +64,8 @@
"name": "__release-cl",
"hidden": true,
"cacheVariables": {
"CMAKE_C_FLAGS_RELWITHDEBINFO": "/MD /O2 /Ob2 /DNDEBUG",
"CMAKE_CXX_FLAGS_RELWITHDEBINFO": "/MD /O2 /Ob2 /DNDEBUG",
"CMAKE_C_FLAGS_RELWITHDEBINFO": "/MD /Zi /O2 /Ob2 /DNDEBUG",
"CMAKE_CXX_FLAGS_RELWITHDEBINFO": "/MD /Zi /O2 /Ob2 /DNDEBUG",
"SRB2_CONFIG_DEV_BUILD": "OFF",
"CMAKE_BUILD_TYPE": "RelWithDebInfo"
}

View file

@ -176,6 +176,41 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
p_deepcopy.cpp
)
# Always compile some files with optimizations in Debug config.
# This is to make the debugging experience less slow for the majority of cases.
set(always_optimize_options "")
if(MSVC)
set(always_optimize_options "$<$<CONFIG:Debug>:/O2;/Ob2>")
else()
set(always_optimize_options "$<$<CONFIG:Debug>:-O3>")
endif()
set_source_files_properties(
r_bsp.cpp
r_data.c
r_debug.cpp
r_debug_parser.cpp
r_debug_printer.cpp
r_draw.cpp
r_fps.cpp
r_main.cpp
r_plane.cpp
r_segs.cpp
r_skins.c
r_sky.c
r_splats.c
r_spritefx.cpp
r_things.cpp
r_bbox.c
r_textures.cpp
r_textures_dups.cpp
r_patch.cpp
r_patchrotation.c
r_picformats.c
r_portal.c
PROPERTIES
COMPILE_OPTIONS "${always_optimize_options}"
)
set_target_properties(SRB2SDL2 PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/sdl/macosx/MacOSXBundleInfo.plist.in")
if(SRB2_CONFIG_ENABLE_WEBM_MOVIES)
@ -210,7 +245,7 @@ add_custom_target(_SRB2_reconf ALL
)
add_dependencies(SRB2SDL2 _SRB2_reconf)
if(("${CMAKE_COMPILER_IS_GNUCC}" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") AND "${CMAKE_SYSTEM_NAME}" MATCHES "Windows")
if(("${CMAKE_COMPILER_IS_GNUCC}") AND "${CMAKE_SYSTEM_NAME}" MATCHES "Windows")
target_link_options(SRB2SDL2 PRIVATE "-Wl,--disable-dynamicbase")
if("${SRB2_CONFIG_STATIC_STDLIB}")
# On MinGW with internal libraries, link the standard library statically
@ -224,8 +259,19 @@ if(("${CMAKE_COMPILER_IS_GNUCC}" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") AND
endif()
endif()
if(MSVC OR CMAKE_CXX_LINK_EXECUTABLE MATCHES "lld-link.exe")
if(MSVC OR CMAKE_CXX_LINK_EXECUTABLE MATCHES "lld-link\\.exe")
target_link_options(SRB2SDL2 PRIVATE /MANIFEST:NO)
target_link_libraries(SRB2SDL2 PRIVATE "dbghelp")
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND MSVC)
# Stuff to make paths not include the builder's file system paths on clang-cl
string(REPLACE "/" "\\" backslashes_cmake_source_dir "${CMAKE_SOURCE_DIR}")
target_compile_options(SRB2SDL2 PRIVATE "$<$<CONFIG:RelWithDebInfo,Release>:/clang:-fdebug-prefix-map=${CMAKE_SOURCE_DIR}=X:/ringracers>")
target_compile_options(SRB2SDL2 PRIVATE "$<$<CONFIG:RelWithDebInfo,Release>:/clang:-fdebug-prefix-map=${backslashes_cmake_source_dir}=X:/ringracers>")
target_compile_options(SRB2SDL2 PRIVATE "$<$<CONFIG:RelWithDebInfo,Release>:/clang:-fdebug-compilation-dir=${CMAKE_SOURCE_DIR}>")
target_link_options(SRB2SDL2 PRIVATE "$<$<CONFIG:RelWithDebInfo,Release>:/pdbaltpath:%_PDB%>")
endif()
target_compile_features(SRB2SDL2 PRIVATE c_std_11 cxx_std_17)
@ -283,6 +329,10 @@ target_link_libraries(SRB2SDL2 PRIVATE ZLIB::ZLIB)
target_link_libraries(SRB2SDL2 PRIVATE PNG::PNG)
target_link_libraries(SRB2SDL2 PRIVATE CURL::libcurl)
target_link_libraries(SRB2SDL2 PRIVATE Opus::opus)
if(WIN32 AND NOT MINGW)
target_link_libraries(SRB2SDL2 PRIVATE cpptrace::cpptrace)
target_compile_definitions(SRB2SDL2 PRIVATE HAVE_CPPTRACE)
endif()
target_link_libraries(SRB2SDL2 PRIVATE ReNameNoise::renamenoise)
if("${CMAKE_SYSTEM_NAME}" MATCHES "FreeBSD")
target_link_libraries(SRB2SDL2 PRIVATE -lexecinfo)
@ -461,6 +511,7 @@ target_compile_options(SRB2SDL2 PRIVATE
# This is a direct translation from versions.mk
$<$<AND:$<COMPILE_LANGUAGE:C>,$<C_COMPILER_ID:GNU>>:
-Wall
-Werror-implicit-function-declaration
-Wno-trigraphs
-W # Was controlled by RELAXWARNINGS
-pedantic
@ -545,6 +596,7 @@ target_compile_options(SRB2SDL2 PRIVATE
$<$<AND:$<COMPILE_LANGUAGE:C>,$<OR:$<C_COMPILER_ID:AppleClang>,$<C_COMPILER_ID:Clang>>>:
#-Wall
-Werror=microsoft
-Werror=implicit-function-declaration
-Wreturn-type # Missing returns in non-void function
-Wduplicate-decl-specifier
-Wsometimes-uninitialized
@ -570,9 +622,14 @@ target_compile_options(SRB2SDL2 PRIVATE
# C++, GNU
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CXX_COMPILER_ID:GNU>>:
-Wall
-Wno-c++98-compat
-Wno-c++11-compat
-Wno-c++14-compat # No C++14 compat needed
-Werror=c++20-extensions
-Werror=c++23-extensions # Disallow newer language features entirely
>
# C++, GNU, Clang and Apple Clang
# C++, Clang and Apple Clang
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<OR:$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:Clang>>>:
#-Wall
-Werror=microsoft
@ -584,6 +641,8 @@ target_compile_options(SRB2SDL2 PRIVATE
-Wno-c++98-compat
-Wno-c++11-compat
-Wno-c++14-compat # No C++14 compat needed
-Werror=c++20-extensions
-Werror=c++23-extensions # Disallow newer language features entirely
-Wno-unused-but-set-variable # Setting unread variables is fine (nontrivial C++ types issue)
-Wno-misleading-indentation # Some cases in code currently
-Wno-deprecated-non-prototype # We have no intention of using C23 yet.
@ -594,6 +653,8 @@ target_compile_options(SRB2SDL2 PRIVATE
-Wno-unused-function
>
# C++, Clang and Apple Clang
# C++, MSVC
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CXX_COMPILER_ID:MSVC>>:
/Wv:19.20.27004.0

View file

@ -457,7 +457,7 @@ enum {
*/
void I_Error(const char *error, ...) FUNCIERROR;
FUNCIERROR void ATTRNORETURN I_Error(const char *error, ...);
/** \brief write a message to stderr (use before I_Quit) for when you need to quit with a msg, but need
the return code 0 of I_Quit();

View file

@ -92,7 +92,7 @@ void I_OsPolling(void);
/** \brief Called by M_Responder when quit is selected, return exit code 0
*/
void I_Quit(void) FUNCNORETURN;
FUNCNORETURN void ATTRNORETURN I_Quit(void);
typedef enum
{

View file

@ -29,7 +29,7 @@ menuitem_t OPTIONS_Voice[] =
NULL, srb2::itemaction(&cv_voice_inputamp), 0, 0},
{IT_STRING | IT_CVAR, "Input Noise Suppression", "Suppress background noise from your voice.",
NULL, {.cvar = &cv_voice_denoise}, 0, 0},
NULL, srb2::itemaction(&cv_voice_denoise), 0, 0},
{IT_STRING | IT_CVAR, "Input Sensitivity", "Voice higher than this threshold will transmit, in decibels.",
NULL, srb2::itemaction(&cv_voice_activationthreshold), 0, 0 },

View file

@ -11,6 +11,7 @@
#include "../doomdef.h"
#include "../doomstat.h"
#include "../info.h"
#include "../g_game.h"
#include "../k_objects.h"
#include "../p_local.h"
#include "../r_state.h"

View file

@ -732,8 +732,7 @@ void R_RenderMaskedSegRange(drawseg_t *drawseg, INT32 x1, INT32 x2)
template <typename T>
static constexpr T saturating_add(T x, T y) noexcept
{
INT64 z;
z = static_cast<INT64>(x) + static_cast<INT64>(y);
INT64 z = static_cast<INT64>(x) + static_cast<INT64>(y);
if (z > static_cast<INT64>(std::numeric_limits<T>::max()))
{
z = static_cast<INT64>(std::numeric_limits<T>::max());
@ -748,8 +747,7 @@ static constexpr T saturating_add(T x, T y) noexcept
template <typename T>
static constexpr T saturating_mul(T x, T y) noexcept
{
INT64 z;
z = static_cast<INT64>(x) * static_cast<INT64>(y);
INT64 z = static_cast<INT64>(x) * static_cast<INT64>(y);
if (z > static_cast<INT64>(std::numeric_limits<T>::max()))
{
z = static_cast<INT64>(std::numeric_limits<T>::max());

View file

@ -20,7 +20,6 @@
#include "../core/string.h"
#include <exception>
#include <stdexcept>
#include <tracy/tracy/Tracy.hpp>
@ -32,11 +31,7 @@
#include <errno.h>
#endif
extern "C" {
#include "time.h" // For log timestamps
}
#ifdef HAVE_SDL
#ifdef HAVE_TTF
#include "SDL.h"
@ -68,46 +63,6 @@ char logfilename[1024];
#endif
#endif
#if defined (_WIN32)
extern "C" {
#include "../win32/win_dbg.h"
}
typedef BOOL (WINAPI *p_IsDebuggerPresent)(VOID);
#endif
#if defined (_WIN32)
static inline VOID MakeCodeWritable(VOID)
{
#ifdef USEASM // Disable write-protection of code segment
DWORD OldRights;
const DWORD NewRights = PAGE_EXECUTE_READWRITE;
PBYTE pBaseOfImage = (PBYTE)GetModuleHandle(NULL);
PIMAGE_DOS_HEADER dosH =(PIMAGE_DOS_HEADER)pBaseOfImage;
PIMAGE_NT_HEADERS ntH = (PIMAGE_NT_HEADERS)(pBaseOfImage + dosH->e_lfanew);
PIMAGE_OPTIONAL_HEADER oH = (PIMAGE_OPTIONAL_HEADER)
((PBYTE)ntH + sizeof (IMAGE_NT_SIGNATURE) + sizeof (IMAGE_FILE_HEADER));
LPVOID pA = pBaseOfImage+oH->BaseOfCode;
SIZE_T pS = oH->SizeOfCode;
#if 1 // try to find the text section
PIMAGE_SECTION_HEADER ntS = IMAGE_FIRST_SECTION (ntH);
WORD s;
for (s = 0; s < ntH->FileHeader.NumberOfSections; s++)
{
if (memcmp (ntS[s].Name, ".text\0\0", 8) == 0)
{
pA = pBaseOfImage+ntS[s].VirtualAddress;
pS = ntS[s].Misc.VirtualSize;
break;
}
}
#endif
if (!VirtualProtect(pA,pS,NewRights,&OldRights))
I_Error("Could not make code writable\n");
#endif
}
#endif
#ifdef LOGMESSAGES
static void InitLogging(void)
{
@ -212,10 +167,6 @@ static void init_exchndl()
if (pfnExcHndlInit != NULL)
(pfnExcHndlInit)();
}
#else
static void init_exchndl()
{
}
#endif
#ifdef _WIN32
@ -300,25 +251,12 @@ int main(int argc, char **argv)
//I_OutputMsg("I_StartupSystem() ...\n");
I_StartupSystem();
#if defined (_WIN32)
#if defined (_WIN32) && !defined(_MSC_VER)
if (!M_CheckParm("-noexchndl"))
{
#if 0 // just load the DLL
p_IsDebuggerPresent pfnIsDebuggerPresent = (p_IsDebuggerPresent)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsDebuggerPresent");
if ((!pfnIsDebuggerPresent || !pfnIsDebuggerPresent())
#ifdef BUGTRAP
&& !InitBugTrap()
#endif
)
#endif
{
init_exchndl();
}
init_exchndl();
}
#ifndef __MINGW32__
prevExceptionFilter = SetUnhandledExceptionFilter(RecordExceptionInfo);
#endif
MakeCodeWritable();
#endif
try {
@ -353,8 +291,6 @@ int main(int argc, char **argv)
return 0;
}
#endif
#ifdef _MSC_VER
int WINAPI WinMain(HINSTANCE pInstance, HINSTANCE pPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{

View file

@ -39,6 +39,12 @@ typedef DWORD (WINAPI *p_timeGetTime) (void);
typedef UINT (WINAPI *p_timeEndPeriod) (UINT);
typedef HANDLE (WINAPI *p_OpenFileMappingA) (DWORD, BOOL, LPCSTR);
typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
#if defined(_WIN32) && !defined(__GNUC__)
#define USE_DBGHELP
#include <DbgHelp.h>
#endif
#endif
#include <stdio.h>
#include <stdlib.h>
@ -141,6 +147,10 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
#define UNIXBACKTRACE
#endif
#ifdef HAVE_CPPTRACE
#include <cpptrace/cpptrace.hpp>
#endif
// Locations for searching for bios.pk3
#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)
#define DEFAULTWADLOCATION1 "/usr/local/share/games/RingRacers"
@ -302,8 +312,10 @@ static void I_ShowErrorMessageBox(const char *messagefordevelopers, boolean dump
dumpmade ?
#if defined (UNIXBACKTRACE)
"crash-log.txt"
#elif defined (_WIN32)
#elif defined (_WIN32) && defined(__GNUC__)
".rpt crash dump"
#elif defined (USE_DBGHELP)
".dmp crash dump"
#endif
" (very important!) and " : "",
#ifdef LOGMESSAGES
@ -369,12 +381,83 @@ static void I_ShowErrorMessageBox(const char *messagefordevelopers, boolean dump
// in case the fullscreen window blocks it for some absurd reason.
}
static void I_ReportSignal(int num, int coredumped)
static void I_ReportSignal(int num, int coredumped, void* tracefromcpptrace)
{
//static char msg[] = "oh no! back to reality!\r\n";
const char * sigmsg;
char msg[128];
char msg[8192];
#ifdef USE_DBGHELP
// The signal code is a WIN32 exception code, not a libc signal
// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-exception_record
switch (num)
{
case EXCEPTION_ACCESS_VIOLATION:
sigmsg = "EXCEPTION_ACCESS_VIOLATION";
break;
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
sigmsg = "EXCEPTION_ARRAY_BOUNDS_EXCEEDED";
break;
case EXCEPTION_BREAKPOINT:
sigmsg = "EXCEPTION_BREAKPOINT";
break;
case EXCEPTION_DATATYPE_MISALIGNMENT:
sigmsg = "EXCEPTION_DATATYPE_MISALIGNMENT";
break;
case EXCEPTION_FLT_DENORMAL_OPERAND:
sigmsg = "EXCEPTION_FLT_DENORMAL_OPERAND";
break;
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
sigmsg = "EXCEPTION_FLT_DENORMAL_OPERAND";
break;
case EXCEPTION_FLT_INEXACT_RESULT:
sigmsg = "EXCEPTION_FLT_INEXACT_RESULT";
break;
case EXCEPTION_FLT_INVALID_OPERATION:
sigmsg = "EXCEPTION_FLT_INVALID_OPERATION";
break;
case EXCEPTION_FLT_OVERFLOW:
sigmsg = "EXCEPTION_FLT_OVERFLOW";
break;
case EXCEPTION_FLT_STACK_CHECK:
sigmsg = "EXCEPTION_FLT_STACK_CHECK";
break;
case EXCEPTION_FLT_UNDERFLOW:
sigmsg = "EXCEPTION_FLT_UNDERFLOW";
break;
case EXCEPTION_ILLEGAL_INSTRUCTION:
sigmsg = "EXCEPTION_ILLEGAL_INSTRUCTION";
break;
case EXCEPTION_IN_PAGE_ERROR:
sigmsg = "EXCEPTION_IN_PAGE_ERROR";
break;
case EXCEPTION_INT_DIVIDE_BY_ZERO:
sigmsg = "EXCEPTION_INT_DIVIDE_BY_ZERO";
break;
case EXCEPTION_INT_OVERFLOW:
sigmsg = "EXCEPTION_INT_OVERFLOW";
break;
case EXCEPTION_INVALID_DISPOSITION:
sigmsg = "EXCEPTION_INVALID_DISPOSITION";
break;
case EXCEPTION_NONCONTINUABLE_EXCEPTION:
sigmsg = "EXCEPTION_NONCONTINUABLE_EXCEPTION";
break;
case EXCEPTION_PRIV_INSTRUCTION:
sigmsg = "EXCEPTION_PRIV_INSTRUCTION";
break;
case EXCEPTION_SINGLE_STEP:
sigmsg = "EXCEPTION_SINGLE_STEP";
break;
case EXCEPTION_STACK_OVERFLOW:
sigmsg = "EXCEPTION_STACK_OVERFLOW";
break;
default:
sigmsg = "";
sprintf(msg, "unknown exception %d", num);
break;
}
#else
switch (num)
{
// case SIGINT:
@ -405,30 +488,132 @@ static void I_ReportSignal(int num, int coredumped)
else
sigmsg = msg;
}
#endif
if (sigmsg)
{
strcpy(msg, sigmsg);
}
if (coredumped)
{
if (sigmsg)
strcpy(msg, sigmsg);
strcat(msg, " (core dumped)");
sigmsg = msg;
}
#ifdef HAVE_CPPTRACE
strncat(msg, "\n", sizeof(msg) - strlen(msg) - 1);
cpptrace::stacktrace const& trace = *(cpptrace::stacktrace*)tracefromcpptrace;
bool firstfound = false;
#ifndef _WIN32
firstfound = true;
#endif
for (const auto& frame : trace)
{
#ifdef _WIN32
// dumb hack, unsure if it works on anything other than windows 10-11
if (!firstfound && frame.symbol == "KiUserExceptionDispatcher")
{
firstfound = true;
continue;
}
if (!firstfound)
{
continue;
}
#endif
srb2::String frame_str;
if (!frame.filename.empty() && frame.line.has_value())
{
frame_str = srb2::format("{} at {}:{}\n", frame.symbol, frame.filename, frame.line.value_or(0));
}
else if (!frame.filename.empty() && !frame.line.has_value())
{
frame_str = srb2::format("{} at {}\n", frame.symbol, frame.filename);
}
else
{
frame_str = srb2::format("{}\n", frame.symbol);
}
strncat(msg, frame_str.c_str(), sizeof(msg) - strlen(msg) - 1);
}
#endif
sigmsg = msg;
I_OutputMsg("\nProcess killed by signal: %s\n\n", sigmsg);
I_ShowErrorMessageBox(sigmsg,
#if defined (UNIXBACKTRACE)
true
#elif defined (_WIN32)
#elif defined (_WIN32) && defined (__GNUC__)
!M_CheckParm("-noexchndl")
#elif defined (USE_DBGHELP)
true
#else
false
#endif
);
}
#ifndef NEWSIGNALHANDLER
#if !defined(NEWSIGNALHANDLER) || defined(USE_DBGHELP)
static void CommonSignalHandleCleanup(void)
{
D_QuitNetGame(); // Fix server freezes
CL_AbortDownloadResume();
G_DirtyGameData();
}
#endif
#ifdef USE_DBGHELP
LPTOP_LEVEL_EXCEPTION_FILTER g_previous_toplevelexceptionfilter;
static LONG WriteMinidumpExceptionFilter(PEXCEPTION_POINTERS ExceptionInfo)
{
#ifdef HAVE_CPPTRACE
// Fully aware this is completely signal unsafe. We don't ever try to recover from signals, so who cares.
// If it breaks it breaks. We're not mission critical software.
cpptrace::stacktrace trace = cpptrace::generate_trace(0, 30);
#else
int trace = 0;
#endif
MINIDUMP_EXCEPTION_INFORMATION mei {};
mei.ExceptionPointers = ExceptionInfo;
mei.ClientPointers = TRUE;
mei.ThreadId = GetCurrentThreadId();
HANDLE outfile;
char outfilename[1024];
GetModuleFileNameA(NULL, outfilename, sizeof(outfilename));
strncat(outfilename, ".dmp", sizeof(outfilename) - strlen(outfilename) - 1);
outfile = CreateFileA(outfilename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
if (outfile == NULL)
{
return EXCEPTION_CONTINUE_SEARCH;
}
BOOL result;
result = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), outfile, MiniDumpNormal, &mei, NULL, NULL);
if (result == FALSE)
{
CloseHandle(outfile);
DeleteFileA("ringracers_minidump.dmp");
goto exit;
}
CloseHandle(outfile);
exit:
CommonSignalHandleCleanup();
I_ReportSignal(ExceptionInfo->ExceptionRecord->ExceptionCode, 0, (void*)&trace);
return EXCEPTION_CONTINUE_SEARCH;
}
#endif
#if !defined(NEWSIGNALHANDLER) && !defined(USE_DBGHELP)
static ATTRNORETURN void signal_handler(INT32 num)
{
g_in_exiting_signal_handler = true;
@ -441,18 +626,20 @@ static ATTRNORETURN void signal_handler(INT32 num)
exit(-2);
}
D_QuitNetGame(); // Fix server freezes
CL_AbortDownloadResume();
G_DirtyGameData();
CommonSignalHandleCleanup();
#ifdef UNIXBACKTRACE
write_backtrace(num);
#endif
I_ReportSignal(num, 0);
I_ReportSignal(num, 0, NULL);
signal(num, SIG_DFL); //default signal action
raise(num);
}
#endif
#ifdef USE_DBGHELP
LPTOP_LEVEL_EXCEPTION_FILTER g_prevtoplevelexceptionfilter;
#endif
FUNCNORETURN static ATTRNORETURN void quit_handler(int num)
{
signal(num, SIG_DFL); //default signal action
@ -829,12 +1016,17 @@ static void I_RegisterSignals (void)
// If these defines don't exist,
// then compilation would have failed above us...
#ifndef NEWSIGNALHANDLER
#if !defined(NEWSIGNALHANDLER) && !defined(USE_DBGHELP)
signal(SIGILL , signal_handler);
signal(SIGSEGV , signal_handler);
signal(SIGABRT , signal_handler);
signal(SIGFPE , signal_handler);
#endif
#ifdef USE_DBGHELP
// Initialize Windows SDK-specific crashdump handler (DbgHelp)
g_previous_toplevelexceptionfilter = SetUnhandledExceptionFilter(WriteMinidumpExceptionFilter);
#endif
}
#ifdef NEWSIGNALHANDLER
@ -1598,9 +1790,9 @@ static void I_Fork(void)
{
signum = WTERMSIG (status);
#ifdef WCOREDUMP
I_ReportSignal(signum, WCOREDUMP (status));
I_ReportSignal(signum, WCOREDUMP (status), NULL);
#else
I_ReportSignal(signum, 0);
I_ReportSignal(signum, 0, NULL);
#endif
status = 128 + signum;
}
@ -1656,7 +1848,7 @@ INT32 I_StartupSystem(void)
//
// I_Quit
//
void I_Quit(void)
FUNCNORETURN void ATTRNORETURN I_Quit(void)
{
static SDL_bool quiting = SDL_FALSE;
@ -1732,7 +1924,7 @@ static boolean shutdowning = false;
extern "C" consvar_t cv_fuzz;
void I_Error(const char *error, ...)
FUNCIERROR void ATTRNORETURN I_Error(const char *error, ...)
{
va_list argptr;
char buffer[8192];

View file

@ -4,6 +4,10 @@
"version": "1.0.0",
"builtin-baseline": "d5ec528843d29e3a52d745a64b469f810b2cedbf",
"dependencies": [
{
"name": "cpptrace",
"platform": "windows & !mingw"
},
"curl",
"libogg",
"libpng",