summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Benvenuto <mark.benvenuto@mongodb.com>2020-03-26 14:18:30 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-03-27 20:06:44 +0000
commit6ec78d34e7135b3f8f842b821e1643714c312d80 (patch)
tree63f824ec3c79244b71168e3c33aec87728bbfb8b
parent7e12da83457ca5a8e76c7d6f39d6b9bbfad3be92 (diff)
downloadmongo-6ec78d34e7135b3f8f842b821e1643714c312d80.tar.gz
SERVER-44645 Windows does not generate minidumps on unhandled C++ exceptions
-rw-r--r--src/mongo/util/exception_filter_win32.cpp3
-rw-r--r--src/mongo/util/exception_filter_win32.h9
-rw-r--r--src/mongo/util/signal_handlers_synchronous.cpp25
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