Last active
February 7, 2018 07:11
-
-
Save pps83/582ad5447c3ede28ad38dcebf23d0789 to your computer and use it in GitHub Desktop.
WriteMinidumpForException
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Windows.h> | |
#include <stdio.h> | |
// fullDump enables MiniDumpWithFullMemory, and results in dmp files to be over 100MB in size (as opposed to default which is only 100KB). | |
// With fullDump Visual Studio is able to display proper backtrace for unhandled c++ exception. Without fullDump WinDBG has to be used. | |
static int WriteMinidumpForException(EXCEPTION_POINTERS* e, bool fullDump) | |
{ | |
HMODULE dbghelp = LoadLibraryA("DbgHelp.dll"); // Note: no matching FreeLibrary | |
if (!dbghelp) | |
return EXCEPTION_CONTINUE_SEARCH; | |
typedef BOOL(WINAPI * MiniDumpWriteDump_func)(HANDLE hProcess, DWORD ProcessId, HANDLE hFile, | |
DWORD DumpType, PVOID ExceptionParam, PVOID UserStreamParam, PVOID CallbackParam); | |
MiniDumpWriteDump_func writeDump = (MiniDumpWriteDump_func)GetProcAddress(dbghelp, "MiniDumpWriteDump"); | |
if (!writeDump) | |
return EXCEPTION_CONTINUE_SEARCH; | |
char dmpSuffix[128]; | |
GetDateFormatA(LOCALE_NEUTRAL, 0, 0, "'.'MMM'_'dd'_'", dmpSuffix, sizeof(dmpSuffix) - 1); | |
GetTimeFormatA(LOCALE_NEUTRAL, 0, 0, "HH'h'mm'm'ss's'", dmpSuffix + strlen(dmpSuffix), sizeof(dmpSuffix) - 1 - strlen(dmpSuffix)); | |
LARGE_INTEGER li; | |
QueryPerformanceCounter(&li); | |
sprintf(dmpSuffix + strlen(dmpSuffix), "_rnd%u", li.LowPart % 100000); | |
strcat(dmpSuffix, ".dmp"); | |
WCHAR outfile[MAX_PATH + 128]; | |
GetModuleFileNameW(NULL, outfile, MAX_PATH); // use __ImageBase for dlls? | |
for (int i = 0, plen = wcslen(outfile), dlen = 1 + strlen(dmpSuffix); i < dlen && i + plen < sizeof(outfile) / sizeof(outfile[0]); ++i) | |
outfile[plen + i] = dmpSuffix[i]; | |
HANDLE fl = ::CreateFileW(outfile, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); | |
if (fl == INVALID_HANDLE_VALUE) | |
return EXCEPTION_CONTINUE_SEARCH; | |
struct MINIDUMP_EXCEPTION_INFORMATION | |
{ | |
DWORD ThreadId; | |
PEXCEPTION_POINTERS ExceptionPointers; | |
BOOL ClientPointers; | |
}; | |
MINIDUMP_EXCEPTION_INFORMATION excInfo; | |
excInfo.ThreadId = GetCurrentThreadId(); | |
excInfo.ExceptionPointers = e; | |
excInfo.ClientPointers = TRUE; | |
DWORD dumpType = fullDump ? 2/*MiniDumpWithFullMemory*/ : 0/*MiniDumpNormal*/; | |
if (!writeDump(GetCurrentProcess(), GetCurrentProcessId(), fl, dumpType, &excInfo, NULL, NULL)) | |
return EXCEPTION_CONTINUE_SEARCH; | |
return EXCEPTION_EXECUTE_HANDLER; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment