zoukankan      html  css  js  c++  java
  • 程序崩溃时自动记录minidump的c++类

    封装了一个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 CrashDumper
    11 
    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 namespace
    32 
    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        else
    126 
    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文件的代码就被强制链接进来了。

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

  • 相关阅读:
    在图片上面添加字体
    wampserver php 识别不了>或者尖括号 php.ini中short_open_tag设置方法
    [P5162] WD与积木
    [P5170] 类欧几里得算法
    [P5172] Sum
    [HEOI2014] 大工程
    [P4721] 分治 FFT
    [BJOI2017] 树的难题
    [P4886] 快递员
    [CERC2014] Virus synthesis
  • 原文地址:https://www.cnblogs.com/FCoding/p/2578557.html
Copyright © 2011-2022 走看看