程序崩溃时自动记录minidump的c++类

来源:互联网 发布:nes模拟器源码 编辑:程序博客网 时间:2024/05/29 19:35

程序崩溃时自动记录minidump的c++类

程序崩溃时自动记录minidump的c++类 - Fcoding_狂人 - 博客园

http://www.cnblogs.com/FCoding/archive/2012/07/05/2578557.html

封装了一个C++类,当程序意外崩溃的时候可以生成dump文件,以便确定错误原因。

头文件:

复制代码
 1 //crash_dumper_w32.h 2  3 #ifndef _CRASH_DUMPER_H_ 4  5 #define _CRASH_DUMPER_H_ 6  7  8 #include <windows.h> 9 10 class CrashDumper11 12 {13 14 public:15 16        CrashDumper();17 18        ~CrashDumper();19 20        static bool _PlaceHolder();21 22 private:23 24        LPTOP_LEVEL_EXCEPTION_FILTER m_OriginalFilter;25 26        static LONG WINAPI ExceptionFilter(struct _EXCEPTION_POINTERS* ExceptionInfo);27 28 };29 30 31 namespace32 33 {34        const bool bPlaceHolder = CrashDumper::_PlaceHolder();35 36 }37 38 #endif
复制代码

实现文件:

 

复制代码
  1 crash_dumper_w32.cpp  2   3    4   5 #include <windows.h>  6   7 #include <tchar.h>  8   9 #include <dbghelp.h> 10  11 #include <string> 12  13   14  15 #include "crash_dumper_w32.h" 16  17   18  19 #ifdef UNICODE     20  21 #     define tstring wstring      22  23 #else        24  25 #     define tstring string  26  27 #endif 28  29   30  31 #pragma comment(lib, "dbghelp.lib") 32  33   34  35 CrashDumper dumper; 36  37   38  39 CrashDumper::CrashDumper() 40  41 { 42  43        m_OriginalFilter = SetUnhandledExceptionFilter(ExceptionFilter); 44  45 } 46  47   48  49 CrashDumper::~CrashDumper() 50  51 { 52  53        SetUnhandledExceptionFilter(m_OriginalFilter); 54  55 } 56  57   58  59 LONG WINAPI CrashDumper::ExceptionFilter(struct _EXCEPTION_POINTERS* ExceptionInfo) 60  61 { 62  63        bool bDumpOK = false; 64  65        DWORD dwProcess = GetCurrentProcessId(); 66  67        HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcess); 68  69        if (hProcess != INVALID_HANDLE_VALUE) 70  71        { 72  73               TCHAR szPath[MAX_PATH]; 74  75               if (GetModuleFileName(NULL, szPath, sizeof(szPath))) 76  77               { 78  79                      std::tstring strDumpFileName = szPath; 80  81                      strDumpFileName += TEXT(".dmp"); 82  83                      HANDLE hFile = CreateFile(strDumpFileName.c_str(), FILE_ALL_ACCESS, 0, NULL, CREATE_ALWAYS, NULL, NULL); 84  85                      if (hFile != INVALID_HANDLE_VALUE) 86  87                      { 88  89                             MINIDUMP_EXCEPTION_INFORMATION exception_information; 90  91                             exception_information.ThreadId = GetCurrentThreadId(); 92  93                             exception_information.ExceptionPointers = ExceptionInfo; 94  95                             exception_information.ClientPointers = TRUE; 96  97                             if (MiniDumpWriteDump(hProcess, dwProcess, hFile, MiniDumpNormal, &exception_information, NULL, NULL)) 98  99                             {100 101                                    bDumpOK = true;102 103                             }104 105  106 107                             CloseHandle(hFile);108 109                      }110 111               }112 113  114 115               CloseHandle(hProcess);116 117        }118 119  120 121        if (bDumpOK)122 123               MessageBox(NULL, TEXT("本程序遇到未处理的异常,MiniDump文件已经生成在程序的运行目录。"), TEXT("提示"), MB_OK);124 125        else126 127               MessageBox(NULL, TEXT("本程序遇到未处理的异常,生成MiniDump文件失败。"), TEXT("提示"), MB_OK);128 129  130 131        return EXCEPTION_EXECUTE_HANDLER;132 133 }134  135 136 bool CrashDumper::_PlaceHolder() {return true;}
复制代码

代码很简单,唯一需要提一下的是下面的一句代码,这个技巧是为了解决当crash_dumper_w32.cpp文件被编译成单独的静态库在程序中使用不起作用的问题。

 

namespace

{

       const bool bPlaceHolder = CrashDumper::_PlaceHolder();

}

 

之所以在静态库中.cpp中的代码不起作用,是因为没有代码去调用crash_dumper_w32.cpp的代码,链接的时候就被编译器给丢掉了。上面的语句在匿名空间中定义了一个变量,这样,每一个包含它的.cpp文件就“被迫”创建了一个不可访问的bPlaceHolder变量,而该变量又必须使用CrashDumper::_PlaceHolder()函数来初始化。crash_dumper_w32.cpp文件的代码就被强制链接进来了。

 

此外,如果是服务类型的程序,还可以在异常处理函数中增加自动启动新实例的功能,以保证服务不间断。

0 0
原创粉丝点击