mirror of https://github.com/Icinga/icinga2.git
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
0b26515c34
commit
f8b7a1511b
|
@ -34,6 +34,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;
|
||||
|
@ -55,6 +63,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.
|
||||
*/
|
||||
|
@ -885,6 +897,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;
|
||||
|
||||
|
@ -938,7 +959,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…
Reference in New Issue