// USAGE: Add the below lines on the top of the body of main.cpp
//
// // sets the minimum size of the stack
// ULONG size = 1024 * 16; // 1 MB * 16
// SetThreadStackGuarantee(&size); // extends the stack to the given size
//
// // enables an application to supersede the top-level exception handler
// SetUnhandledExceptionFilter(ExceptionFilter_Callback);
#pragma once
#include <windows.h> // for Dbghelp.h
#include <Dbghelp.h> // use minidump
#pragma comment(lib, "dbghelp.lib") // link with dbghelp.lib
bool WriteDump(EXCEPTION_POINTERS* pException)
{
char dumpName[MAX_PATH];
char* appName = dumpName + GetModuleFileNameA(GetModuleHandleA(0), dumpName, MAX_PATH);
SYSTEMTIME currTime;
GetSystemTime(&currTime);
wsprintfA(appName - strlen(".exe"), // only get its name, not the extension
"_%4d%02d%02d_%02d%02d%02d.dmp", // to make a unique file name, use the current time
currTime.wYear, currTime.wMonth, currTime.wDay,
currTime.wHour, currTime.wMinute, currTime.wSecond);
// file handle of where to save to
HANDLE hFile = CreateFileA(dumpName, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (hFile == INVALID_HANDLE_VALUE)
{
printf("Creating Dump File is failed.\n");
return false;
}
// since debugging is used for a crash
MINIDUMP_EXCEPTION_INFORMATION exceptionInfo;
exceptionInfo.ThreadId = GetCurrentThreadId();
// comes from the exception
exceptionInfo.ExceptionPointers = pException;
// used when writing a dump for a different process
exceptionInfo.ClientPointers = FALSE;
MiniDumpWriteDump(
GetCurrentProcess(),
GetCurrentProcessId(),
hFile,
// Little Dump: Partial information but still useful
MINIDUMP_TYPE(MiniDumpNormal),
pException ? &exceptionInfo : nullptr,
nullptr,
nullptr);
CloseHandle(hFile);
return true;
}
LONG CALLBACK ExceptionFilter_Callback(EXCEPTION_POINTERS* pException)
{
// creates a file and write the dump on it
if(WriteDump(pException) == false)
printf("Logging Minidump is failed.\n");
// do not return EXCEPTION_EXECUTE_HANDLER
// the crash handler does NOT inhibit normal behavior
return EXCEPTION_CONTINUE_SEARCH; // it means obeying the SetErrorMode flags
}