C++庫(Google Breakpad)

Google Breakpad是什么?

  一個開源的多平臺崩潰報告系統。

  Google breakpad是一個非常實用的跨平臺的崩潰轉儲和分析模塊,它支持Windows,Linux和Mac和Solaris。由于他本身跨平臺,所以很大程度上減少了我們在平臺移植時的工作,畢竟崩潰轉儲,每個平臺下都不同,使用起來很難統一,而Google breakpad就幫我們做到了這一點,不管是哪個平臺下的崩潰,都能夠進行統一的分析。

  現在很多工程都在使用它:最著名的幾個如Chrome,Firefox,Picasa和Google Earth。另外他的License是BSD的,也就是說,我們即便是在商業軟件中使用,也是合法的。好東西!

Google Breakpad原理(比較抽象)

?

? ? ? breakpad把應用程序分成三個部分,代碼,breakpad客戶端和調試信息。

??????1. 在build system中,通過symbol dumper用平臺相關的調試信息生成平臺無關的symbol文件。這樣做的好處很明顯,一旦平臺無關了,所有平臺的崩潰就可以做統一的分析了。

  2. breakpad采取進程外轉儲和分析崩潰的方式,他使用C/S結構,客戶端用來捕獲當前進程中發生的崩潰,并通知服務端崩潰發生。服務端用來響應客戶端,抓取dump文件。這樣做的目的是為了減少崩潰進程對dump的影響

  3. Dump生成后轉發到崩潰分析器中,這個部分可以在本地也可以在服務器上,它對Dump文件進行解析,生成可讀的堆棧信息。

Google Breakpad安裝和編譯(Windows)

  1、? 下載Google breakpad源代碼(從svn中簽出最新代碼)

  2、? 安裝python(2.7版本可用)

  3、? 生成Windows工程文件

  cd  "源碼目錄/src/tools/gyp"# 注意,此處不能使用全路徑,不然會出錯gyp.bat --no-circular-check "../../client/windows/breakpad_client.gyp"

  

  4、? Build All

  備注:如果無法通過svn下載源代碼,可在CSDN上利用網友分享的。

Google Breakpad的使用

?????? 在Windows下使用breakpad的方法很簡單,只需要創建一個ExceptionHandler的類即可,這個ExceptionHandler就是用戶捕獲崩潰的類。

 1  handler = new ExceptionHandler(const wstring& dump_path,
 2                                FilterCallback filter,
 3                                MinidumpCallback callback,
 4                                void* callback_context,
 5                                int handler_types,
 6                                MINIDUMP_TYPE dump_type,
 7                                const wchar_t* pipe_name,
 8                                const CustomClientInfo* custom_info);

參數說明:

  l? //dump文件路徑。

  l? //crash時調用回調函數,返回ture/false來繼續/停止異常處理。

  l? //minidump寫入后調用的回調函數

  l? //設備上下文,回調使用的

  l? //HandlerType異常類型,可在exception_handler.h查看

  l? //minidump的類型,使用DbgHelp.h中MINIDUMP_TYPE類型

  l? //接收crash的server端的管道名

  l? //使用OOP產生minidump時,使用這個自定義客戶信息類指針來發送自定義數據

? ? ?使用breakpad的時候,有兩個地方需要注意:

  1. 把breakpad的solution下的幾個工程,包含到你開發的工程中,或者直接包含它們的lib。

    common:基礎功能,包含一個對GUID的封裝和http上傳的類。

    exception_handler:用來捕獲崩潰的類。

    crash_generation_server:breakpad的服務端,用來在產生崩潰時抓取dump。

    crash_generation_client:breakpad的客戶端,用來捕獲當前進程的崩潰。

  2. 在初始化breakpad之前,記得先創建好dump文件的目錄,不然breakpad服務端將不能正常的寫dump,這會導致breakpad客戶端在崩潰時無限等待服務端dump寫完的消息,最后失去響應。

