// MiniDumpWriteDump.cpp : コンソール アプリケーション用のエントリ ポイントの定義 // #include #include // マルチスレッド版でコンパイルしないと _beginthreadex が見つからないエラーになります。 #include typedef enum _MINIDUMP_TYPE { MiniDumpNormal = 0x00000000, MiniDumpWithDataSegs = 0x00000001, MiniDumpWithFullMemory = 0x00000002, MiniDumpWithHandleData = 0x00000004, MiniDumpFilterMemory = 0x00000008, MiniDumpScanMemory = 0x00000010, MiniDumpWithUnloadedModules = 0x00000020, MiniDumpWithIndirectlyReferencedMemory = 0x00000040, MiniDumpFilterModulePaths = 0x00000080, MiniDumpWithProcessThreadData = 0x00000100, MiniDumpWithPrivateReadWriteMemory = 0x00000200, MiniDumpWithoutOptionalData = 0x00000400, MiniDumpWithFullMemoryInfo = 0x00000800, MiniDumpWithThreadInfo = 0x00001000, MiniDumpWithCodeSegs = 0x00002000, MiniDumpWithoutAuxiliaryState = 0x00004000, MiniDumpWithFullAuxiliaryState = 0x00008000, MiniDumpValidTypeFlags = 0x0000ffff, } MINIDUMP_TYPE; #include typedef struct _MINIDUMP_EXCEPTION_INFORMATION { DWORD ThreadId; PEXCEPTION_POINTERS ExceptionPointers; BOOL ClientPointers; } MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION; typedef struct _MINIDUMP_EXCEPTION_INFORMATION64 { DWORD ThreadId; ULONG64 ExceptionRecord; ULONG64 ContextRecord; BOOL ClientPointers; } MINIDUMP_EXCEPTION_INFORMATION64, *PMINIDUMP_EXCEPTION_INFORMATION64; #include typedef BOOL (WINAPI *PFN_MiniDumpWriteDump)( HANDLE hProcess, DWORD ProcessId, HANDLE hFile, MINIDUMP_TYPE DumpType, CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, CONST PVOID UserStreamParam, CONST PVOID CallbackParam ); HMODULE g_hModuleDbgHelp = NULL; PFN_MiniDumpWriteDump g_pfn_MiniDumpWriteDump = NULL; static LPTOP_LEVEL_EXCEPTION_FILTER g_pfn_OrigFilter = NULL; static LONG __stdcall CrashHandlerExceptionFilter( EXCEPTION_POINTERS * pExPtrs ); unsigned int WINAPI DumpThread( LPVOID pData ) { EXCEPTION_POINTERS * pParams = (EXCEPTION_POINTERS *)pData; HANDLE hProcess = NULL; hProcess = ::GetCurrentProcess(); DWORD dwProcessId = 0; dwProcessId = ::GetCurrentProcessId(); HANDLE hFile = INVALID_HANDLE_VALUE; hFile = ::CreateFile( "minidump.dmp", GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, // share NULL, // securityattr CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); if ( hFile != INVALID_HANDLE_VALUE ) { BOOL BRet = FALSE; MINIDUMP_EXCEPTION_INFORMATION stExceptionInfo; ZeroMemory( &(stExceptionInfo), sizeof(stExceptionInfo) ); stExceptionInfo.ThreadId = ::GetCurrentThreadId(); stExceptionInfo.ClientPointers = FALSE; stExceptionInfo.ExceptionPointers = pParams; BRet = g_pfn_MiniDumpWriteDump( hProcess, dwProcessId, hFile, MiniDumpNormal, &(stExceptionInfo), NULL, NULL ); if ( BRet ) { ::OutputDebugString( "MiniDumpWriteDump succeeded\n" ); } else { ::OutputDebugString( "MiniDumpWriteDump failed\n" ); } } ::CloseHandle( hFile ); hFile = NULL; return TRUE; } static LONG __stdcall CrashHandlerExceptionFilter( EXCEPTION_POINTERS * pExPtrs ) { // OS のクラッシュハンドラが起動して Microsoft に情報を送るかどうかのダイアログを表示 LONG lRet = EXCEPTION_CONTINUE_SEARCH; // OS のクラッシュハンドラを起動しないようになります。 //LONG lRet = EXCEPTION_EXECUTE_HANDLER; if ( g_pfn_MiniDumpWriteDump == NULL ) { // OS のクラッシュハンドラが起動して Microsoft に情報を送るかどうかのダイアログを表示 lRet = EXCEPTION_CONTINUE_SEARCH; return lRet; } { unsigned int dwThreadId = 0; HANDLE hThread = (HANDLE) ::_beginthreadex( NULL, 0, DumpThread, pExPtrs, 0, &dwThreadId ); if ( hThread != (HANDLE)-1 ) { // 本当はリトライ処理入れたほうがいいです。 ::WaitForSingleObject( hThread, INFINITE ); ::CloseHandle( hThread ); hThread = NULL; // OS のクラッシュハンドラを起動しないようになります。 lRet = EXCEPTION_EXECUTE_HANDLER; } } return lRet; } void setMyCrashHandler( void ) { g_pfn_OrigFilter = ::SetUnhandledExceptionFilter( CrashHandlerExceptionFilter ); } void unsetMyCrashHandler( void ) { if ( g_pfn_OrigFilter ) { ::SetUnhandledExceptionFilter( g_pfn_OrigFilter ); } } void crashMe( void ) { int i = 10; int j = 0; int k = 0; k = i/j; } int main(int argc, char* argv[]) { printf("Hello World!\n"); g_hModuleDbgHelp = NULL; g_hModuleDbgHelp = ::LoadLibrary( "dbghelp.dll" ); if ( g_hModuleDbgHelp ) { g_pfn_MiniDumpWriteDump = (PFN_MiniDumpWriteDump)::GetProcAddress( g_hModuleDbgHelp, "MiniDumpWriteDump" ); } setMyCrashHandler(); crashMe(); unsetMyCrashHandler(); if ( g_hModuleDbgHelp ) { g_pfn_MiniDumpWriteDump = NULL; ::FreeLibrary( g_hModuleDbgHelp ); g_hModuleDbgHelp = NULL; } return 0; }