6.NDK Android jni開發 so庫奔潰解決辦法 (相機圖片美化)

SO庫奔潰總結方案:
1.添加日誌信息
2.找到c的源代碼生成帶符號的so庫。
3.安裝bugly,分析具體那一行出了問題
4.jni異常和c++異常的基本分析和解決辦法
5.從奔潰信息中可以反饋一個問題:c比較安全,比較難破解

=====================================================

 

在介紹工具之前,先簡單講一下有調試與無調試信息的兩個版本 so 。 一個含有 native 代碼的 app 項目的典型結構是這樣的:

一般的分析崩潰日誌的工具都是利用含有調試信息的 so, 結合崩潰信息,分析崩潰點在源代碼中的行號。

 
通常一次編譯會先生成一個有含有調試信息的 so, 路徑通常是在 obj/local/ 各 abi 目錄下,其中還有一些中間文件(比如.o文件);再通過對這些含有調試信息的 so 進行一次 strip , 產生對應的無調試信息 so, 放到 libs 目錄下各 abi 目錄中, 發佈產品時,我們都是用這些 strip 後的 so。
————————————————

1.android如何編譯出帶符號表的.so庫

如果是mk:可以直接生成2種so庫
如果是cmake:debug版本就是帶符號的。release就是不帶符號的。
用默認的so庫路徑
#生成的so文件目錄
#set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../../../../src/main/jniLibs/armebai-v7a)
把自己生成的註釋掉
 
bugly:分析有符號的so庫
符號表:
 
 
VS 編寫實現方法生成 dll 動態庫

使用VisualStudio高效開發調試AndroidNDK

cmake編譯so庫。然後同時生成apk。
會發現:會先編譯然後生成的apk會把so打包進去。放心好了
===========================================================================
2.so庫奔潰具體行數: 定位so奔潰的行數

Android NDK墓碑/崩潰分析

 
閃退發生時在logcat中將日誌過濾條件選爲“No Filters”就可以看到完整的閃退日誌,或者叫tombstone(墓碑)文件。
tombstone(墓碑)是當系統 crash 的時候,會保存一個 tombstone 文件到/data/tombstones目錄下(Logcat中也會有相應的信息)
3.NDK安裝包中提供了三個調試工具:addr2line、objdump和ndk-stack,
google官方提供的ndk-stack工具分析:
4.bugly的定位原理:ndk-stack使用:
Android ndk-stack 定位so庫crash位置
如果你覺得上面的方法太麻煩的話,ndk-stack可以幫你減輕操作步聚,直接定位到代碼出錯的位置。
使用adb獲取logcat的日誌,並通過管道輸出給ndk-stack分析,並指定包含符號表的so文件位置。如果程序包含多種CPU架構,需要根據手機的CPU類型,來選擇不同的CPU架構目錄。以armv7架構爲例,執行如下命令:
 

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
可以看到具體的行數
 
 
總結:
如果是so庫找不到,那麼看不到詳情
null指針可以
5.so庫奔潰,日誌種類分析:
結合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文件,確保信息不會丟失。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章