diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/util/exception_filter_win32.cpp | 3 | ||||
-rw-r--r-- | src/mongo/util/exception_filter_win32.h | 9 | ||||
-rw-r--r-- | src/mongo/util/signal_handlers_synchronous.cpp | 25 |
3 files changed, 35 insertions, 2 deletions
diff --git a/src/mongo/util/exception_filter_win32.cpp b/src/mongo/util/exception_filter_win32.cpp index fd0bbb3055c..1cd8993eea1 100644 --- a/src/mongo/util/exception_filter_win32.cpp +++ b/src/mongo/util/exception_filter_win32.cpp @@ -130,6 +130,7 @@ void doMinidumpWithException(struct _EXCEPTION_POINTERS* exceptionInfo) { CloseHandle(hFile); } +} // namespace LONG WINAPI exceptionFilter(struct _EXCEPTION_POINTERS* excPointers) { char exceptionString[128]; @@ -193,7 +194,7 @@ LONG WINAPI exceptionFilter(struct _EXCEPTION_POINTERS* excPointers) { // We won't reach here return EXCEPTION_EXECUTE_HANDLER; } -} // namespace + LPTOP_LEVEL_EXCEPTION_FILTER filtLast = 0; diff --git a/src/mongo/util/exception_filter_win32.h b/src/mongo/util/exception_filter_win32.h index ea4c2ccf501..11cb3c6f974 100644 --- a/src/mongo/util/exception_filter_win32.h +++ b/src/mongo/util/exception_filter_win32.h @@ -33,4 +33,13 @@ namespace mongo { void setWindowsUnhandledExceptionFilter(); +#ifdef _WIN32 + +/** + * Windows unhandled exception filter + */ +LONG WINAPI exceptionFilter(struct _EXCEPTION_POINTERS* excPointers); + +#endif + } // namespace mongo diff --git a/src/mongo/util/signal_handlers_synchronous.cpp b/src/mongo/util/signal_handlers_synchronous.cpp index 8b54c9ff21e..de02dd08d49 100644 --- a/src/mongo/util/signal_handlers_synchronous.cpp +++ b/src/mongo/util/signal_handlers_synchronous.cpp @@ -76,8 +76,31 @@ const char* strsignal(int signalNum) { } } +int sehExceptionFilter(unsigned int code, struct _EXCEPTION_POINTERS* excPointers) { + exceptionFilter(excPointers); + + return EXCEPTION_EXECUTE_HANDLER; +} + +// Follow SEH conventions by defining a status code per their conventions +// Bit 31-30: 11 = ERROR +// Bit 29: 1 = Client bit, i.e. a user-defined code +#define STATUS_EXIT_ABRUPT 0xE0000001 + +// Historically we relied on raising SEH exception and letting the unhandled exception handler then +// handle it to that we can dump the process. This works in all but one case. +// The C++ terminate handler runs the terminate handler in a SEH __try/__catch. Therefore, any SEH +// exceptions we raise become handled. Now, we setup our own SEH handler to quick catch the SEH +// exception and take the dump bypassing the unhandled exception handler. +// void endProcessWithSignal(int signalNum) { - RaiseException(EXIT_ABRUPT, EXCEPTION_NONCONTINUABLE, 0, nullptr); + + __try { + RaiseException(STATUS_EXIT_ABRUPT, EXCEPTION_NONCONTINUABLE, 0, nullptr); + } __except (sehExceptionFilter(GetExceptionCode(), GetExceptionInformation())) { + // The exception filter exits the process + quickExit(EXIT_ABRUPT); + } } #else |