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\tools\gyp\gyp.bat --no-circular-check src\client\windows\breakpad_client.gyp
(4)sln文件會生成到src\client\windows目錄
(5)使用sln編譯,lib文件會生成到google_breakpad\src\client\windows\debug 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('\0');
    int result = swprintf_s(text,
        1024,
        TEXT("Dump generation request %s\r\n"),
        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信息。




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM