本文來自breakpad源碼目錄中doc目錄下的linux_starter_guide.md,建議直接去看原文。
如何將breakpad添加進你的Linux程序
本文檔是在Linux上使用Breakpad client庫的概述。
構建Breakpad庫
Breakpad提供了一個Autotools構建系統,用於構建Linux client庫和 processor庫。在Breakpad源目錄中運行`./configure && make`,將會在src/client/linux 目錄下生成
一個名靜態庫libbreakpad_client.a,這個靜態庫中包含了應用程序崩潰時生成minidumps所需的所有代碼。
將Breakpad集成到你的程序中
首先,在你的應用程序中引用異常處理程序頭文件,然后在編譯中記得鏈接breakpad提供的靜態庫libbreakpad_client.a,在編譯中頭文件搜索包含breakpad的src目錄。具體可以參考下面的編譯命令。
#include "client/linux/handler/exception_handler.h"
現在可以在你的程序中實例化一個ExceptionHandler對象。 異常處理在ExceptionHandler對象的生命周期內處於活動狀態,因此應用程序的啟動過程中盡早實例化它,並且使其處於保活狀態(盡可能長時間)。為了做一些有用的事情,ExceptionHandler構造函數需要一個有寫權限的路徑來寫入minidump文件,以及一個回調函數來接收有關已寫 minidump的信息:
static bool dumpCallback(const google_breakpad::MinidumpDescriptor& descriptor, void* context, bool succeeded) { printf("Dump path: %s\n", descriptor.path()); return succeeded; } void crash() { volatile int* a = (int*)(NULL); *a = 1; } int main(int argc, char* argv[]) { google_breakpad::MinidumpDescriptor descriptor("/tmp"); google_breakpad::ExceptionHandler eh(descriptor, NULL, dumpCallback, NULL, true, -1); crash(); return 0; }
編譯並運行此示例,將會在/ tmp中生成一個minidump文件,並且在退出之前應打印minidump文件名。 您可以通過exception_handler.h頭文件了解有關ExceptionHandler構造函數的其他參數的更多信息。
編譯命令如下:其中如要注意的點:1)我的測試Demo名稱為test2.cpp。2)我的測試Demo位於Breakpad的src目錄下。3)我的編譯命令是在進入breakpad的src目錄下執行的。4)參數-I 指定頭文件搜索路徑。因為我當前位於breakpad的src目錄下,所以頭文件搜索的也就是breakpad的src目錄。5)如果你的g++版本比較新,直接支持C++11,則不需要明確給出-std=c++11。
$ g++ -g -I ./ -o breakpad_test test2.cpp ./client/linux/libbreakpad_client.a -lpthread -std=c++11
注意:你應該在回調函數中做盡可能少的工作。當前應用程序處於不安全狀態。從其他函數庫分配內存或調用函數可能並不安全。
如果你必須要在回調函數中實現一些功能,最安全的操作是`fork`和`exec`一個新的進程來執行你需要做的任何功能。Breakpad源碼中包含[libc函數的一些簡單重新實現][2],避免直接調用libc庫,同樣 [用於進行Linux系統調用的頭文件][3](in src/third_party/lss),避免直接調用一些其他的動態庫。
發送minidump文件
在實際的應用程序中,你可能希望以某種方式處理minidump文件,可能是將其發送到服務器進行分析。Breakpad源碼樹中包含可能有用的東西,[關於HTTP上傳的源代碼] [4],以及[小型轉儲上傳工具] [5]。
[4]: breakpad/src/common/linux/http_upload.h
[5]: breakpad/src/tools/linux/symupload/minidump_upload.cc
為你的應用程序生成符號文件
為了產生有用的堆棧跟蹤信息,Breakpad要求將二進制文件中的調試符號轉換為[文本格式的符號文件] [6]。首先,確保已使用-g編譯你的二進制文件以包含調試符號。 其次,在Breakpad源目錄中執行configure && make編譯dump_syms工具,最后,在你的二進制文件上運行`dump_syms`,產生文本格式的符號。例如,你的二進制文件名為“ test”:
$ google-breakpad/src/tools/linux/dump_syms/dump_syms ./test > test.sym
[6]: breakpad/docs/symbol_files.md
為了將這些符號與minidump_stackwalk工具一起使用,你需要將它們放在特定的目錄結構中。 例如,符號文件的第一行包含生成此目錄結構所需的信息(你的輸出將有所不同):
$ head -n1 test.sym MODULE Linux x86_64 6EDC6ACDB282125843FD59DA9C81BD830 test $ mkdir -p ./symbols/test/6EDC6ACDB282125843FD59DA9C81BD830 $ mv test.sym ./symbols/test/6EDC6ACDB282125843FD59DA9C81BD830
你可能還會在Mozilla存儲庫中找到[symbolstore.py] [7]腳本,該腳本封裝了這些步驟。
[7]: https://dxr.mozilla.org/mozilla-central/source/toolkit/crashreporter/tools/symbolstore.py
處理minidump以產生堆棧跟蹤信息
Breakpad包含一個名為`minidump_stackwalk`的工具,該工具可以提取一個minidump文件及其相應的文本格式符號,並生成符號化的堆棧跟蹤。如果你是按照上述說明編譯的Breakpad源代碼,則該文件應位於google-breakpad / src / processor目錄中。 只需將minidump和符號路徑作為命令行參數傳遞給它:
$ google-breakpad/src/processor/minidump_stackwalk minidump.dmp ./symbols
它在stderr上生成詳細輸出,而在stdout上生成stacktrace,因此你可能需要重定向stderr。