summaryrefslogtreecommitdiff
path: root/src/mongo/util/exception_filter_win32.cpp
diff options
context:
space:
mode:
authorMark Benvenuto <mark.benvenuto@mongodb.com>2014-06-04 11:08:13 -0400
committerMark Benvenuto <mark.benvenuto@mongodb.com>2014-06-05 14:27:05 -0400
commit9ca367e8ef23be3f6e2a51f7d89411d8746fad56 (patch)
treecfbc988364a37d8e56413613bd40a97a8619add4 /src/mongo/util/exception_filter_win32.cpp
parentb377ac13c1df7108f6f01032d40f5d8818148b24 (diff)
downloadmongo-9ca367e8ef23be3f6e2a51f7d89411d8746fad56.tar.gz
SERVER-14079: Add signal handlers to shell
The shell currently lacks the signal handlers that mongod/mongos have making it tough to investigate issues. This change does the following 1. Add signal handlers to shell & tools. 2. Add invalid_parameter handler for Windows 3. Add better logging for pure call handler on Windows 4. Take dumps on terminate handler on Windows 5. Change shell to use common signal handlers 6. Remove some random dead code / commented lines.
Diffstat (limited to 'src/mongo/util/exception_filter_win32.cpp')
-rw-r--r--src/mongo/util/exception_filter_win32.cpp222
1 files changed, 114 insertions, 108 deletions
diff --git a/src/mongo/util/exception_filter_win32.cpp b/src/mongo/util/exception_filter_win32.cpp
index 5019e27e6b4..2e7f3d2e565 100644
--- a/src/mongo/util/exception_filter_win32.cpp
+++ b/src/mongo/util/exception_filter_win32.cpp
@@ -40,132 +40,138 @@
namespace mongo {
- /* create a process dump.
- To use, load up windbg. Set your symbol and source path.
- Open the crash dump file. To see the crashing context, use .ecxr in windbg
- TODO: consider using WER local dumps in the future
- */
- void doMinidump(struct _EXCEPTION_POINTERS* exceptionInfo) {
- WCHAR moduleFileName[MAX_PATH];
-
- DWORD ret = GetModuleFileNameW(NULL, &moduleFileName[0], ARRAYSIZE(moduleFileName));
- if (ret == 0) {
- int gle = GetLastError();
- log() << "GetModuleFileName failed " << errnoWithDescription(gle);
-
- // Fallback name
- wcscpy_s(moduleFileName, L"mongo");
- }
- else {
- WCHAR* dotStr = wcschr(&moduleFileName[0], L'.');
- if (dotStr != NULL) {
- *dotStr = L'\0';
+ namespace {
+ /* create a process dump.
+ To use, load up windbg. Set your symbol and source path.
+ Open the crash dump file. To see the crashing context, use .ecxr in windbg
+ TODO: consider using WER local dumps in the future
+ */
+ void doMinidumpWithException(struct _EXCEPTION_POINTERS* exceptionInfo) {
+ WCHAR moduleFileName[MAX_PATH];
+
+ DWORD ret = GetModuleFileNameW(NULL, &moduleFileName[0], ARRAYSIZE(moduleFileName));
+ if (ret == 0) {
+ int gle = GetLastError();
+ log() << "GetModuleFileName failed " << errnoWithDescription(gle);
+
+ // Fallback name
+ wcscpy_s(moduleFileName, L"mongo");
+ }
+ else {
+ WCHAR* dotStr = wcschr(&moduleFileName[0], L'.');
+ if (dotStr != NULL) {
+ *dotStr = L'\0';
+ }
}
- }
- std::wstring dumpName(moduleFileName);
+ std::wstring dumpName(moduleFileName);
- std::string currentTime = terseCurrentTime(false);
+ std::string currentTime = terseCurrentTime(false);
- dumpName += L".";
+ dumpName += L".";
- dumpName += toWideString(currentTime.c_str());
+ dumpName += toWideString(currentTime.c_str());
- dumpName += L".mdmp";
+ dumpName += L".mdmp";
- HANDLE hFile = CreateFileW(dumpName.c_str(),
- GENERIC_WRITE,
- 0,
- NULL,
- CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
- if ( INVALID_HANDLE_VALUE == hFile ) {
- DWORD lasterr = GetLastError();
- log() << "failed to open minidump file " << toUtf8String(dumpName.c_str()) << " : "
- << errnoWithDescription( lasterr ) << std::endl;
- return;
- }
+ HANDLE hFile = CreateFileW(dumpName.c_str(),
+ GENERIC_WRITE,
+ 0,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if ( INVALID_HANDLE_VALUE == hFile ) {
+ DWORD lasterr = GetLastError();
+ log() << "failed to open minidump file " << toUtf8String(dumpName.c_str()) << " : "
+ << errnoWithDescription( lasterr ) << std::endl;
+ return;
+ }
- MINIDUMP_EXCEPTION_INFORMATION aMiniDumpInfo;
- aMiniDumpInfo.ThreadId = GetCurrentThreadId();
- aMiniDumpInfo.ExceptionPointers = exceptionInfo;
- aMiniDumpInfo.ClientPointers = FALSE;
+ MINIDUMP_EXCEPTION_INFORMATION aMiniDumpInfo;
+ aMiniDumpInfo.ThreadId = GetCurrentThreadId();
+ aMiniDumpInfo.ExceptionPointers = exceptionInfo;
+ aMiniDumpInfo.ClientPointers = FALSE;
+
+ MINIDUMP_TYPE miniDumpType =
+ #ifdef _DEBUG
+ MiniDumpWithFullMemory;
+ #else
+ static_cast<MINIDUMP_TYPE>(
+ MiniDumpNormal
+ | MiniDumpWithIndirectlyReferencedMemory
+ | MiniDumpWithProcessThreadData);
+ #endif
+ log() << "writing minidump diagnostic file " << toUtf8String(dumpName.c_str()) << std::endl;
+
+ BOOL bstatus = MiniDumpWriteDump(GetCurrentProcess(),
+ GetCurrentProcessId(),
+ hFile,
+ miniDumpType,
+ exceptionInfo != NULL ? &aMiniDumpInfo : NULL,
+ NULL,
+ NULL);
+ if ( FALSE == bstatus ) {
+ DWORD lasterr = GetLastError();
+ log() << "failed to create minidump : "
+ << errnoWithDescription( lasterr ) << std::endl;
+ }
- MINIDUMP_TYPE miniDumpType =
-#ifdef _DEBUG
- MiniDumpWithFullMemory;
-#else
- static_cast<MINIDUMP_TYPE>(
- MiniDumpNormal
- | MiniDumpWithIndirectlyReferencedMemory
- | MiniDumpWithProcessThreadData);
-#endif
- log() << "writing minidump diagnostic file " << toUtf8String(dumpName.c_str()) << std::endl;
-
- BOOL bstatus = MiniDumpWriteDump(GetCurrentProcess(),
- GetCurrentProcessId(),
- hFile,
- miniDumpType,
- &aMiniDumpInfo,
- NULL,
- NULL);
- if ( FALSE == bstatus ) {
- DWORD lasterr = GetLastError();
- log() << "failed to create minidump : "
- << errnoWithDescription( lasterr ) << std::endl;
+ CloseHandle(hFile);
}
- CloseHandle(hFile);
- }
-
- LONG WINAPI exceptionFilter( struct _EXCEPTION_POINTERS *excPointers ) {
- char exceptionString[128];
- sprintf_s( exceptionString, sizeof( exceptionString ),
- ( excPointers->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION ) ?
- "(access violation)" : "0x%08X", excPointers->ExceptionRecord->ExceptionCode );
- char addressString[32];
- sprintf_s( addressString, sizeof( addressString ), "0x%p",
- excPointers->ExceptionRecord->ExceptionAddress );
- log() << "*** unhandled exception " << exceptionString
- << " at " << addressString << ", terminating" << std::endl;
- if ( excPointers->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION ) {
- ULONG acType = excPointers->ExceptionRecord->ExceptionInformation[0];
- const char* acTypeString;
- switch ( acType ) {
- case 0:
- acTypeString = "read from";
- break;
- case 1:
- acTypeString = "write to";
- break;
- case 8:
- acTypeString = "DEP violation at";
- break;
- default:
- acTypeString = "unknown violation at";
- break;
+ LONG WINAPI exceptionFilter( struct _EXCEPTION_POINTERS *excPointers ) {
+ char exceptionString[128];
+ sprintf_s( exceptionString, sizeof( exceptionString ),
+ ( excPointers->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION ) ?
+ "(access violation)" : "0x%08X", excPointers->ExceptionRecord->ExceptionCode );
+ char addressString[32];
+ sprintf_s( addressString, sizeof( addressString ), "0x%p",
+ excPointers->ExceptionRecord->ExceptionAddress );
+ log() << "*** unhandled exception " << exceptionString
+ << " at " << addressString << ", terminating" << std::endl;
+ if ( excPointers->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION ) {
+ ULONG acType = excPointers->ExceptionRecord->ExceptionInformation[0];
+ const char* acTypeString;
+ switch ( acType ) {
+ case 0:
+ acTypeString = "read from";
+ break;
+ case 1:
+ acTypeString = "write to";
+ break;
+ case 8:
+ acTypeString = "DEP violation at";
+ break;
+ default:
+ acTypeString = "unknown violation at";
+ break;
+ }
+ sprintf_s( addressString, sizeof( addressString ), " 0x%p",
+ excPointers->ExceptionRecord->ExceptionInformation[1] );
+ log() << "*** access violation was a " << acTypeString << addressString << std::endl;
}
- sprintf_s( addressString, sizeof( addressString ), " 0x%p",
- excPointers->ExceptionRecord->ExceptionInformation[1] );
- log() << "*** access violation was a " << acTypeString << addressString << std::endl;
- }
- log() << "*** stack trace for unhandled exception:" << std::endl;
+ log() << "*** stack trace for unhandled exception:" << std::endl;
- // Create a copy of context record because printWindowsStackTrace will mutate it.
- CONTEXT contextCopy(*(excPointers->ContextRecord));
+ // Create a copy of context record because printWindowsStackTrace will mutate it.
+ CONTEXT contextCopy(*(excPointers->ContextRecord));
- printWindowsStackTrace( contextCopy );
+ printWindowsStackTrace( contextCopy );
- doMinidump(excPointers);
+ doMinidumpWithException(excPointers);
- // Don't go through normal shutdown procedure. It may make things worse.
- log() << "*** immediate exit due to unhandled exception" << std::endl;
- ::_exit(EXIT_ABRUPT);
+ // Don't go through normal shutdown procedure. It may make things worse.
+ log() << "*** immediate exit due to unhandled exception" << std::endl;
+ ::_exit(EXIT_ABRUPT);
+
+ // We won't reach here
+ return EXCEPTION_EXECUTE_HANDLER;
+ }
+ }
- // We won't reach here
- return EXCEPTION_EXECUTE_HANDLER;
+ void doMinidump() {
+ doMinidumpWithException(NULL);
}
LPTOP_LEVEL_EXCEPTION_FILTER filtLast = 0;