爲什麼使用Google Breakpad?
在項目開發中,我們經常需要引入一些第三方的.so文件或者是寫一些Native代碼,但是當Native代碼出現crash後,對crash的追蹤和定位一直是一個比較艱難的事情。
Google Breakpad是一套完整的工具集,從Crash的捕獲到Crash的dump,都提供了相對應的工具。它記錄了崩潰時的.dump文件,無論我們是在本地或者發送到服務器端,都可以用相對應的工具來解析.dump文件幫助我們查找C和C++堆棧蹤跡。
Google BreakPad簡介
Google breakpad是一個跨平臺的崩潰轉儲和分析框架和工具集合。
Breakpad由三個主要組件:
-
client,以library的形式內置在我們的應用中,當崩潰發生時寫 minidump文件。
-
symbol dumper, 讀取由編譯器生成的調試信息(debugging information),並生成 symbol file。
-
processor, 讀取 minidump文件 和 symbol file ,生成可讀的c/c++ Stack trace。
簡單來說就是一個生成 minidump,一個生成symbol file,然後將其合併處理成可讀的Stack trace。
引入Google BreakPad到項目,並解析.dump文件
1.利用Android新建一個項目,具體參考的Sample,可以直接導入Android Studio中,這個項目是採用CMakeLists.txt來配置的。
2.在真機中運行項目會出現下面的界面,點擊按鈕應用閃退。
3.閃退之後會在手機的文件管理器中會生成一個crashDump目錄,裏面有一個.dump文件
4.在Android Studiod的安裝目錄\bin\lldb\bin中存在一個minidump_stackwalk.exe的可執行文件,我們現在需要用這個工具對.dump文件進行解析,並將解析的結果寫到crash.txt文件中
minidump_stackwalk.exe f7ab957b-326b-4772-160d079e-1f44738d.dmp >crash.txt
5.成功解析文件
6.從dump文件解析出來的信息來看,crash原因是SIGSEGV,根據文章Android 平臺 Native 代碼的崩潰捕獲機制及實現的介紹,我們可知Crash reason: SIGSEGV代表哪種類型的錯誤:
Crash reason: SIGSEGV //是當一個進程執行了一個無效的內存引用,或發生段錯誤時發送給它的信號。
Crash address: 0x0
Process uptime: not available
Thread 0 (crashed) //crash 發生時候的線程
0 libcrash-lib.so + 0x7b2 //發生 crash 的位置和寄存器信息
7.有了具體的寄存器信息,我們就進行符號解析,可以使用Android NDK中提供的addr2line來根據地址進行一個符號反解的過程,該工具在Android SDK目錄下可以找到。
工具鏈的選擇要根據.so的類型來決定,看解析後的文件,有顯示CPU信息。下面是NDK20的工具鏈目錄:
- 如果是arm-64位的so,解析是需要使用aarch64-linux-android-4.9下的工具鏈。
- 如果是arm-32位的so,解析是需要使用arm-linux-androideabi-4.9下的工具鏈。
- 如果是x86-64位的so,解析是需要使用x86_64-4.9下的工具鏈。
- 如果是x86-32位的so,解析是需要使用x86-4.9下的工具鏈
8.這裏,因爲CPU信息是armv7,所以選擇arm-linux-androideabi-4.9下的工具鏈。我們將項目中build目錄下的arm-v7a對應的libcrash-lib.so(app\build\intermediates\transforms\mergeJniLibs\debug\0\lib\armeabi-v7a\libcrash-lib.so)拷貝到arm-linux-androideabi-4.9下的工具鏈目錄(arm-linux-androideabi-4.9\prebuilt\windows-x86_64\bin)中,然後執行如下命令:
arm-linux-androideabi-addr2line.exe -f -C -e libcrash-lib.so 0x7b2
最後就能看到具體是哪個類下的哪一行報錯了。