使用NDK編寫native code時候,真機常會出現crash的錯誤。然後logcat就是一片錯誤堆棧。
- I/DEBUG ( 2562): signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 40123d5c
-
- I/DEBUG ( 2562): backtrace:
- I/DEBUG ( 2562): #00 pc 00000d5c <unknown>
- I/DEBUG ( 2562): #01 pc 0009f8db /system/lib/libstagefright.so (android::SmoothStreamingExtractor::SmoothStreamingExtractor(android::sp<android::DataSource> const&)+366)
- I/DEBUG ( 2562): #02 pc 00082f89 /system/lib/libstagefright.so (android::MediaExtractor::Create(android::sp<android::DataSource> const&, char const*)+500)
- I/DEBUG ( 2562): #03 pc 00045cdf /system/lib/libmediaplayerservice.so (android::AmlogicPlayerExtractorDemux::AmlogicPlayerExtractorDemux(AVFormatContext*)+438)
- I/DEBUG ( 2562): #04 pc 0004602d /system/lib/libmediaplayerservice.so (android::AmlogicPlayerExtractorDemux::extractor_read_header(AVFormatContext*, AVFormatParameters*)+20)
- I/DEBUG ( 2562): #05 pc 00102210 /system/lib/libamplayer.so (avformat_open_input_header+604)
- ....
曾經一直用log的方式查看揣測錯誤的代碼行數。熟不知這些看似淫亂的錯誤日誌其實就是錯誤堆棧的相關信息,只需要一個工具轉換即可。
android-ndk-r10\toolchains\arm-linux-androideabi-4.8\prebuilt\windows-x86_64\bin\arm-linux-androideabi-addr2line
使用方式很簡單
- // -f 輸出函數名
- // -e 輸出錯誤代碼行數和文件路徑
- // xxx.so 對應出錯的so文件, 在android工程obj目錄下
- // addr 是具體的地址
- arm-linux-androideabi-addr2line -f -e xxx.so addr
錯誤日誌中backtracer就是堆棧信息,#00 #01 就是堆棧列表。 #00 就是堆棧頂層就是錯誤所在地址,pc後面的就是地址00000d5c
arm-linux-androideabi-addr2line -f -e /system/lib/libstagefright.so 00000d5c
這樣瞬間就能定位錯誤了。。。
注意這個so文件是android工程obj目錄裏面的,而不是libs裏面的。
obj目錄是帶有debug信息的庫文件,libs的庫文件是沒有debug信息的,addr2line無法讀取源代碼信息。