mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-23 21:55:03 +02:00
Run termination handler for uncaught C++ exceptions on Windows
On Windows, the termination handler is executed for uncaught C++ exceptions unless a SEH unhandled exception filter is also set. In this case, this filter has to explicitly chain the default filter to keep this behavior.
This commit is contained in:
parent
7c4996d1c2
commit
0b9ef5ab6d
@ -33,6 +33,14 @@
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
#ifdef _WIN32
|
||||
/* MSVC throws unhandled C++ exceptions as SEH exceptions with this specific error code.
|
||||
* There seems to be no system header that actually defines this constant.
|
||||
* See also https://devblogs.microsoft.com/oldnewthing/20160915-00/?p=94316
|
||||
*/
|
||||
#define EXCEPTION_CODE_CXX_EXCEPTION 0xe06d7363
|
||||
#endif /* _WIN32 */
|
||||
|
||||
REGISTER_TYPE(Application);
|
||||
|
||||
boost::signals2::signal<void ()> Application::OnReopenLogs;
|
||||
@ -54,6 +62,10 @@ double Application::m_StartTime;
|
||||
bool Application::m_ScriptDebuggerEnabled = false;
|
||||
double Application::m_LastReloadFailed;
|
||||
|
||||
#ifdef _WIN32
|
||||
static LPTOP_LEVEL_EXCEPTION_FILTER l_DefaultUnhandledExceptionFilter = nullptr;
|
||||
#endif /* _WIN32 */
|
||||
|
||||
/**
|
||||
* Constructor for the Application class.
|
||||
*/
|
||||
@ -881,6 +893,15 @@ void Application::ExceptionHandler()
|
||||
#ifdef _WIN32
|
||||
LONG CALLBACK Application::SEHUnhandledExceptionFilter(PEXCEPTION_POINTERS exi)
|
||||
{
|
||||
/* If an unhandled C++ exception occurs with both a termination handler (std::set_terminate()) and an unhandled
|
||||
* SEH filter (SetUnhandledExceptionFilter()) set, the latter one is called. However, our termination handler is
|
||||
* better suited for dealing with C++ exceptions. In this case, the SEH exception will have a specific code and
|
||||
* we can just call the default filter function which will take care of calling the termination handler.
|
||||
*/
|
||||
if (exi->ExceptionRecord->ExceptionCode == EXCEPTION_CODE_CXX_EXCEPTION) {
|
||||
return l_DefaultUnhandledExceptionFilter(exi);
|
||||
}
|
||||
|
||||
if (l_InExceptionHandler)
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
|
||||
@ -934,7 +955,7 @@ void Application::InstallExceptionHandlers()
|
||||
sa.sa_handler = &Application::SigAbrtHandler;
|
||||
sigaction(SIGABRT, &sa, nullptr);
|
||||
#else /* _WIN32 */
|
||||
SetUnhandledExceptionFilter(&Application::SEHUnhandledExceptionFilter);
|
||||
l_DefaultUnhandledExceptionFilter = SetUnhandledExceptionFilter(&Application::SEHUnhandledExceptionFilter);
|
||||
#endif /* _WIN32 */
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user