=====================================================
在介紹工具之前,先簡單講一下有調試與無調試信息的兩個版本 so 。 一個含有 native 代碼的 app 項目的典型結構是這樣的:
一般的分析崩潰日誌的工具都是利用含有調試信息的 so, 結合崩潰信息,分析崩潰點在源代碼中的行號。
1.android如何編譯出帶符號表的.so庫
#生成的so文件目錄
#set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../../../../src/main/jniLibs/armebai-v7a)
把自己生成的註釋掉使用VisualStudio高效開發調試AndroidNDK
Android NDK墓碑/崩潰分析
tombstone(墓碑)是當系統 crash 的時候,會保存一個 tombstone 文件到/data/tombstones目錄下(Logcat中也會有相應的信息)
1.運行終端。 跳轉到你android sdk 目錄 因爲你的adb 在裏面。
如 cd /Users/name/Android/adt-bundle-mac-x86_64-20131030/sdk/platform-tools
2、找了路徑正確繼續下一步,./adb logcat | 你android ndk-stack所在的路徑 -sym /你安卓工程.so文件所在的目錄
如./adb logcat | /Users/name/Android/android-ndk-r8e/ndk-stack -sym /Users/name/test/proj.android/obj/local/armeabi
3、正確配置後會在終端出現
- waiting for device -
adb logcat | $NDK_HOME/ndk-stack -sym $PROJECT/libs/armeabi
其中,$PROJECT/libs/armeabi是so的路徑。
adb logcat | $NDK_HOME/ndk-stack -sym /Users/mac/AiOpen/AiOpen/app/jni-libs/armeabi
<span style="color:#000000"><span style="color:#37474f">adb logcat > /Users/mac/ndk/tongue.txt</span></span>
$NDK_HOME/ndk-stack -sym /Users/mac/AiOpen/AiOpen/app/jni-libs/armeabi -dump /Users/mac/ndk/tongue.txt
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
信息,配合崩潰信號列表:信號 | 描述 |
---|---|
SIGSEGV | 內存引用無效。 |
SIGBUS | 訪問內存對象的未定義部分。 |
SIGFPE | 算術運算錯誤,除以零。 |
SIGILL | 非法指令,如執行垃圾或特權指令 |
SIGSYS | 糟糕的系統調用 |
SIGXCPU | 超過CPU時間限制。 |
SIGXFSZ | 文件大小限制。 |
1、SIGSEGV 段錯誤
SEGV_MAPERR 要訪問的地址沒有映射到內存空間。 比如上面對空指針的寫操作, 當指針被意外複寫爲一個較小的數值時。
SEGV_ACCERR 訪問的地址沒有權限。比如試圖對代碼段進行寫操作。
2、SIGFPE 浮點錯誤,一般發生在算術運行出錯時。
FPE_INTDIV 除以0
FPE_INTOVE 整數溢出
3、SIGBUS 總線錯誤
BUS_ADRALN 地址對齊出錯。arm cpu比x86 cpu 要求更嚴格的對齊機制,所以在 arm cpu 機器中比較常見。
4、SIGILL 發生這種錯誤一般是由於某處內存被意外改寫了。
ILL_ILLOPC 非法的指令操作碼
ILL_ILLOPN 非法的指令操作數
5、當調用堆棧中出現 stack_chk_fail 函數時,一般是由於比如 strcpy 之類的函數調用將棧上的內容覆蓋,而引起棧檢查失敗。
Testin崩潰分析如何幫開發者發現NDK錯誤
以上提到的方法,只適合在開發測試期間,如果你的應用或遊戲已經上線,而用戶經常反饋說崩潰、閃退,指望用戶幫你收集信息定位問題幾乎是不可能的。這個時候,我們就需要用其他的手段來捕獲崩潰信息。
目前業界已經有一些公司推出了崩潰信息收集的服務,通過嵌入SDK,在程序發生崩潰時收集堆棧信息,發送到雲服務平臺,從而幫助開發者定位錯誤信息。在這方面,國內的Testin和國外的crittercism都可以提供類似服務。
Testin從1.4版本開始支持NDK的崩潰分析,其最新版本已升級到1.7。當程序發生NDK錯誤時,其內嵌的SDK會收集程序在用戶手機上發生崩潰時的堆棧信息(主要就是上面我們通過logcat日誌獲取到的函數指針)、設備信息、線程信息等,SDK將這些信息上報至Testin雲服務平臺,在平臺進行唯一性的處理、並可以自定義時段進行詳盡的統計分析,從多維度展示程序崩潰的信息和嚴重程度;最新版本還支持用戶自定義場景,方便開發者定位問題所在。
從用戶手機上報的堆棧信息,Testin爲NDK崩潰提供了符號化的功能,只要將我們編譯過程中產生的包含符號表的so文件上傳,就可以自動將函數指針地址定位到函數名稱和代碼行數。符號化之後,看起來就和我們前面在本地測試的結果是一樣的了,一目瞭然。而且使用這個功能還有一個好處:這些包含符號表的so文件,在每次開發者編譯之後都會改變,很有可能我們發佈之後就已經變了,因爲開發者會修改程序。在這樣的情況下,即使我們拿到了崩潰時的堆棧信息,那也無法再進行符號化了。我們可以將這些文件上傳到Testin進行符號化的工作,Testin會爲我們保存和管理不同版本的so文件,確保信息不會丟失。