進程內抓取Dump

  進程內抓取Dump文件是最簡單的breakpad的用法。 

 1 bool InitBreakpad()
 2 {
 3     google_breakpad::ExceptionHandler *pCrashHandler =
 4         new google_breakpad::ExceptionHandler(L"c:\dumps",
 5         onExceptionFilter,
 6         onMinidumpDumped,
 7         NULL,
 8         google_breakpad::ExceptionHandler::HANDLER_ALL,
 9         MiniDumpNormal,
10         NULL,
11         NULL);
12 
13     if(pCrashHandler == NULL)
14     {
15         return false;
16     }
17 
18     return true;
19 }

進程外抓取Dump

  使用進程外抓取Dump是比較推薦的做法。使用進程外抓取Dump時,需要指定服務端和客戶端,在服務端中需要創建CrashGenerationServer的實例,而在客戶端中則只需要創建ExceptionHandler即可。此外,如果服務端自己需要抓進程內的Dump,請將pipe的參數置為NULL。

 1 const wchar_t s_pPipeName[] = L"\\.\pipe\breakpad\crash_handler_server";
 2 const std::wstring s_strCrashDir = L"c:\dumps";
 3 
 4 bool InitBreakpad()
 5 {
 6     google_breakpad::CrashGenerationServer *pCrashServer = 
 7         new google_breakpad::CrashGenerationServer(s_pPipeName,
 8                 NULL,
 9                 onClientConnected,
10                 NULL,
11                 onClientDumpRequest,
12                 NULL,
13                 onClientExited,
14                 NULL,
15                 true,
16                 &s_strCrashDir);
17 
18     if(pCrashServer == NULL) 
19     {
20          return false;
21     }
22 
23     if(!pCrashServer->Start()) 
24     {
25         delete pCrashServer;
26         pCrashServer = NULL;
27     }
28 
29     google_breakpad::ExceptionHandler *pCrashHandler = 
30         new google_breakpad::ExceptionHandler(s_strCrashDir,
31                   onExceptionFilter,
32                   onMinidumpDumped,
33                   NULL,
34                   google_breakpad::ExceptionHandler::HANDLER_ALL,
35                   MiniDumpNormal,
36                   (pCrashServer == NULL) ? s_pPipeName : NULL,
37                   NULL);
38 
39     if(pCrashHandler == NULL) 
40     {
41         return false;
42     }
43
44    return true;
45}

Google Breakpad代碼分析

?????? 代碼結構

  在我們來看breakpad是如何實現其強大的功能之前,我們先來看一下他的代碼結構吧。

?

? ? ? Google breakpad的源代碼都在src的目錄下,分為如下幾個文件夾:

  client:這下面包含了前臺應用程序中捕捉dump的部分代碼,里面按照平臺分成各個子文件夾

  common:前臺后臺都會用到的部分基礎代碼,字符串轉換,內存讀寫,md5神馬的

  google_breakpad:breakpad中公共的頭文件

  processor:用于在后臺處理崩潰的核心代碼

  testing:測試工程

  third_party:第三方庫

  tools:一些小工具,用于處理dump文件和符號表

Google Breakpad的崩潰捕獲機制

  在Windows下捕獲崩潰,大家很容易會想到那個捕獲結構化異常的Api:SetUnhandledExceptionFilter。

  breakpad中也使用了這個Api來實現的崩潰捕獲,另外,breakpad還捕獲了另外兩種C++運行庫提供的崩潰,一種是使用_set_purecall_handler捕獲純虛函數調用產生的崩潰,還有一種是使用_set_invalid_parameter_handler捕獲錯誤的參數調用產生的崩潰。

breakpad中的C/S結構

  由于breakpad是在進程外抓取dump,所以breakpad需要實現一個C/S結構來處理崩潰進程抓取dump的請求。

  breakpad中使用了命名管道來實現IPC。

  (1)、Register

  客戶進程連接上服務進程:連接上管道,設置管道狀態

  客戶進程向服務進程注冊:通過NamedPipe,將客戶進程的信息傳遞給服務進程,也從服務進程讀取到數據。

  客戶進程傳遞的數據包括:服務進程ID、dump類型、crash線程id的地址、EXCEPTION_POINTERS指針的地址、參數異常和純虛函數異常的斷言信息地址、客戶進程信息。服務進程會監控客戶進程的退出。

  客戶進程接收的數據包括:客戶進程用于觸發生成dump的Event Handle;客戶進程用于監聽的dump生成完畢Event Handle;客戶進程用于監聽的服務進程活著Mutex handle等。

  客戶進程在TransactNamePipe函數執行完畢之后,再執行了一次WriteFile操作,發送MESSAGE_TAG_REGISTRATION_ACK消息給服務進程,服務進程收到該ACK消息時,關閉跟客戶進程的連接。服務進程對管道的操作順序為:讀-->寫-->讀,第二次讀是客戶進程通知服務進程關閉管道。

  在客戶端,初始化ExceptionHandler的時候,如果指定了PipeName,也就表示此時需要使用進程外的dump抓取,ExceptionHandler會建立一個 CrashGenerationClient的對象,由這個對象連接服務端,將自己注冊到服務端上去。注冊的過程會順序調用IsRegistered、ConnectToServer、ConnectToPipe、RegisterClient等函數。

  大家可以參看exception_handler.cc中的ExceptionHandler::Initialize函數。

?

  在服務端,初始化CrashGenerationServer的時候,就會建立一個命名管道,并等待客戶端來連接(OnPipeConnected)。一旦有客戶端連接上來(HandleReadDoneState),服務端會為每一個客戶端生成一個ClientInfo的對象,之后用這個對象來管理所有的客戶端(ClientInfo::Initialize()),并創建客戶連接句柄將連接結果信息(PrepareReply、DuplicateHandle)回送給客戶端(RespondToClient),客戶端接收到回送信息(ValidateResponse)。

?????? (2)、RequestDump

  一旦有崩潰發生,客戶端就會向服務端請求Dump(RequestDump),服務端響應(OnDumpRequest)就會從這個ClientInfo對象中取出dump所需要的信息,具體地,通過RegisterWaitForSingleObject注冊了崩潰Event Handle的回調函數。回調函數里做了這么幾件事情:

  1)、通過ReadProcessMemory讀取客戶進程的信息;

  2)、生成dump;  

  3)、觸發dump生成事件,通知客戶進程,復位觸發dump事件。

  大家可以參看crash_generation_server.cc中的CrashGenerationServer::HandleReadDoneState函數。

Google Breakpad存在的問題

  進程外生成dump有很多好處,其中最大的好處就是不會被崩潰進程影響,這樣dump的過程就不容易出錯,但是這樣也有一定的弊端。

  1. 部分崩潰無法抓取。在一些極端的崩潰,如堆棧溢出之類的崩潰,進程外抓取dump有時候會失敗。

  2. 無法抓取死鎖或者其他原因導致的進程僵死。breakpad現在沒有檢測進程死鎖的代碼,也沒有在服務端控制客戶端請求dump的代碼,所以現在breakpad無法抓取死鎖等進程僵死的問題。

  3. 對服務端有依賴。如果指定了在使用進程外抓取dump,breakpad對服務端就有依賴。主要體現在抓取dump時,如果服務端不存在,客戶端將無法正常抓取dump,甚至有時會出現阻塞。

?

PS:深入理解實現方式請調試Breakpad源代碼。

轉載于:https://www.cnblogs.com/MakeView660/p/6077436.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/285453.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/285453.shtml
英文地址,請注明出處:http://en.pswp.cn/news/285453.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

java eleven進度條

