zoukankan      html  css  js  c++  java
  • google breakpad 使用初步总结


    项目地址:https://code.google.com/p/google-breakpad/    访问不了请挂VPN

    这是一个由google主导的开源项目,官方介绍为:An open-source multi-platform crash reporting system,即 开源的多平台崩溃上报系统。
    这是由google员工在工作中那20%的自由创造时间创造的作品,真正对技术热爱的人才会在自由时间改变世界,只完成工作的人永远只能做一把被人用完就丢的枪。

    言归正传,google breakpad 支持iOS linux windows,
    linux的崩溃捕获机制我比较熟悉,做好信号处理已经能搞定一大半了;
    但是我对windows的崩溃捕获机制仅限于SEH,SEH无法满足所有场景的崩溃捕获(当然google breakpad也不能满足所有场景),
    所以本文主要描述在windows平台上如何使用google breakpad捕获崩溃。

    源码下载:
    使用svn下载即可,不会可以点右上角的红X。

    源码结构:主要在src的目录下
    build:    编译脚本
    client:主要包括捕获以及dump代码
    common:通用支持代码
    google_breakpad:breakpad使用的公共支持代码
    processor:崩溃处理核心代码
    testing:测试代码
    third_party:第三方支持库
    tools:一些小工具,用于处理dump文件和符号表

    支持的捕获方式:
    在exception_handler.h文件中可以看到以下定义:

      enum HandlerType {
        HANDLER_NONE = 0,
        HANDLER_EXCEPTION = 1 << 0,          // SetUnhandledExceptionFilter
        HANDLER_INVALID_PARAMETER = 1 << 1,  // _set_invalid_parameter_handler
        HANDLER_PURECALL = 1 << 2,           // _set_purecall_handler
        HANDLER_ALL = HANDLER_EXCEPTION |
                      HANDLER_INVALID_PARAMETER |
                      HANDLER_PURECALL
      };
    


    也就是有这3种捕获方式:
    1.HANDLER_EXCEPTION    -    即使用 SetUnhandledExceptionFilter 函数捕获,也就是大家熟知的SEH
    2.HANDLER_INVALID_PARAMETER    -    使用 _set_purecall_handler 捕获纯虚函数导致的崩溃
    3.HANDLER_PURECALL            -    使用 _set_invalid_parameter_handler 捕获错误参数调用导致的崩溃


    google breakpad 是一套系统,支持dump文件的上传,上传是通过crash_report_sender完成的,协议使用http,Lib使用wininet,本文只做比较基础的本地dump用法演示,
    整套c/s架构演示待我有时间后添加吧。


    google breakpad 支持进程内捕获、进程外捕获,各有优劣:
    进程外捕获:
        不会被崩溃进程自身影响,dump过程比较不易出现缺失信息、出错等问题;
        但是堆栈溢出有可能抓不到,死锁处理不了(这也不是崩溃)。

    进程内捕获:
        有可能影响到自身的dump过程。

    这玩意的选择自己看着办吧,我这里主要演示如何进程内捕获。

    如何使用:
    先简单看看代码调用方法,其实很简单,就是声明一个ExceptionHandler对象,ExceptionHandler构造函数如下:

    ExceptionHandler(const wstring& dump_path,        //dump文件存储路径
                       FilterCallback filter,        //在写minidump之前调用,根据返回值决定是否dump
                       MinidumpCallback callback,    //写入minidump后调用
                       void* callback_context,        //上下文,不需要就NULL
                       int handler_types);            //指定需要安装的handle类型, 一般 ExceptionHandler::HANDLER_ALL 搞定
                       
      ExceptionHandler(const wstring& dump_path,
                       FilterCallback filter,
                       MinidumpCallback callback,
                       void* callback_context,
                       int handler_types,
                       MINIDUMP_TYPE dump_type,        //MINIDUMP_TYPE类型
                       const wchar_t* pipe_name,    //管道名,用于进程外捕获时的进程间通信
                       const CustomClientInfo* custom_info);    //客户端信息
                       
      ExceptionHandler(const wstring& dump_path,
                       FilterCallback filter,
                       MinidumpCallback callback,
                       void* callback_context,
                       int handler_types,
                       MINIDUMP_TYPE dump_type,
                       HANDLE pipe_handle,            
                       const CustomClientInfo* custom_info);
                       
      ExceptionHandler(const wstring& dump_path,
                       FilterCallback filter,
                       MinidumpCallback callback,
                       void* callback_context,
                       int handler_types,
                       CrashGenerationClient* crash_generation_client);
    


                
                
    在windows平台编译安装:
    环境:win8 + vs2010

    1.下载源文件
    2.生成工程:
    (1)安装python2.7,讲python2.7的安装目录设置到环境变量的path中,cmd中输入python能调用到python就算成功了
    (2)打开一个cmd,进入google_breakpad目录
    (3)    set GYP_MSVS_VERSION=2010
            src oolsgypgyp.bat --no-circular-check srcclientwindowsreakpad_client.gyp
    (4)sln文件会生成到srcclientwindows目录
    (5)使用sln编译,lib文件会生成到google_breakpadsrcclientwindowsdebug or release目录中
    友情提示:项目默认是编译mt的,可以自己根据需求修改


    以下开始真正的调用方法:

    //一些需要的头文件
    #include <windows.h>
    #include <tchar.h>
    
    #include "google_breakpad/client/windows/crash_generation/client_info.h"
    #include "google_breakpad/client/windows/crash_generation/crash_generation_server.h"
    #include "google_breakpad/client/windows/handler/exception_handler.h"
    #include "google_breakpad/client/windows/common/ipc_protocol.h"
    
    //库
    #pragma comment(lib, "exception_handler.lib")
    #pragma comment(lib, "common.lib")
    #pragma comment(lib, "crash_generation_client.lib")
    #pragma comment(lib, "crash_generation_server.lib")
    
    //定义静态的对象
    using namespace google_breakpad;
    static ExceptionHandler* handler = NULL;
    



    实现dump后处理函数:

    bool ShowDumpResults(const wchar_t* dump_path,
        const wchar_t* minidump_id,
        void* context,
        EXCEPTION_POINTERS* exinfo,
        MDRawAssertionInfo* assertion,
        bool succeeded)
    {
        //MessageBox(NULL, _T("aa"), _T("bb"), 0);
    
    
        TCHAR* text = new TCHAR[1024];
        text[0] = _T('');
        int result = swprintf_s(text,
            1024,
            TEXT("Dump generation request %s
    "),
            succeeded ? TEXT("succeeded") : TEXT("failed"));
        if (result == -1) {
            delete [] text;
        }
    
        return succeeded;
    }
    



    在_tWinMain中创建对象:

    wstring wszDumpSavePath = L"F:\dumptest\";                //保存dump文件的路径,可以动态获取自身的路径
        handler = new ExceptionHandler(wszDumpSavePath.c_str(),    
            NULL,
            ShowDumpResults,
            NULL,
            ExceptionHandler::HANDLER_ALL);
    


            
    然后就OK了,在程序中人为制造一些崩溃问题,执行程序后,dmp文件就会保存到你设置的路径了。

    如何查看dmp信息:
    将dmp+exe+pdb文件放到同一目录下,双击dmp文件(用vs打开),即可查看dmp信息。



  • 相关阅读:
    ArrayBlockingQueue和LinkedBlockingQueue
    hibernate中保存一个对象后再设置此对象的属性为什么不需要调用update方法了
    Hello World!
    org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction;
    jquery的attr在浏览器发生错误,checkbox的属性总是为undefined
    如何解决设置maven时Could not read settings.xml
    iOS与HTML交互问题
    一个苹果证书怎么多次使用——导出p12文件
    Mac Chrome-点击书签页在新的标签打开之方法
    iOS 开发者中的个人账号与组织账号之间区别
  • 原文地址:https://www.cnblogs.com/solohac/p/4602816.html
Copyright © 2011-2022 走看看