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

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

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

    头文件:

    //crash_dumper_w32.h
    
    #ifndef _CRASH_DUMPER_H_
    
    #define _CRASH_DUMPER_H_
    
    
    #include <windows.h>
    
    class CrashDumper
    
    {
    
    public:
    
           CrashDumper();
    
           ~CrashDumper();
    
           static bool _PlaceHolder();
    
    private:
    
           LPTOP_LEVEL_EXCEPTION_FILTER m_OriginalFilter;
    
           static LONG WINAPI ExceptionFilter(struct _EXCEPTION_POINTERS* ExceptionInfo);
    
    };
    
    
    namespace
    
    {
           const bool bPlaceHolder = CrashDumper::_PlaceHolder();
    
    }
    
    #endif

    实现文件:

    crash_dumper_w32.cpp
    
     
    
    #include <windows.h>
    
    #include <tchar.h>
    
    #include <dbghelp.h>
    
    #include <string>
    
     
    
    #include "crash_dumper_w32.h"
    
     
    
    #ifdef UNICODE    
    
    #     define tstring wstring     
    
    #else       
    
    #     define tstring string 
    
    #endif
    
     
    
    #pragma comment(lib, "dbghelp.lib")
    
     
    
    CrashDumper dumper;
    
     
    
    CrashDumper::CrashDumper()
    
    {
    
           m_OriginalFilter = SetUnhandledExceptionFilter(ExceptionFilter);
    
    }
    
     
    
    CrashDumper::~CrashDumper()
    
    {
    
           SetUnhandledExceptionFilter(m_OriginalFilter);
    
    }
    
     
    
    LONG WINAPI CrashDumper::ExceptionFilter(struct _EXCEPTION_POINTERS* ExceptionInfo)
    
    {
    
           bool bDumpOK = false;
    
           DWORD dwProcess = GetCurrentProcessId();
    
           HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcess);
    
           if (hProcess != INVALID_HANDLE_VALUE)
    
           {
    
                  TCHAR szPath[MAX_PATH];
    
                  if (GetModuleFileName(NULL, szPath, sizeof(szPath)))
    
                  {
    
                         std::tstring strDumpFileName = szPath;
    
                         strDumpFileName += TEXT(".dmp");
    
                         HANDLE hFile = CreateFile(strDumpFileName.c_str(), FILE_ALL_ACCESS, 0, NULL, CREATE_ALWAYS, NULL, NULL);
    
                         if (hFile != INVALID_HANDLE_VALUE)
    
                         {
    
                                MINIDUMP_EXCEPTION_INFORMATION exception_information;
    
                                exception_information.ThreadId = GetCurrentThreadId();
    
                                exception_information.ExceptionPointers = ExceptionInfo;
    
                                exception_information.ClientPointers = TRUE;
    
                                if (MiniDumpWriteDump(hProcess, dwProcess, hFile, MiniDumpNormal, &exception_information, NULL, NULL))
    
                                {
    
                                       bDumpOK = true;
    
                                }
    
     
    
                                CloseHandle(hFile);
    
                         }
    
                  }
    
     
    
                  CloseHandle(hProcess);
    
           }
    
     
    
           if (bDumpOK)
    
                  MessageBox(NULL, TEXT("本程序遇到未处理的异常,MiniDump文件已经生成在程序的运行目录。"), TEXT("提示"), MB_OK);
    
           else
    
                  MessageBox(NULL, TEXT("本程序遇到未处理的异常,生成MiniDump文件失败。"), TEXT("提示"), MB_OK);
    
     
    
           return EXCEPTION_EXECUTE_HANDLER;
    
    }
     
    
    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文件的代码就被强制链接进来了。

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

  • 相关阅读:
    (剑指Offer)面试题18:树的子结构
    (剑指Offer)面试题17:合并两个排序的链表
    (剑指Offer)面试题16:反转链表
    程序员水平分级 你属于哪一类?
    Hacker
    十分钟让你看懂中国经济形势,10分钟,坚持看完,必有所获~(转载)
    人口问题,怎样的生育率才能保持正常的世代更替?
    理科和文科的区别?
    柴晓霞:做销售要学会画蓝图 (转载)
    工作,为钱还是为理想
  • 原文地址:https://www.cnblogs.com/Lthis/p/4668931.html
Copyright © 2011-2022 走看看