Fix reporting unhandled exceptions in MSVC

For some reason set_terminate() doesn't work with MSVC2013
master
Piotr Dziwinski 2015-08-16 00:06:27 +02:00
parent 0c670e7699
commit 4d3a0b6602
3 changed files with 53 additions and 47 deletions

View File

@ -135,43 +135,53 @@ int SDL_MAIN_FUNC(int argc, char *argv[])
InitializeEventTypeTexts(); InitializeEventTypeTexts();
int code = 0; int code = 0;
while (true) try
{ {
CApplication app(systemUtils.get()); // single instance of the application while (true)
ParseArgsStatus status = app.ParseArguments(argc, argv);
if (status == PARSE_ARGS_FAIL)
{ {
systemUtils->SystemDialog(SDT_ERROR, "COLOBOT - Fatal Error", "Invalid commandline arguments!\n"); CApplication app(systemUtils.get()); // single instance of the application
return app.GetExitCode();
}
else if (status == PARSE_ARGS_HELP)
{
return app.GetExitCode();
}
ParseArgsStatus status = app.ParseArguments(argc, argv);
if (! app.Create()) if (status == PARSE_ARGS_FAIL)
{
code = app.GetExitCode();
if (code != 0 && !app.GetErrorMessage().empty())
{ {
systemUtils->SystemDialog(SDT_ERROR, "COLOBOT - Fatal Error", app.GetErrorMessage()); systemUtils->SystemDialog(SDT_ERROR, "COLOBOT - Fatal Error", "Invalid commandline arguments!\n");
return app.GetExitCode();
} }
logger.Info("Didn't run main loop. Exiting with code %d\n", code); else if (status == PARSE_ARGS_HELP)
return code; {
return app.GetExitCode();
}
if (!app.Create())
{
code = app.GetExitCode();
if (code != 0 && !app.GetErrorMessage().empty())
{
systemUtils->SystemDialog(SDT_ERROR, "COLOBOT - Fatal Error", app.GetErrorMessage());
}
logger.Info("Didn't run main loop. Exiting with code %d\n", code);
return code;
}
code = app.Run();
bool restarting = app.IsRestarting();
if (!restarting)
break;
} }
}
code = app.Run(); catch (std::exception& e)
{
bool restarting = app.IsRestarting(); CSignalHandlers::HandleUncaughtException(e);
}
if (!restarting) catch (...)
break; {
CSignalHandlers::HandleOtherUncaughtException();
} }
logger.Info("Exiting with code %d\n", code); logger.Info("Exiting with code %d\n", code);
return code; return code;
} }

View File

@ -40,7 +40,6 @@ void CSignalHandlers::Init(CSystemUtils* systemUtils)
signal(SIGABRT, SignalHandler); signal(SIGABRT, SignalHandler);
signal(SIGFPE, SignalHandler); signal(SIGFPE, SignalHandler);
signal(SIGILL, SignalHandler); signal(SIGILL, SignalHandler);
std::set_terminate(UnhandledExceptionHandler);
} }
void CSignalHandlers::SignalHandler(int sig) void CSignalHandlers::SignalHandler(int sig)
@ -73,29 +72,23 @@ std::string demangle(const char* name) {
#else #else
// For MSVC and others // For MSVC and others
// In MSVC typeinfo(e).name() should be already demangled // In MSVC typeinfo(e).name() should be already demangled
std::string demangle(const char* name) { std::string demangle(const char* name)
{
return name; return name;
} }
#endif #endif
void CSignalHandlers::UnhandledExceptionHandler() void CSignalHandlers::HandleUncaughtException(const std::exception& e)
{ {
std::exception_ptr exptr = std::current_exception(); std::stringstream ss;
try ss << "Type: " << demangle(typeid(e).name()) << std::endl;
{ ss << "Message: " << e.what();
std::rethrow_exception(exptr); ReportError(ss.str());
} }
catch (const std::exception& e)
{ void CSignalHandlers::HandleOtherUncaughtException()
std::stringstream ss; {
ss << "Type: " << demangle(typeid(e).name()) << std::endl; ReportError("Unknown unhandled exception (not inherited from std::exception)");
ss << "Message: " << e.what();
ReportError(ss.str());
}
catch (...)
{
ReportError("Unknown unhandled exception (not inherited from std::exception)");
}
} }
void CSignalHandlers::ReportError(const std::string& errorMessage) void CSignalHandlers::ReportError(const std::string& errorMessage)

View File

@ -28,6 +28,9 @@ class CSignalHandlers
public: public:
static void Init(CSystemUtils* systemUtils); static void Init(CSystemUtils* systemUtils);
static void HandleUncaughtException(const std::exception& e);
static void HandleOtherUncaughtException();
private: private:
static void SignalHandler(int sig); static void SignalHandler(int sig);
static void UnhandledExceptionHandler(); static void UnhandledExceptionHandler();