mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Add cpptrace in I_Error on windows, minidumps, stricter warnings, optimized drawers in debug
This commit is contained in:
parent
c1b22c0c73
commit
94ef03dcd2
11 changed files with 294 additions and 99 deletions
|
|
@ -125,6 +125,9 @@ find_package(PNG REQUIRED)
|
||||||
find_package(SDL2 CONFIG REQUIRED)
|
find_package(SDL2 CONFIG REQUIRED)
|
||||||
find_package(CURL REQUIRED)
|
find_package(CURL REQUIRED)
|
||||||
find_package(Opus 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
|
# Use the one in thirdparty/fmt to guarantee a minimum version
|
||||||
#find_package(FMT CONFIG REQUIRED)
|
#find_package(FMT CONFIG REQUIRED)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,8 +54,8 @@
|
||||||
"name": "__develop-cl",
|
"name": "__develop-cl",
|
||||||
"hidden": true,
|
"hidden": true,
|
||||||
"cacheVariables": {
|
"cacheVariables": {
|
||||||
"CMAKE_C_FLAGS_RELWITHDEBINFO": "/MD /O2 /Ob2 /DNDEBUG",
|
"CMAKE_C_FLAGS_RELWITHDEBINFO": "/MD /Zi /O2 /Ob2 /DNDEBUG",
|
||||||
"CMAKE_CXX_FLAGS_RELWITHDEBINFO": "/MD /O2 /Ob2 /DNDEBUG",
|
"CMAKE_CXX_FLAGS_RELWITHDEBINFO": "/MD /Zi /O2 /Ob2 /DNDEBUG",
|
||||||
"SRB2_CONFIG_DEV_BUILD": "ON",
|
"SRB2_CONFIG_DEV_BUILD": "ON",
|
||||||
"CMAKE_BUILD_TYPE": "RelWithDebInfo"
|
"CMAKE_BUILD_TYPE": "RelWithDebInfo"
|
||||||
}
|
}
|
||||||
|
|
@ -64,8 +64,8 @@
|
||||||
"name": "__release-cl",
|
"name": "__release-cl",
|
||||||
"hidden": true,
|
"hidden": true,
|
||||||
"cacheVariables": {
|
"cacheVariables": {
|
||||||
"CMAKE_C_FLAGS_RELWITHDEBINFO": "/MD /O2 /Ob2 /DNDEBUG",
|
"CMAKE_C_FLAGS_RELWITHDEBINFO": "/MD /Zi /O2 /Ob2 /DNDEBUG",
|
||||||
"CMAKE_CXX_FLAGS_RELWITHDEBINFO": "/MD /O2 /Ob2 /DNDEBUG",
|
"CMAKE_CXX_FLAGS_RELWITHDEBINFO": "/MD /Zi /O2 /Ob2 /DNDEBUG",
|
||||||
"SRB2_CONFIG_DEV_BUILD": "OFF",
|
"SRB2_CONFIG_DEV_BUILD": "OFF",
|
||||||
"CMAKE_BUILD_TYPE": "RelWithDebInfo"
|
"CMAKE_BUILD_TYPE": "RelWithDebInfo"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -176,6 +176,41 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
|
||||||
p_deepcopy.cpp
|
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")
|
set_target_properties(SRB2SDL2 PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/sdl/macosx/MacOSXBundleInfo.plist.in")
|
||||||
|
|
||||||
if(SRB2_CONFIG_ENABLE_WEBM_MOVIES)
|
if(SRB2_CONFIG_ENABLE_WEBM_MOVIES)
|
||||||
|
|
@ -210,7 +245,7 @@ add_custom_target(_SRB2_reconf ALL
|
||||||
)
|
)
|
||||||
add_dependencies(SRB2SDL2 _SRB2_reconf)
|
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")
|
target_link_options(SRB2SDL2 PRIVATE "-Wl,--disable-dynamicbase")
|
||||||
if("${SRB2_CONFIG_STATIC_STDLIB}")
|
if("${SRB2_CONFIG_STATIC_STDLIB}")
|
||||||
# On MinGW with internal libraries, link the standard library statically
|
# 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()
|
||||||
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_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()
|
endif()
|
||||||
|
|
||||||
target_compile_features(SRB2SDL2 PRIVATE c_std_11 cxx_std_17)
|
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 PNG::PNG)
|
||||||
target_link_libraries(SRB2SDL2 PRIVATE CURL::libcurl)
|
target_link_libraries(SRB2SDL2 PRIVATE CURL::libcurl)
|
||||||
target_link_libraries(SRB2SDL2 PRIVATE Opus::opus)
|
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)
|
target_link_libraries(SRB2SDL2 PRIVATE ReNameNoise::renamenoise)
|
||||||
if("${CMAKE_SYSTEM_NAME}" MATCHES "FreeBSD")
|
if("${CMAKE_SYSTEM_NAME}" MATCHES "FreeBSD")
|
||||||
target_link_libraries(SRB2SDL2 PRIVATE -lexecinfo)
|
target_link_libraries(SRB2SDL2 PRIVATE -lexecinfo)
|
||||||
|
|
@ -461,6 +511,7 @@ target_compile_options(SRB2SDL2 PRIVATE
|
||||||
# This is a direct translation from versions.mk
|
# This is a direct translation from versions.mk
|
||||||
$<$<AND:$<COMPILE_LANGUAGE:C>,$<C_COMPILER_ID:GNU>>:
|
$<$<AND:$<COMPILE_LANGUAGE:C>,$<C_COMPILER_ID:GNU>>:
|
||||||
-Wall
|
-Wall
|
||||||
|
-Werror-implicit-function-declaration
|
||||||
-Wno-trigraphs
|
-Wno-trigraphs
|
||||||
-W # Was controlled by RELAXWARNINGS
|
-W # Was controlled by RELAXWARNINGS
|
||||||
-pedantic
|
-pedantic
|
||||||
|
|
@ -545,6 +596,7 @@ target_compile_options(SRB2SDL2 PRIVATE
|
||||||
$<$<AND:$<COMPILE_LANGUAGE:C>,$<OR:$<C_COMPILER_ID:AppleClang>,$<C_COMPILER_ID:Clang>>>:
|
$<$<AND:$<COMPILE_LANGUAGE:C>,$<OR:$<C_COMPILER_ID:AppleClang>,$<C_COMPILER_ID:Clang>>>:
|
||||||
#-Wall
|
#-Wall
|
||||||
-Werror=microsoft
|
-Werror=microsoft
|
||||||
|
-Werror=implicit-function-declaration
|
||||||
-Wreturn-type # Missing returns in non-void function
|
-Wreturn-type # Missing returns in non-void function
|
||||||
-Wduplicate-decl-specifier
|
-Wduplicate-decl-specifier
|
||||||
-Wsometimes-uninitialized
|
-Wsometimes-uninitialized
|
||||||
|
|
@ -570,9 +622,14 @@ target_compile_options(SRB2SDL2 PRIVATE
|
||||||
# C++, GNU
|
# C++, GNU
|
||||||
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CXX_COMPILER_ID:GNU>>:
|
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CXX_COMPILER_ID:GNU>>:
|
||||||
-Wall
|
-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>>>:
|
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<OR:$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:Clang>>>:
|
||||||
#-Wall
|
#-Wall
|
||||||
-Werror=microsoft
|
-Werror=microsoft
|
||||||
|
|
@ -584,6 +641,8 @@ target_compile_options(SRB2SDL2 PRIVATE
|
||||||
-Wno-c++98-compat
|
-Wno-c++98-compat
|
||||||
-Wno-c++11-compat
|
-Wno-c++11-compat
|
||||||
-Wno-c++14-compat # No C++14 compat needed
|
-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-unused-but-set-variable # Setting unread variables is fine (nontrivial C++ types issue)
|
||||||
-Wno-misleading-indentation # Some cases in code currently
|
-Wno-misleading-indentation # Some cases in code currently
|
||||||
-Wno-deprecated-non-prototype # We have no intention of using C23 yet.
|
-Wno-deprecated-non-prototype # We have no intention of using C23 yet.
|
||||||
|
|
@ -594,6 +653,8 @@ target_compile_options(SRB2SDL2 PRIVATE
|
||||||
-Wno-unused-function
|
-Wno-unused-function
|
||||||
>
|
>
|
||||||
|
|
||||||
|
# C++, Clang and Apple Clang
|
||||||
|
|
||||||
# C++, MSVC
|
# C++, MSVC
|
||||||
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CXX_COMPILER_ID:MSVC>>:
|
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CXX_COMPILER_ID:MSVC>>:
|
||||||
/Wv:19.20.27004.0
|
/Wv:19.20.27004.0
|
||||||
|
|
|
||||||
|
|
@ -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
|
/** \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();
|
the return code 0 of I_Quit();
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ void I_OsPolling(void);
|
||||||
|
|
||||||
/** \brief Called by M_Responder when quit is selected, return exit code 0
|
/** \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
|
typedef enum
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ menuitem_t OPTIONS_Voice[] =
|
||||||
NULL, srb2::itemaction(&cv_voice_inputamp), 0, 0},
|
NULL, srb2::itemaction(&cv_voice_inputamp), 0, 0},
|
||||||
|
|
||||||
{IT_STRING | IT_CVAR, "Input Noise Suppression", "Suppress background noise from your voice.",
|
{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.",
|
{IT_STRING | IT_CVAR, "Input Sensitivity", "Voice higher than this threshold will transmit, in decibels.",
|
||||||
NULL, srb2::itemaction(&cv_voice_activationthreshold), 0, 0 },
|
NULL, srb2::itemaction(&cv_voice_activationthreshold), 0, 0 },
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
#include "../doomdef.h"
|
#include "../doomdef.h"
|
||||||
#include "../doomstat.h"
|
#include "../doomstat.h"
|
||||||
#include "../info.h"
|
#include "../info.h"
|
||||||
|
#include "../g_game.h"
|
||||||
#include "../k_objects.h"
|
#include "../k_objects.h"
|
||||||
#include "../p_local.h"
|
#include "../p_local.h"
|
||||||
#include "../r_state.h"
|
#include "../r_state.h"
|
||||||
|
|
|
||||||
|
|
@ -732,8 +732,7 @@ void R_RenderMaskedSegRange(drawseg_t *drawseg, INT32 x1, INT32 x2)
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static constexpr T saturating_add(T x, T y) noexcept
|
static constexpr T saturating_add(T x, T y) noexcept
|
||||||
{
|
{
|
||||||
INT64 z;
|
INT64 z = static_cast<INT64>(x) + static_cast<INT64>(y);
|
||||||
z = static_cast<INT64>(x) + static_cast<INT64>(y);
|
|
||||||
if (z > static_cast<INT64>(std::numeric_limits<T>::max()))
|
if (z > static_cast<INT64>(std::numeric_limits<T>::max()))
|
||||||
{
|
{
|
||||||
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>
|
template <typename T>
|
||||||
static constexpr T saturating_mul(T x, T y) noexcept
|
static constexpr T saturating_mul(T x, T y) noexcept
|
||||||
{
|
{
|
||||||
INT64 z;
|
INT64 z = static_cast<INT64>(x) * static_cast<INT64>(y);
|
||||||
z = static_cast<INT64>(x) * static_cast<INT64>(y);
|
|
||||||
if (z > static_cast<INT64>(std::numeric_limits<T>::max()))
|
if (z > static_cast<INT64>(std::numeric_limits<T>::max()))
|
||||||
{
|
{
|
||||||
z = static_cast<INT64>(std::numeric_limits<T>::max());
|
z = static_cast<INT64>(std::numeric_limits<T>::max());
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@
|
||||||
#include "../core/string.h"
|
#include "../core/string.h"
|
||||||
|
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
#include <tracy/tracy/Tracy.hpp>
|
#include <tracy/tracy/Tracy.hpp>
|
||||||
|
|
||||||
|
|
@ -32,11 +31,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include "time.h" // For log timestamps
|
#include "time.h" // For log timestamps
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_SDL
|
|
||||||
|
|
||||||
#ifdef HAVE_TTF
|
#ifdef HAVE_TTF
|
||||||
#include "SDL.h"
|
#include "SDL.h"
|
||||||
|
|
@ -68,46 +63,6 @@ char logfilename[1024];
|
||||||
#endif
|
#endif
|
||||||
#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
|
#ifdef LOGMESSAGES
|
||||||
static void InitLogging(void)
|
static void InitLogging(void)
|
||||||
{
|
{
|
||||||
|
|
@ -212,10 +167,6 @@ static void init_exchndl()
|
||||||
if (pfnExcHndlInit != NULL)
|
if (pfnExcHndlInit != NULL)
|
||||||
(pfnExcHndlInit)();
|
(pfnExcHndlInit)();
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
static void init_exchndl()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
@ -300,25 +251,12 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
//I_OutputMsg("I_StartupSystem() ...\n");
|
//I_OutputMsg("I_StartupSystem() ...\n");
|
||||||
I_StartupSystem();
|
I_StartupSystem();
|
||||||
#if defined (_WIN32)
|
|
||||||
|
#if defined (_WIN32) && !defined(_MSC_VER)
|
||||||
if (!M_CheckParm("-noexchndl"))
|
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
|
#endif
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
@ -353,8 +291,6 @@ int main(int argc, char **argv)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
int WINAPI WinMain(HINSTANCE pInstance, HINSTANCE pPrevInstance, LPSTR lpCmdLine, int nShowCmd)
|
int WINAPI WinMain(HINSTANCE pInstance, HINSTANCE pPrevInstance, LPSTR lpCmdLine, int nShowCmd)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,12 @@ typedef DWORD (WINAPI *p_timeGetTime) (void);
|
||||||
typedef UINT (WINAPI *p_timeEndPeriod) (UINT);
|
typedef UINT (WINAPI *p_timeEndPeriod) (UINT);
|
||||||
typedef HANDLE (WINAPI *p_OpenFileMappingA) (DWORD, BOOL, LPCSTR);
|
typedef HANDLE (WINAPI *p_OpenFileMappingA) (DWORD, BOOL, LPCSTR);
|
||||||
typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
|
typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
|
||||||
|
|
||||||
|
#if defined(_WIN32) && !defined(__GNUC__)
|
||||||
|
#define USE_DBGHELP
|
||||||
|
#include <DbgHelp.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
@ -141,6 +147,10 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
|
||||||
#define UNIXBACKTRACE
|
#define UNIXBACKTRACE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_CPPTRACE
|
||||||
|
#include <cpptrace/cpptrace.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
// Locations for searching for bios.pk3
|
// Locations for searching for bios.pk3
|
||||||
#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)
|
#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)
|
||||||
#define DEFAULTWADLOCATION1 "/usr/local/share/games/RingRacers"
|
#define DEFAULTWADLOCATION1 "/usr/local/share/games/RingRacers"
|
||||||
|
|
@ -302,8 +312,10 @@ static void I_ShowErrorMessageBox(const char *messagefordevelopers, boolean dump
|
||||||
dumpmade ?
|
dumpmade ?
|
||||||
#if defined (UNIXBACKTRACE)
|
#if defined (UNIXBACKTRACE)
|
||||||
"crash-log.txt"
|
"crash-log.txt"
|
||||||
#elif defined (_WIN32)
|
#elif defined (_WIN32) && defined(__GNUC__)
|
||||||
".rpt crash dump"
|
".rpt crash dump"
|
||||||
|
#elif defined (USE_DBGHELP)
|
||||||
|
".dmp crash dump"
|
||||||
#endif
|
#endif
|
||||||
" (very important!) and " : "",
|
" (very important!) and " : "",
|
||||||
#ifdef LOGMESSAGES
|
#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.
|
// 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";
|
//static char msg[] = "oh no! back to reality!\r\n";
|
||||||
const char * sigmsg;
|
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)
|
switch (num)
|
||||||
{
|
{
|
||||||
// case SIGINT:
|
// case SIGINT:
|
||||||
|
|
@ -405,30 +488,132 @@ static void I_ReportSignal(int num, int coredumped)
|
||||||
else
|
else
|
||||||
sigmsg = msg;
|
sigmsg = msg;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
if (sigmsg)
|
||||||
|
{
|
||||||
|
strcpy(msg, sigmsg);
|
||||||
|
}
|
||||||
|
|
||||||
if (coredumped)
|
if (coredumped)
|
||||||
{
|
{
|
||||||
if (sigmsg)
|
|
||||||
strcpy(msg, sigmsg);
|
|
||||||
strcat(msg, " (core dumped)");
|
strcat(msg, " (core dumped)");
|
||||||
|
}
|
||||||
|
|
||||||
|
#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;
|
sigmsg = msg;
|
||||||
}
|
|
||||||
|
|
||||||
I_OutputMsg("\nProcess killed by signal: %s\n\n", sigmsg);
|
I_OutputMsg("\nProcess killed by signal: %s\n\n", sigmsg);
|
||||||
|
|
||||||
I_ShowErrorMessageBox(sigmsg,
|
I_ShowErrorMessageBox(sigmsg,
|
||||||
#if defined (UNIXBACKTRACE)
|
#if defined (UNIXBACKTRACE)
|
||||||
true
|
true
|
||||||
#elif defined (_WIN32)
|
#elif defined (_WIN32) && defined (__GNUC__)
|
||||||
!M_CheckParm("-noexchndl")
|
!M_CheckParm("-noexchndl")
|
||||||
|
#elif defined (USE_DBGHELP)
|
||||||
|
true
|
||||||
#else
|
#else
|
||||||
false
|
false
|
||||||
#endif
|
#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)
|
static ATTRNORETURN void signal_handler(INT32 num)
|
||||||
{
|
{
|
||||||
g_in_exiting_signal_handler = true;
|
g_in_exiting_signal_handler = true;
|
||||||
|
|
@ -441,18 +626,20 @@ static ATTRNORETURN void signal_handler(INT32 num)
|
||||||
exit(-2);
|
exit(-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
D_QuitNetGame(); // Fix server freezes
|
CommonSignalHandleCleanup();
|
||||||
CL_AbortDownloadResume();
|
|
||||||
G_DirtyGameData();
|
|
||||||
#ifdef UNIXBACKTRACE
|
#ifdef UNIXBACKTRACE
|
||||||
write_backtrace(num);
|
write_backtrace(num);
|
||||||
#endif
|
#endif
|
||||||
I_ReportSignal(num, 0);
|
I_ReportSignal(num, 0, NULL);
|
||||||
signal(num, SIG_DFL); //default signal action
|
signal(num, SIG_DFL); //default signal action
|
||||||
raise(num);
|
raise(num);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_DBGHELP
|
||||||
|
LPTOP_LEVEL_EXCEPTION_FILTER g_prevtoplevelexceptionfilter;
|
||||||
|
#endif
|
||||||
|
|
||||||
FUNCNORETURN static ATTRNORETURN void quit_handler(int num)
|
FUNCNORETURN static ATTRNORETURN void quit_handler(int num)
|
||||||
{
|
{
|
||||||
signal(num, SIG_DFL); //default signal action
|
signal(num, SIG_DFL); //default signal action
|
||||||
|
|
@ -829,12 +1016,17 @@ static void I_RegisterSignals (void)
|
||||||
|
|
||||||
// If these defines don't exist,
|
// If these defines don't exist,
|
||||||
// then compilation would have failed above us...
|
// then compilation would have failed above us...
|
||||||
#ifndef NEWSIGNALHANDLER
|
#if !defined(NEWSIGNALHANDLER) && !defined(USE_DBGHELP)
|
||||||
signal(SIGILL , signal_handler);
|
signal(SIGILL , signal_handler);
|
||||||
signal(SIGSEGV , signal_handler);
|
signal(SIGSEGV , signal_handler);
|
||||||
signal(SIGABRT , signal_handler);
|
signal(SIGABRT , signal_handler);
|
||||||
signal(SIGFPE , signal_handler);
|
signal(SIGFPE , signal_handler);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_DBGHELP
|
||||||
|
// Initialize Windows SDK-specific crashdump handler (DbgHelp)
|
||||||
|
g_previous_toplevelexceptionfilter = SetUnhandledExceptionFilter(WriteMinidumpExceptionFilter);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NEWSIGNALHANDLER
|
#ifdef NEWSIGNALHANDLER
|
||||||
|
|
@ -1598,9 +1790,9 @@ static void I_Fork(void)
|
||||||
{
|
{
|
||||||
signum = WTERMSIG (status);
|
signum = WTERMSIG (status);
|
||||||
#ifdef WCOREDUMP
|
#ifdef WCOREDUMP
|
||||||
I_ReportSignal(signum, WCOREDUMP (status));
|
I_ReportSignal(signum, WCOREDUMP (status), NULL);
|
||||||
#else
|
#else
|
||||||
I_ReportSignal(signum, 0);
|
I_ReportSignal(signum, 0, NULL);
|
||||||
#endif
|
#endif
|
||||||
status = 128 + signum;
|
status = 128 + signum;
|
||||||
}
|
}
|
||||||
|
|
@ -1656,7 +1848,7 @@ INT32 I_StartupSystem(void)
|
||||||
//
|
//
|
||||||
// I_Quit
|
// I_Quit
|
||||||
//
|
//
|
||||||
void I_Quit(void)
|
FUNCNORETURN void ATTRNORETURN I_Quit(void)
|
||||||
{
|
{
|
||||||
static SDL_bool quiting = SDL_FALSE;
|
static SDL_bool quiting = SDL_FALSE;
|
||||||
|
|
||||||
|
|
@ -1732,7 +1924,7 @@ static boolean shutdowning = false;
|
||||||
|
|
||||||
extern "C" consvar_t cv_fuzz;
|
extern "C" consvar_t cv_fuzz;
|
||||||
|
|
||||||
void I_Error(const char *error, ...)
|
FUNCIERROR void ATTRNORETURN I_Error(const char *error, ...)
|
||||||
{
|
{
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
char buffer[8192];
|
char buffer[8192];
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,10 @@
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"builtin-baseline": "d5ec528843d29e3a52d745a64b469f810b2cedbf",
|
"builtin-baseline": "d5ec528843d29e3a52d745a64b469f810b2cedbf",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
|
{
|
||||||
|
"name": "cpptrace",
|
||||||
|
"platform": "windows & !mingw"
|
||||||
|
},
|
||||||
"curl",
|
"curl",
|
||||||
"libogg",
|
"libogg",
|
||||||
"libpng",
|
"libpng",
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue