Skip to content

Instantly share code, notes, and snippets.

@adamjs
Created August 6, 2024 21:23
Show Gist options
  • Save adamjs/8f20df17e1b8c3945863eca9c91a97ce to your computer and use it in GitHub Desktop.
Save adamjs/8f20df17e1b8c3945863eca9c91a97ce to your computer and use it in GitHub Desktop.
Utility code to log crashes to .dmp files on Windows for remote debugging
#include <windows.h>
#include <dbghelp.h>
#include <iostream>
#include <strsafe.h>
// Link with the DbgHelp.lib
#pragma comment(lib, "dbghelp.lib")
// Function to create the dump file
void CreateDump(EXCEPTION_POINTERS* pExceptionPointers, TCHAR* szFileName)
{
// Define the dump file path
TCHAR szPath[MAX_PATH];
SYSTEMTIME st;
GetSystemTime(&st);
GetTempPath(MAX_PATH, szPath);
StringCchPrintf(szFileName, MAX_PATH, TEXT("%s%s_%04d%02d%02d_%02d%02d%02d.dmp"), szPath, TEXT("MyAppCrashDump"),
st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
// Create the dump file
HANDLE hDumpFile = CreateFile(szFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hDumpFile != INVALID_HANDLE_VALUE)
{
MINIDUMP_EXCEPTION_INFORMATION dumpInfo;
dumpInfo.ThreadId = GetCurrentThreadId();
dumpInfo.ExceptionPointers = pExceptionPointers;
dumpInfo.ClientPointers = TRUE;
// Write the dump file
MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpWithDataSegs, &dumpInfo, NULL, NULL);
CloseHandle(hDumpFile);
}
}
// Custom unhandled exception filter
LONG WINAPI CustomUnhandledExceptionFilter(EXCEPTION_POINTERS* pExceptionPointers)
{
TCHAR szFileName[MAX_PATH];
CreateDump(pExceptionPointers, szFileName);
// Copy file path to clipboard
if (OpenClipboard(NULL))
{
EmptyClipboard();
size_t size = (lstrlen(szFileName) + 1) * sizeof(TCHAR);
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, size);
if (hMem)
{
memcpy(GlobalLock(hMem), szFileName, size);
GlobalUnlock(hMem);
SetClipboardData(CF_UNICODETEXT, hMem);
}
CloseClipboard();
}
// Show a message box with the dump file location
TCHAR szMessage[MAX_PATH + 50];
StringCchPrintf(szMessage, MAX_PATH + 50, TEXT("The application has crashed.\nA dump file has been created and the path has been copied to the clipboard:\n%s"), szFileName);
MessageBox(NULL, szMessage, TEXT("Application Crash"), MB_OK | MB_ICONERROR);
return EXCEPTION_EXECUTE_HANDLER;
}
// Function to cause a crash (access violation)
void CauseCrash()
{
int* p = nullptr;
*p = 0; // CRASH!!
}
int main()
{
// Only install our custom unhandled exception filter if the debugger isn't attached.
if (!IsDebuggerPresent())
{
// Set the custom unhandled exception filter
SetUnhandledExceptionFilter(CustomUnhandledExceptionFilter);
}
std::cout << "This app will crash to test crash dump logging." << std::endl;
// Cause a crash
CauseCrash();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment