Skip to content

Commit

Permalink
write minidumps for unhandled exceptions on Windows
Browse files Browse the repository at this point in the history
This will write a file mongo.dmp in the current directory when you crash.
You can open this dump with windbg and examine all thread stacks and locals.
To read and parse the exception details, issue the .ecxr command.
  • Loading branch information
milkie committed Apr 24, 2012
1 parent 5dda12c commit 86b4fde
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 1 deletion.
2 changes: 1 addition & 1 deletion SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -625,7 +625,7 @@ elif "win32" == os.sys.platform:
else:
env.Append( LINKFLAGS=" /NODEFAULTLIB:MSVCPRT /NODEFAULTLIB:MSVCRT " )

winLibString = "ws2_32.lib kernel32.lib advapi32.lib Psapi.lib"
winLibString = "ws2_32.lib kernel32.lib advapi32.lib Psapi.lib DbgHelp.lib"

if force64:

Expand Down
45 changes: 45 additions & 0 deletions src/mongo/db/db.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@

#if defined(_WIN32)
# include "../util/ntservice.h"
# include <DbgHelp.h>
#else
# include <sys/file.h>
#endif
Expand Down Expand Up @@ -1253,6 +1254,48 @@ namespace mongo {

LPTOP_LEVEL_EXCEPTION_FILTER filtLast = 0;

/* 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
*/
void doMinidump(struct _EXCEPTION_POINTERS* exceptionInfo) {
LPCWSTR dumpFilename = L"mongo.dmp";
HANDLE hFile = CreateFileW(dumpFilename,
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if ( INVALID_HANDLE_VALUE == hFile ) {
DWORD lasterr = GetLastError();
log() << "failed to open minidump file " << dumpFilename << " : "
<< errnoWithDescription( lasterr ) << endl;
return;
}

MINIDUMP_EXCEPTION_INFORMATION aMiniDumpInfo;
aMiniDumpInfo.ThreadId = GetCurrentThreadId();
aMiniDumpInfo.ExceptionPointers = exceptionInfo;
aMiniDumpInfo.ClientPointers = TRUE;

log() << "writing minidump dignostic file " << dumpFilename << endl;
BOOL bstatus = MiniDumpWriteDump(GetCurrentProcess(),
GetCurrentProcessId(),
hFile,
MiniDumpNormal,
&aMiniDumpInfo,
NULL,
NULL);
if ( FALSE == bstatus ) {
DWORD lasterr = GetLastError();
log() << "failed to create minidump : "
<< errnoWithDescription( lasterr ) << endl;
}

CloseHandle(hFile);
}

LONG WINAPI exceptionFilter( struct _EXCEPTION_POINTERS *excPointers ) {
char exceptionString[128];
sprintf_s( exceptionString, sizeof( exceptionString ),
Expand Down Expand Up @@ -1285,6 +1328,8 @@ namespace mongo {
log() << "*** access violation was a " << acTypeString << addressString << endl;
}

doMinidump(excPointers);

// In release builds, let dbexit() try to shut down cleanly
#if !defined(_DEBUG)
dbexit( EXIT_UNCAUGHT, "unhandled exception" );
Expand Down

0 comments on commit 86b4fde

Please sign in to comment.