2019獨角獸企業重金招聘Python工程師標準>>> 一個矩形組件 MethodDescribleJProgrssBar()不帶進度字符,最小值0最大值100的水平進度條JProgressBar(int orient)VERTICAL/HORIZONTALJProgressBar(int in,int max)指定最大最小的水平進度條JProgressBar(in…

Docker:多階段構建 ASP.NET Core 應用鏡像

本文選自『.NET大牛之路』知識星球,發布于2022年05月25日。今天我們一起來寫 Dockerfile 構建一個 ASP.NET Core 應用鏡像,同時還會將鏡像發布到 Docker Hub 倉庫。1創建示例 Web 應用程序為了演示,我們先創建一個 ASP.NET Core 應用程序&…

[轉]【JAVA各版本特性】JAVA 1.0

閑來想了解下各版本之間的特性,搜索沒有最新的特性說明,故想寫一份。廢話不多說。 JDK Version 1.0 1996-01-23 Oak(橡樹) 初代版本,偉大的一個里程碑,但是是純解釋運行,使用外掛JIT,性能比較差&#xff0…

【數據庫原理及應用】經典題庫附答案(14章全)——第八章:數據庫并發控制

【數據庫原理及應用】經典題庫附答案(14章全)——第一章:數據庫基礎知識 【數據庫原理及應用】經典題庫附答案(14章全)——第二章:關系數據庫知識 【數據庫原理及應用】經典題庫附答案(14章全)——第三章:結構化查詢語言SQL 【數據庫原理及應用】經典題庫附答案(14章…

Tomcat(Windows)

百度云:鏈接:http://pan.baidu.com/s/1pKYrf79 密碼:56t0官網下載網址:http://archive.apache.org/dist/tomcat/tomcat-9/v9.0.0.M13/bin/ 轉載于:https://www.cnblogs.com/haxianhe/p/9271103.html

北京Uber優步司機獎勵政策(3月11日)

滴快車單單2.5倍,注冊地址:http://www.udache.com/ 如何注冊Uber司機(全國版最新最詳細注冊流程)/月入2萬/不用搶單:http://www.cnblogs.com/mfryf/p/4612609.html 優步獎勵低/不掙錢/怎么辦?看這里:http://www.cnblogs.com/mfry…

【招聘(廣州)】成功易(廣州).Net Core中高級開發工程師

成功易(廣州)信息技術有限公司簡介成功易是一家集團性公司,創立于2002年,總部位于北京,旗下擁有7家子公司。廣州成功易成立于2019年,人員逐漸增長150人,組織架構完善, 我們是騰訊廣告…

【數據庫原理及應用】經典題庫附答案(14章全)——第九章:數據庫安全性

【數據庫原理及應用】經典題庫附答案(14章全)——第一章:數據庫基礎知識 【數據庫原理及應用】經典題庫附答案(14章全)——第二章:關系數據庫知識 【數據庫原理及應用】經典題庫附答案(14章全)——第三章:結構化查詢語言SQL 【數據庫原理及應用】經典題庫附答案(14章…

webstrom使用方法

一、設置file-settings- -color&fonts設置,字體 主體 -file and code templates模板ctrlr 查找,替換1 雙擊shift 快速查找2 file -new project 新建文件夾3 file-new 新建html css js等4 右鍵-local history 查看歷史5 雙擊選擇某個元素,…

ERROR 1045 (28000): Access denied for user 'ODBC'@'localhost' 解決Mysql錯誤

1、停止 服務 PS C:\WINDOWS\system32> net stop mysql mysql 服務正在停止. mysql 服務已成功停止。2、執行 mysqld --shared-memory --skip-grant-tables PS C:\WINDOWS\system32> mysqld --shared-memory --skip-grant-tables ------以下操作 另外打開一個 終端--…

xcode 設置快捷鍵 整行上下移動

2019獨角獸企業重金招聘Python工程師標準>>> 設置整行代碼上下移動:找到Xcode中的自帶的配置文件:/Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Versions/A/Resources/IDETextKeyBindingSet.plist用文本編輯IDETextKeyBind…

【數據庫原理及應用】經典題庫附答案(14章全)——第十章:數據庫完整性

【數據庫原理及應用】經典題庫附答案(14章全)——第一章:數據庫基礎知識 【數據庫原理及應用】經典題庫附答案(14章全)——第二章:關系數據庫知識 【數據庫原理及應用】經典題庫附答案(14章全)——第三章:結構化查詢語言SQL 【數據庫原理及應用】經典題庫附答案(14章…

用.Net Core接入微信公眾號開發

Part1前言最近想寫一點基于.Net Core微信公眾號開發的文章Part2測試公眾號申請測試公眾號申請地址:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?tsandbox/login微信公眾號開發文檔:https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Overview.html通過微…

騰訊、百度、小米等7家互聯網各大廠的中臺建設怎么樣了?

中臺是真正為前臺而生的平臺(可以是技術平臺,業務能力甚至是組織機構),它存在的唯一目的就是更好的服務前臺規模化創新,進而更好的響應服務引領用戶,使企業真正做到自身能力與用戶需求的持續對接。 以下轉載…

JAVA基礎知識之網絡編程——-基于AIO的異步Socket通信

異步IO 下面摘子李剛的《瘋狂JAVA講義》 按照POSIX標準來劃分IO,分為同步IO和異步IO。對于IO操作分為兩步,1)程序發出IO請求。 2)完成實際的IO操作。 阻塞IO和非阻塞IO都是針對第一步來劃分的,如果發出IO請求會阻塞線程…

基于.NetCore開發博客項目 StarBlog - (13) 加入友情鏈接功能

系列文章基于.NetCore開發博客項目 StarBlog - (1) 為什么需要自己寫一個博客?基于.NetCore開發博客項目 StarBlog - (2) 環境準備和創建項目基于.NetCore開發博客項目 StarBlog - (3) 模型設計基于.NetCore開發博客項目 StarBlog - (4) markdown博客批量導入基于.N…

【數據庫原理及應用】經典題庫附答案(14章全)——第十二章:數據庫技術新發展

【數據庫原理及應用】經典題庫附答案(14章全)——第一章:數據庫基礎知識 【數據庫原理及應用】經典題庫附答案(14章全)——第二章:關系數據庫知識 【數據庫原理及應用】經典題庫附答案(14章全)——第三章:結構化查詢語言SQL 【數據庫原理及應用】經典題庫附答案(14章…

EditPlus 文件查找功能:在指定文件夾,用正則查尋包含指定內容的文件,指定文件類型,并排除特殊文件名文件

單擊菜單欄上的【Search】&#xff08;查找&#xff09;&#xff0c;選擇【Find in Files】&#xff08;在文件中查找&#xff09;命令&#xff1a; 查找項&#xff1a;正則查找video標簽&#xff0c;src為不包含http的mp4 <video src"([^http].*\.mp4)" width&q…

【數據庫原理及應用】經典題庫附答案(14章全)——第十三章:面向對象程數據庫系統

【數據庫原理及應用】經典題庫附答案(14章全)——第一章:數據庫基礎知識 【數據庫原理及應用】經典題庫附答案(14章全)——第二章:關系數據庫知識 【數據庫原理及應用】經典題庫附答案(14章全)——第三章:結構化查詢語言SQL 【數據庫原理及應用】經典題庫附答案(14章…

NOIP2016普及組第三題——海港

題目描述 小K是一個海港的海關工作人員&#xff0c;每天都有許多船只到達海港&#xff0c;船上通常有很多來自不同國家的乘客。 小K對這些到達海港的船只非常感興趣&#xff0c;他按照時間記錄下了到達海港的每一艘船只情況&#xff1b;對于第i艘到達的船&#xff0c;他記錄了這…