Android Native crash日誌分析,androidcrash
在Android應用crash的類型中,native類型crash應該是比較難的一種了,因為大家接觸的少,然後相對也要多轉幾道工序,所有大部分對這個都比較生疏。雖然相關文章也有很多了,但是我在剛開始學的過程中還是遇到一些問題,下面一一記錄,以便將來翻閱。
分析native crash 日誌需要幾個東西:
log
native crash的日誌都是從一行星號(*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***)開始,這行星號也是ndk-stack工具用來尋找native crash的標誌。一個native crash日誌例子:
1 04-16 11:18:00.323 26512 26512 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 2 04-16 11:18:00.324 26512 26512 F DEBUG : Build fingerprint: 'nubia/NX531J/NX531J:7.1.1/NMF26F/nubia04130311:user/release-keys' 3 04-16 11:18:00.324 26512 26512 F DEBUG : Revision: '0' 4 04-16 11:18:00.324 26512 26512 F DEBUG : ABI: 'arm' 5 04-16 11:18:00.324 26512 26512 F DEBUG : pid: 26452, tid: 26491, name: Thread-4 >>> com.willhua.opencvstudy <<< 6 04-16 11:18:00.324 26512 26512 F DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xc8080000 7 04-16 11:18:00.324 26512 26512 F DEBUG : r0 c807a400 r1 c7e80000 r2 00000069 r3 00000069 8 04-16 11:18:00.324 26512 26512 F DEBUG : r4 caa4ca9c r5 007e9000 r6 00000964 r7 c69838f8 9 04-16 11:18:00.324 26512 26512 F DEBUG : r8 00005c00 r9 00017002 sl 001fa400 fp cac6ec0010 04-16 11:18:00.324 26512 26512 F DEBUG : ip e71aac64 sp c69838e8 lr caa8e949 pc caa8e97c cpsr 800f003011 04-16 11:18:00.326 26512 26512 F DEBUG : 12 04-16 11:18:00.326 26512 26512 F DEBUG : backtrace:13 04-16 11:18:00.326 26512 26512 F DEBUG : #00 pc 0004097c /data/app/com.willhua.opencvstudy-1/lib/arm/libOpenCV.so (_Z14darkGrayThreadPv+179)14 04-16 11:18:00.326 26512 26512 F DEBUG : #01 pc 000475d3 /system/lib/libc.so (_ZL15__pthread_startPv+22)15 04-16 11:18:00.326 26512 26512 F DEBUG : #02 pc 00019d3d /system/lib/libc.so (__start_thread+6)
帶symbols的so檔案
對於比如手機公司的開發人員來說,一般來說出問題的so對應的帶symbols的so都在out/target/product/<model_name>/symbols/system/lib/下面,而對於常見的使用AndroidStudio開發的單個應用來說,其對應的帶symbols的在<PROJECT_ROOT>\app\src\main\obj\local\<ABI>\下面的so,而不能是\app\src\main\libs\<ABI>的,這裡面的是不包含symbols資訊的,拿這個去分析,輸出的結果就是“??:?”。其實這兩個so的體積對比也是很明顯的的,在我的應用程式中,前一個帶symbols的so的體積為7M多,而後一個只有2M。
分析工具
- addr2line:用來分析單個pc地址對應的源碼行數,比如樣本log中的第13行中的#00 pc 0004097c,0004097c就是crash時pc調用的堆棧地址,用這個地址就可以分析出對應在源碼中的行數;
- objdump:用來把相應的so變成組合語言的asm檔案,然後根據地址資訊(比如0004097c)就可以找到更加詳細的相關函數資訊;
- ndk-stack:用來把log資訊全部翻譯成更加詳細的帶源碼行數資訊的log,相當於是在整個crash堆棧資訊都執行addr2line命令。
對於使用linux系統作為開發環境的,linux就內建addr2line命令。而對於筆者這種使用Windows的,在sdk中安裝了NDK之後,在ndk中就帶有這些工具。
比如addr2line工具在:sdk\ndk-bundle\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\bin下面,同時這個bin下麵包含很多其他工具,比如objdump,readelf等;
ndk-stack工具則在sdk\ndk-bundle下面;
關於這些工具的具體使用,在https://www.oschina.net/question/2241352_213433這篇文章中講的很詳細,我也就不再重複。
但是提醒一點:crash log與對應的so一定要對應起來。即錯誤的情況是:你拿了一份舊的log,然後你修改了so相關的源碼,然後編譯出來了新的so,你拿著這個新的so以及舊log中的地址去讓addr2line等分析,那肯定是是得不到正確的結果的。
剛剛提到的那篇文章講的很詳細,為了避免以後找不到所以我就把它複製到這裡。
/****************************************************************************************************************************************/