mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
Merge #4729
4729: Add exception handling for Windows r=def- a=Jupeyy Only tested on wine yet. I am using https://github.com/jrfonseca/drmingw We don't need to ship debug symbols, but need to keep a copy of DDNet.exe with debug symbols. Using addr2line works on the addresses printed by this tool. currently crash reports go into %appdata%/Teeworlds/dumps (that dir seems to be rarely used anyway, but can also change to /crashlogs or smth) ## Checklist - [ ] Tested the change ingame - [ ] Provided screenshots if it is a visual change - [ ] Tested in combination with possibly related configuration options - [ ] Written a unit test if it works standalone, system.c especially - [ ] Considered possible null pointers and out of bounds array indexing - [ ] Changed no physics that affect existing maps - [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional) Co-authored-by: Jupeyy <jupjopjap@gmail.com> Co-authored-by: Dennis Felsing <dennis@felsin9.de>
This commit is contained in:
commit
b793e1e41b
|
@ -117,6 +117,8 @@ option(DISCORD_DYNAMIC "Enable discovering Discord rich presence libraries at ru
|
|||
option(PREFER_BUNDLED_LIBS "Prefer bundled libraries over system libraries" ${AUTO_DEPENDENCIES_DEFAULT})
|
||||
option(DEV "Don't generate stuff necessary for packaging" OFF)
|
||||
|
||||
option(EXCEPTION_HANDLING "Enable exception handling (only works with Windows as of now)" OFF)
|
||||
|
||||
if(TEST_MYSQL)
|
||||
set(MYSQL ON)
|
||||
endif()
|
||||
|
@ -217,6 +219,14 @@ if(NOT MSVC AND NOT HAIKU)
|
|||
add_c_compiler_flag_if_supported(OUR_FLAGS -stdlib=libc++)
|
||||
endif()
|
||||
|
||||
if(EXCEPTION_HANDLING)
|
||||
add_c_compiler_flag_if_supported(OUR_FLAGS -DCONF_EXCEPTION_HANDLING)
|
||||
# use the frame pointer (frame pointer usage is disabled by default in
|
||||
# some architectures like x86_64 and for some optimization levels; and it
|
||||
# may be impossible to walk the call stack without it)
|
||||
add_c_compiler_flag_if_supported(OUR_FLAGS -fno-omit-frame-pointer)
|
||||
endif()
|
||||
|
||||
add_c_compiler_flag_if_supported(OUR_FLAGS_OWN -Wall)
|
||||
if(CMAKE_VERSION VERSION_GREATER 3.3 OR CMAKE_VERSION VERSION_EQUAL 3.3)
|
||||
add_c_compiler_flag_if_supported(OUR_FLAGS_OWN
|
||||
|
@ -239,6 +249,12 @@ if(NOT MSVC AND NOT HAIKU)
|
|||
#add_cxx_compiler_flag_if_supported(OUR_FLAGS_OWN "-Wuseless-cast")
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
if(EXCEPTION_HANDLING)
|
||||
add_c_compiler_flag_if_supported(OUR_FLAGS /DCONF_EXCEPTION_HANDLING)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT MSVC AND NOT HAIKU)
|
||||
check_c_compiler_flag("-O2;-Wp,-Werror;-D_FORTIFY_SOURCE=2" DEFINE_FORTIFY_SOURCE) # Some distributions define _FORTIFY_SOURCE by themselves.
|
||||
endif()
|
||||
|
@ -440,6 +456,10 @@ else()
|
|||
set(WEBSOCKETS_INCLUDE_DIRS)
|
||||
endif()
|
||||
|
||||
if(EXCEPTION_HANDLING)
|
||||
find_package(ExceptionHandling)
|
||||
endif()
|
||||
|
||||
if(TARGET_OS AND TARGET_OS STREQUAL "mac")
|
||||
find_program(CMAKE_OTOOL otool)
|
||||
find_program(DMGBUILD dmgbuild)
|
||||
|
@ -1399,6 +1419,7 @@ set(COPY_FILES
|
|||
${FFMPEG_COPY_FILES}
|
||||
${WEBSOCKETS_COPY_FILES}
|
||||
${DISCORDSDK_COPY_FILES}
|
||||
${EXCEPTION_HANDLING_COPY_FILES}
|
||||
)
|
||||
file(COPY ${COPY_FILES} DESTINATION .)
|
||||
|
||||
|
|
21
cmake/FindExceptionHandling.cmake
Normal file
21
cmake/FindExceptionHandling.cmake
Normal file
|
@ -0,0 +1,21 @@
|
|||
if(TARGET_OS STREQUAL "windows")
|
||||
set_extra_dirs_lib(EXCEPTION_HANDLING drmingw)
|
||||
find_file(EXCEPTION_HANDLING_LIBRARY
|
||||
NAMES exchndl.dll
|
||||
HINTS ${HINTS_EXCEPTION_HANDLING_LIBDIR}
|
||||
PATHS ${PATHS_EXCEPTION_HANDLING_LIBDIR}
|
||||
${CROSSCOMPILING_NO_CMAKE_SYSTEM_PATH}
|
||||
)
|
||||
|
||||
is_bundled(EXCEPTION_HANDLING_BUNDLED "${EXCEPTION_HANDLING_LIBRARY}")
|
||||
if(NOT EXCEPTION_HANDLING_BUNDLED)
|
||||
message(FATAL_ERROR "could not find exception handling paths")
|
||||
endif()
|
||||
set(EXCEPTION_HANDLING_COPY_FILES
|
||||
"${EXTRA_EXCEPTION_HANDLING_LIBDIR}/exchndl.dll"
|
||||
"${EXTRA_EXCEPTION_HANDLING_LIBDIR}/dbgcore.dll"
|
||||
"${EXTRA_EXCEPTION_HANDLING_LIBDIR}/dbghelp.dll"
|
||||
"${EXTRA_EXCEPTION_HANDLING_LIBDIR}/mgwhelp.dll"
|
||||
"${EXTRA_EXCEPTION_HANDLING_LIBDIR}/symsrv.dll"
|
||||
)
|
||||
endif()
|
|
@ -1 +1 @@
|
|||
Subproject commit 1cdf759f4e46edbe174250f523b9cc737c4ad8ea
|
||||
Subproject commit 635aa7afb698ed68feeb733aaea2cf861c2a1899
|
|
@ -4060,4 +4060,45 @@ int os_version_str(char *version, int length)
|
|||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(CONF_EXCEPTION_HANDLING)
|
||||
#if defined(CONF_FAMILY_WINDOWS)
|
||||
static HMODULE gs_ExceptionHandlingModule = nullptr;
|
||||
#endif
|
||||
|
||||
void init_exception_handler()
|
||||
{
|
||||
#if defined(CONF_FAMILY_WINDOWS)
|
||||
gs_ExceptionHandlingModule = LoadLibraryA("exchndl.dll");
|
||||
if(gs_ExceptionHandlingModule != nullptr)
|
||||
{
|
||||
auto pfnExcHndlInit = (void APIENTRY (*)())GetProcAddress(gs_ExceptionHandlingModule, "ExcHndlInit");
|
||||
pfnExcHndlInit();
|
||||
}
|
||||
#else
|
||||
#error exception handling not implemented
|
||||
#endif
|
||||
}
|
||||
|
||||
void set_exception_handler_log_file(const char *pLogFilePath)
|
||||
{
|
||||
#if defined(CONF_FAMILY_WINDOWS)
|
||||
if(gs_ExceptionHandlingModule != nullptr)
|
||||
{
|
||||
// Intentional
|
||||
#ifdef __MINGW32__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wcast-function-type"
|
||||
#endif
|
||||
auto pExceptionLogFilePathFunc = (BOOL APIENTRY(*)(const char *))(GetProcAddress(gs_ExceptionHandlingModule, "ExcHndlSetLogFileNameA"));
|
||||
#ifdef __MINGW32__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
pExceptionLogFilePathFunc(pLogFilePath);
|
||||
}
|
||||
#else
|
||||
#error exception handling not implemented
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -2368,6 +2368,11 @@ void set_console_msg_color(const void *rgbvoid);
|
|||
*/
|
||||
int os_version_str(char *version, int length);
|
||||
|
||||
#if defined(CONF_EXCEPTION_HANDLING)
|
||||
void init_exception_handler();
|
||||
void set_exception_handler_log_file(const char *pLogFilePath);
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -4268,6 +4268,10 @@ int main(int argc, const char **argv)
|
|||
InitAndroid();
|
||||
#endif
|
||||
|
||||
#if defined(CONF_EXCEPTION_HANDLING)
|
||||
init_exception_handler();
|
||||
#endif
|
||||
|
||||
if(secure_random_init() != 0)
|
||||
{
|
||||
RandInitFailed = true;
|
||||
|
@ -4292,6 +4296,16 @@ int main(int argc, const char **argv)
|
|||
IDiscord *pDiscord = CreateDiscord();
|
||||
ISteam *pSteam = CreateSteam();
|
||||
|
||||
#if defined(CONF_EXCEPTION_HANDLING)
|
||||
char aBuf[IO_MAX_PATH_LENGTH];
|
||||
char aBufName[IO_MAX_PATH_LENGTH];
|
||||
char aDate[64];
|
||||
str_timestamp(aDate, sizeof(aDate));
|
||||
str_format(aBufName, sizeof(aBufName), "dumps/" GAME_NAME "_crash_log_%d_%s.RTP", pid(), aDate);
|
||||
pStorage->GetCompletePath(IStorage::TYPE_SAVE, aBufName, aBuf, sizeof(aBuf));
|
||||
set_exception_handler_log_file(aBuf);
|
||||
#endif
|
||||
|
||||
if(RandInitFailed)
|
||||
{
|
||||
dbg_msg("secure", "could not initialize secure RNG");
|
||||
|
|
|
@ -3645,6 +3645,10 @@ int main(int argc, const char **argv)
|
|||
signal(SIGINT, HandleSigIntTerm);
|
||||
signal(SIGTERM, HandleSigIntTerm);
|
||||
|
||||
#if defined(CONF_EXCEPTION_HANDLING)
|
||||
init_exception_handler();
|
||||
#endif
|
||||
|
||||
CServer *pServer = CreateServer();
|
||||
IKernel *pKernel = IKernel::Create();
|
||||
|
||||
|
@ -3658,6 +3662,16 @@ int main(int argc, const char **argv)
|
|||
IConfigManager *pConfigManager = CreateConfigManager();
|
||||
IEngineAntibot *pEngineAntibot = CreateEngineAntibot();
|
||||
|
||||
#if defined(CONF_EXCEPTION_HANDLING)
|
||||
char aBuf[IO_MAX_PATH_LENGTH];
|
||||
char aBufName[IO_MAX_PATH_LENGTH];
|
||||
char aDate[64];
|
||||
str_timestamp(aDate, sizeof(aDate));
|
||||
str_format(aBufName, sizeof(aBufName), "dumps/" GAME_NAME "-Server_crash_log_%d_%s.RTP", pid(), aDate);
|
||||
pStorage->GetCompletePath(IStorage::TYPE_SAVE, aBufName, aBuf, sizeof(aBuf));
|
||||
set_exception_handler_log_file(aBuf);
|
||||
#endif
|
||||
|
||||
pServer->InitRegister(&pServer->m_NetServer, pEngineMasterServer, pConfigManager->Values(), pConsole);
|
||||
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue