core: Catch and I_Error uncaught exceptions in main

This commit is contained in:
Eidolon 2023-01-01 15:13:01 -06:00
parent 9806df5883
commit ba109d8981
2 changed files with 51 additions and 4 deletions

View file

@ -6,7 +6,7 @@ target_sources(SRB2SDL2 PRIVATE
i_threads.c
i_net.c
i_system.c
i_main.c
i_main.cpp
i_video.c
dosstr.c
endtxt.c

View file

@ -23,6 +23,10 @@
#include "../m_misc.h"/* path shit */
#include "../i_system.h"
#include <exception>
#include <stdexcept>
#include <string>
#if defined (__GNUC__) || defined (__unix__)
#include <unistd.h>
#endif
@ -31,7 +35,9 @@
#include <errno.h>
#endif
extern "C" {
#include "time.h" // For log timestamps
}
#ifdef HAVE_SDL
@ -70,7 +76,9 @@ char logfilename[1024];
#endif
#if defined (_WIN32)
extern "C" {
#include "../win32/win_dbg.h"
}
typedef BOOL (WINAPI *p_IsDebuggerPresent)(VOID);
#endif
@ -151,20 +159,20 @@ static void InitLogging(void)
if (M_IsPathAbsolute(reldir))
{
left = snprintf(logfilename, sizeof logfilename,
"%s"PATHSEP, reldir);
"%s" PATHSEP, reldir);
}
else
#ifdef DEFAULTDIR
if (logdir)
{
left = snprintf(logfilename, sizeof logfilename,
"%s"PATHSEP DEFAULTDIR PATHSEP"%s"PATHSEP, logdir, reldir);
"%s" PATHSEP DEFAULTDIR PATHSEP "%s" PATHSEP, logdir, reldir);
}
else
#endif/*DEFAULTDIR*/
{
left = snprintf(logfilename, sizeof logfilename,
"."PATHSEP"%s"PATHSEP, reldir);
"." PATHSEP "%s" PATHSEP, reldir);
}
strftime(&logfilename[left], sizeof logfilename - left,
@ -208,6 +216,33 @@ ChDirToExe (void)
}
#endif
static void walk_exception_stack(std::string& accum, bool nested) {
if (nested)
accum.append("\n Caused by: Unknown exception");
else
accum.append("Uncaught exception: Unknown exception");
}
static void walk_exception_stack(std::string& accum, const std::exception& ex, bool nested) {
if (nested)
accum.append("\n Caused by: ");
else
accum.append("Uncaught exception: ");
accum.append("(");
accum.append(typeid(ex).name());
accum.append(") ");
accum.append(ex.what());
try {
std::rethrow_if_nested(ex);
} catch (const std::exception& ex) {
walk_exception_stack(accum, ex, true);
} catch (...) {
walk_exception_stack(accum, true);
}
}
/** \brief The main function
@ -268,6 +303,8 @@ int main(int argc, char **argv)
MakeCodeWritable();
#endif
try {
// startup SRB2
CONS_Printf("Setting up Dr. Robotnik's Ring Racers...\n");
D_SRB2Main();
@ -279,6 +316,16 @@ int main(int argc, char **argv)
// never return
D_SRB2Loop();
} catch (const std::exception& ex) {
std::string exception;
walk_exception_stack(exception, ex, false);
I_Error("%s", exception.c_str());
} catch (...) {
std::string exception;
walk_exception_stack(exception, false);
I_Error("%s", exception.c_str());
}
#ifdef BUGTRAP
// This is safe even if BT didn't start.
ShutdownBugTrap();