diff options
author | Mark Benvenuto <mark.benvenuto@mongodb.com> | 2020-03-26 14:18:30 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-03-27 20:06:44 +0000 |
commit | 6ec78d34e7135b3f8f842b821e1643714c312d80 (patch) | |
tree | 63f824ec3c79244b71168e3c33aec87728bbfb8b /src | |
parent | 7e12da83457ca5a8e76c7d6f39d6b9bbfad3be92 (diff) | |
download | mongo-6ec78d34e7135b3f8f842b821e1643714c312d80.tar.gz |
SERVER-44645 Windows does not generate minidumps on unhandled C++ exceptions
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 |