日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++库(Google Breakpad)

發布時間:2023/12/9 c/c++ 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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

總結

以上是生活随笔為你收集整理的C++库(Google Breakpad)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。