转载:https://www.easyicon.net/(免费icon)
转载:https://www.codeproject.com/Articles/5260/XCrashReport-Exception-Handling-and-Crash-Report-4(codeproject示例demo)
转载:https://blog.csdn.net/agan4014/article/details/2614770
转载:http://blog.sina.com.cn/s/blog_5513eb7b0100nu80.html
转载:https://blog.csdn.net/sunflover454/article/details/51200663
实现原理:在程序运行过程中异常,通过捕获异常,并在回调函数启动BugReport程序
实现效果
第一步:导入上面的源码文件到自己的工程中
CrashFileNames.h
#ifndef CRASHFILENAMES_H #define CRASHFILENAMES_H #define XCRASHREPORT_MINI_DUMP_FILE _T("CRASH.DMP")//Crash文件 #define XCRASHREPORT_ERROR_LOG_FILE _T("ERRORLOG.TXT")//日志文件 #define XCRASHREPORT_CRASH_REPORT_APP _T("xxxBugReport.exe")//你自己BugReport程序名字 #endif //CRASHFILENAMES_H
ExceptionHandler.h
#ifndef EXCEPTIONHANDLER_H #define EXCEPTIONHANDLER_H typedef struct _EXCEPTION_POINTERS EXCEPTION_POINTERS, *PEXCEPTION_POINTERS; int __cdecl RecordExceptionInfo(PEXCEPTION_POINTERS data, const TCHAR *Message); #endif
ExceptionHandler.cpp
#pragma warning(disable : 4514) #pragma warning(disable : 4201) #define _WIN32_WINDOWS 0x0500 // for IsDebuggerPresent // comment out this line if you don't want minidumps #define XCRASHREPORT_WRITE_MINIDUMP //#define XCRASHREPORT_WRITE_ERROR_LOG // does not require MFC; use 'Not using precompiled headers' #include "windows.h" #include <tchar.h> #include "GetWinVer.h" #include "miniversion.h" #include <DbgHelp.h> #include "CrashFileNames.h" #pragma comment(lib, "Dbghelp.lib") #ifndef _countof #define _countof(array) (sizeof(array)/sizeof(array[0])) #endif const int NumCodeBytes = 16; // Number of code bytes to record. const int MaxStackDump = 3072; // Maximum number of DWORDS in stack dumps. const int StackColumns = 4; // Number of columns in stack dump. #define ONEK 1024 #define SIXTYFOURK (64*ONEK) #define ONEM (ONEK*ONEK) #define ONEG (ONEK*ONEK*ONEK) /////////////////////////////////////////////////////////////////////////////// // lstrrchr (avoid the C Runtime ) static TCHAR * lstrrchr(LPCTSTR string, int ch) { TCHAR *start = (TCHAR *)string; while (*string++) /* find end of string */ ; /* search towards front */ while (--string != start && *string != (TCHAR) ch) ; if (*string == (TCHAR) ch) /* char found ? */ return (TCHAR *)string; return NULL; } #define HPRINTF_BUFFER_SIZE (8*1024) // must be at least 2048 static TCHAR hprintf_buffer[HPRINTF_BUFFER_SIZE]; // wvsprintf never prints more than one K. static int hprintf_index = 0; /////////////////////////////////////////////////////////////////////////////// // hflush static void hflush(HANDLE LogFile) { if (hprintf_index > 0) { DWORD NumBytes; WriteFile(LogFile, hprintf_buffer, lstrlen(hprintf_buffer), &NumBytes, 0); hprintf_index = 0; } } /////////////////////////////////////////////////////////////////////////////// // hprintf static void hprintf(HANDLE LogFile, LPCTSTR Format, ...) { if (hprintf_index > (HPRINTF_BUFFER_SIZE-1024)) { DWORD NumBytes; WriteFile(LogFile, hprintf_buffer, lstrlen(hprintf_buffer), &NumBytes, 0); hprintf_index = 0; } va_list arglist; va_start( arglist, Format); hprintf_index += wvsprintf(&hprintf_buffer[hprintf_index], Format, arglist); va_end( arglist); } #ifdef XCRASHREPORT_WRITE_MINIDUMP /////////////////////////////////////////////////////////////////////////////// // DumpMiniDump static void DumpMiniDump(HANDLE hFile, PEXCEPTION_POINTERS excpInfo) { if (excpInfo == NULL) { // Generate exception to get proper context in dump __try { OutputDebugString(_T("raising exception ")); RaiseException(EXCEPTION_BREAKPOINT, 0, 0, NULL); } __except(DumpMiniDump(hFile, GetExceptionInformation()), EXCEPTION_CONTINUE_EXECUTION) { } } else { OutputDebugString(_T("writing minidump ")); MINIDUMP_EXCEPTION_INFORMATION eInfo; eInfo.ThreadId = GetCurrentThreadId(); eInfo.ExceptionPointers = excpInfo; eInfo.ClientPointers = FALSE; // note: MiniDumpWithIndirectlyReferencedMemory does not work on Win98 MiniDumpWriteDump( GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, excpInfo ? &eInfo : NULL, NULL, NULL); } } #endif // XCRASHREPORT_WRITE_MINIDUMP /////////////////////////////////////////////////////////////////////////////// // FormatTime // // Format the specified FILETIME to output in a human readable format, // without using the C run time. static void FormatTime(LPTSTR output, FILETIME TimeToPrint) { output[0] = _T('