Skip to content

Instantly share code, notes, and snippets.

@pps83
Last active February 7, 2018 07:11
Show Gist options
  • Save pps83/582ad5447c3ede28ad38dcebf23d0789 to your computer and use it in GitHub Desktop.
Save pps83/582ad5447c3ede28ad38dcebf23d0789 to your computer and use it in GitHub Desktop.
WriteMinidumpForException
#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