#include <DbgHelp.h>
#pragma comment(lib, "dbghelp.lib")
class CExceptionHandler
{
public:
static CString GetDumpFilename()
{
CString filename;
TCHAR buffer[MAX_PATH];
GetModuleFileName(NULL,buffer,MAX_PATH);
filename = buffer;
int index = filename.ReverseFind(_T('.'));
filename=filename.Left(index);
filename+=_T(".dmp");
return filename;
}
static LONG WINAPI SelfUnhandledExceptionFilter(__in struct _EXCEPTION_POINTERS *ExceptionInfo)
{
USES_CONVERSION;
MINIDUMP_EXCEPTION_INFORMATION ExceptionParam;
ExceptionParam.ThreadId=GetCurrentThreadId();
ExceptionParam.ExceptionPointers=ExceptionInfo;
ExceptionParam.ClientPointers=TRUE;
MINIDUMP_USER_STREAM UserStreams[2];
WCHAR strBulid[MAX_PATH];
StringCchPrintf(strBulid, MAX_PATH, L"Build: %s %s", A2W(__DATE__), A2W(__TIME__));
UserStreams[0].Type=CommentStreamW;
UserStreams[0].Buffer=strBulid;
UserStreams[0].BufferSize=MAX_PATH;
HMODULE hModule;
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
(LPCTSTR)ExceptionInfo->ExceptionRecord->ExceptionAddress,&hModule);
WCHAR strModuleName[MAX_PATH];
GetModuleFileNameW(hModule,strModuleName,MAX_PATH);
WCHAR szError[MAX_PATH*2];
StringCchPrintf(szError,MAX_PATH*2,
L"Module=%s ,Code=%x ,Flag=%x ,Address=%p",
strModuleName,ExceptionInfo->ExceptionRecord->ExceptionCode,
ExceptionInfo->ExceptionRecord->ExceptionFlags,
ExceptionInfo->ExceptionRecord->ExceptionAddress);
UserStreams[1].Type=CommentStreamW;
UserStreams[1].Buffer=szError;
UserStreams[1].BufferSize=MAX_PATH*2;
MINIDUMP_USER_STREAM_INFORMATION UserStreamInfo;
UserStreamInfo.UserStreamArray=UserStreams;
UserStreamInfo.UserStreamCount=2;
CString filename = GetDumpFilename();
HANDLE hFile = CreateFile(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
::MiniDumpWriteDump(GetCurrentProcess(),
GetCurrentProcessId(),
hFile,
MiniDumpWithFullMemory,
&ExceptionParam,
&UserStreamInfo,
NULL
);
return EXCEPTION_EXECUTE_HANDLER;
}
static void Setup()
{
::SetUnhandledExceptionFilter(SelfUnhandledExceptionFilter);
}
};