过滤release下因异常而弹出的对话框

debugreport.h

#pragma once void InitReporter(const char * pszSavePath);

debugreport.cpp

#include "StdAfx.h" #include #include "debugreport.h" // typedef BOOL (WINAPI *MiniDumpWriteDump_type)( HANDLE hProcess, DWORD dwPid, HANDLE hFile, MINIDUMP_TYPE DumpType, CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam); #pragma data_seg(".amy_Handler") static HANDLE handler_thread_ = 0; static HANDLE handler_event = 0; static HANDLE handler_event2 = 0; static CRITICAL_SECTION critical_lock; static bool g_bNeedWriteDump = true; static HANDLE handler_file = INVALID_HANDLE_VALUE; CString g_crash_file_name; static HMODULE dbghelp_module_; static MiniDumpWriteDump_type minidump_write_dump_; static MINIDUMP_TYPE dump_type_; static const int kWaitForHandlerThreadMs = 60000; static const int kExceptionHandlerThreadInitialStackSize = 64 * 1024; struct MYEXCEPTINFO { DWORD requesting_thread_id_; // The exception info passed to the exception handler on the exception // thread, if an exception occurred. NULL for user-requested dumps. EXCEPTION_POINTERS* exception_info_; BOOL except_ret; }; static MYEXCEPTINFO except_info = { 0 }; #pragma data_seg() DWORD WINAPI ExceptionHandlerThreadMain(void* lpParameter) { WaitForSingleObject(handler_event, INFINITE); if (!g_bNeedWriteDump) { SetEvent(handler_event2); return 0; } EnterCriticalSection(&critical_lock); handler_file = CreateFile(g_crash_file_name, GENERIC_WRITE, 0, // no sharing NULL, CREATE_ALWAYS, // fail if exists FILE_ATTRIBUTE_NORMAL, NULL); if (minidump_write_dump_ && (handler_file != INVALID_HANDLE_VALUE)) { MINIDUMP_EXCEPTION_INFORMATION einfo; einfo.ThreadId = except_info.requesting_thread_id_; einfo.ExceptionPointers = except_info.exception_info_; einfo.ClientPointers = FALSE; except_info.except_ret = minidump_write_dump_(GetCurrentProcess(), GetCurrentProcessId(), handler_file, MiniDumpNormal, &einfo, NULL, NULL); } if(handler_file != INVALID_HANDLE_VALUE) { CloseHandle(handler_file); handler_file = INVALID_HANDLE_VALUE; } LeaveCriticalSection (&critical_lock); SetEvent(handler_event2); return 0; } BOOL WriteMinidumpWithException(struct _EXCEPTION_POINTERS* ExceptionInfo) { EnterCriticalSection(&critical_lock); except_info.requesting_thread_id_ = GetCurrentThreadId(); except_info.exception_info_ = ExceptionInfo; LeaveCriticalSection (&critical_lock); SetEvent(handler_event); if(WaitForSingleObject(handler_event2, kWaitForHandlerThreadMs ) == WAIT_TIMEOUT) { ExitProcess(-2); } return except_info.except_ret; } LONG WINAPI ExceptionFilter(struct _EXCEPTION_POINTERS* ExceptionInfo) { DWORD code = ExceptionInfo->ExceptionRecord->ExceptionCode; bool is_debug_exception = (code == EXCEPTION_BREAKPOINT) || (code == EXCEPTION_SINGLE_STEP); BOOL success = FALSE; if(!is_debug_exception) { success = WriteMinidumpWithException(ExceptionInfo); } if (success) { ExitProcess(-1); return EXCEPTION_EXECUTE_HANDLER; } else { // There was an exception, it was a breakpoint or something else ignored // above, or it was passed to the handler, which decided not to handle it. // This could be because the filter callback didn't want it, because // minidump writing failed for some reason, or because the post-minidump // callback function indicated failure. Give the previous handler a // chance to do something with the exception. If there is no previous // handler, return EXCEPTION_CONTINUE_SEARCH, which will allow a debugger // or native "crashed" dialog to handle the exception. return EXCEPTION_CONTINUE_SEARCH; } } void InitReporter(const char * pszSavePath) { InitializeCriticalSection(&critical_lock); handler_event = CreateEvent(NULL, FALSE, FALSE, NULL); handler_event2 = CreateEvent(NULL, FALSE, FALSE, NULL); dbghelp_module_ = LoadLibrary(_T("dbghelp.dll")); if (dbghelp_module_) { minidump_write_dump_ = reinterpret_cast( GetProcAddress(dbghelp_module_, "MiniDumpWriteDump")); } if(minidump_write_dump_) { TCHAR szFileName[_MAX_PATH] = {0}; __time32_t t; _time32(&t); _stprintf(szFileName, TEXT("%s//crash_RelationSvr_%d.dmp"), pszSavePath, t); g_crash_file_name = szFileName; } DWORD thread_id; handler_thread_ = CreateThread(NULL, // lpThreadAttributes kExceptionHandlerThreadInitialStackSize, ExceptionHandlerThreadMain, 0, // lpParameter 0, // dwCreationFlags &thread_id); _CrtSetReportMode(_CRT_ASSERT, 0); SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_NOGPFAULTERRORBOX ); SetUnhandledExceptionFilter(&ExceptionFilter); }

使用:

 

在程序初始化的地方调用InitReporter,把_stprintf(szFileName, TEXT("%s//crash_batchreship_%d.dmp"), GetModulePath().c_str(), t);改成程序自己的dump文件即可

你可能感兴趣的:(转载技术文章)