前言
Android系統對於Native(C/C++)應用程序的調試手段比單純的linux系統coredump文件與gdb結合調試的手段.但是Android系統的天然不支持這種調試方式,其在內核中就沒有啓用coredump生成機制,那麼Android系統下我們使用什麼方式調試Native程序的崩潰問題呢?其實,Android系統將系統應用程序產生的崩潰日誌都存儲到了/data/tombstones目錄下,其詳細記錄了Native應用程序崩潰時進程上下文,通過該文件我們可以知道進程崩潰的原因,崩潰的地點,崩潰線程的函數調用棧,通過這些信息就可輕鬆的定位到崩潰的具體位置.下面詳細的介紹如何通過/data/tombstones目錄下的崩潰日誌定位到崩潰的位置和原因。
調試步驟
1.編寫用於調試的程序
int main (void)
{
int *null = 0;
*null = 0;
return 0;
}
2.編譯並將其下載到Android系統
arm-linux-androideabi-gcc coredump.c -o coredump -pie -fPIE -g
adb push coredump /data/coredump
./coredump
3.在terminal運行查看崩潰日誌
ls /data/tombstones
root@firefly:/data/tombstones # ls
tombstone_00
上面的代碼會觸發崩潰,其會在/data/tombstones生成對應的崩潰日誌,日誌基本信息如下:
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
**Build fingerprint: 'Android/rk3288_box/rk3288_box:5.1.1/LMY48W/firefly03111810:userdebug/test-keys'
Revision: '0'
ABI: 'arm'
pid: 2992, tid: 2992, name: coredump >>> ./coredump <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
r0 00000001 r1 bebcc894 r2 00000000 r3 00000000
r4 bebcc894 r5 bebcc89c r6 00000001 r7 b6f5730c
r8 00000000 r9 00000000 sl 00000000 fp bebcc85c
ip b6f3264c sp bebcc850 lr b6eed39f pc b6f57328 cpsr 60070010
d0 0000000000000000 d1 0000000000000000
d2 0000000000000fff d3 0000b30a0000b30a
d4 000000000000b30a d5 0000000000000000
d6 0000000000000000 d7 0000000000000000
d8 0000000000000000 d9 0000000000000000
d10 0000000000000000 d11 0000000000000000
d12 0000000000000000 d13 0000000000000000
d14 0000000000000000 d15 0000000000000000
d16 0000000000000000 d17 0000000000000fff
d18 0000000000000000 d19 0000000000000000
d20 0000000000000000 d21 0000000000000000
d22 0000000000000000 d23 0000000000000000
d24 0000000000000000 d25 0000000000000000
d26 0000000000000000 d27 0000000000000000
d28 0000000000000000 d29 0000000000000000
d30 0000000000000000 d31 0000000000000000
scr 00000000
backtrace:
#00 pc 00000328 /data/coredump/coredump (main+28)
#01 pc 0001239d /system/lib/libc.so (__libc_init+44)**
4.根據崩潰日誌定位崩潰位置
崩潰日誌中提供了程序崩潰時的函數調用棧,其詳細記錄了程序運行時PC(Programer Counter)地址,我麼可以根據這些地址,定位程序的崩潰時程序的運行過程.調試崩潰位置,我們需要使用到addr2line函數,該函數將地址信息對應到程序的符號信息,根據符號信息就可以定位到程序代碼的具體位置。
lhl@lhl-ubuntu:~/test$ arm-linux-androideabi-addr2line -a 00000328 -e coredump
0x00000328
/home/lhl/test/coredump.c:4
調試信息顯示崩潰位置在coredump.c的第4行,對應一下代碼,第4行爲*null = 0; //訪問非法地址0,觸發段錯誤
注意事項
1. 編譯應用程序時需要制定-g選項,該選項會在應用程序中添加符號信息,而在使用addr2line時需要這些符號信息定位崩潰位置
2.如果是第三方SDK中.so出現問題,則需要檢測上層應用調用問題。