Android系统调试-程序崩溃调试

Android系统对于Native(C/C++)应用程序的调试手段比单纯的linux系统coredump文件与gdb结合调试的手段.但是Android系统的天然不支持这种调试方式,其在内核中就没有启用coredump生成机制,那么Android系统下我们使用什么方式调试Native程序的崩溃问题呢?其实,Android系统将系统应用程序产生的崩溃日志都存储到了/data/tombstones目录下,其详细记录了Native应用程序崩溃时进程上下文,通过该文件我们可以知道进程崩溃的原因,崩溃的地点,崩溃线程的函数调用栈,通过这些信息就可轻松的定位到崩溃的具体位置.下面详细的介绍如何通过/data/tombstones目录下的崩溃日志定位到崩溃的位置和原因。

调试步骤

编写用于调试的程序

int main  (void) 
{
    int *null = 0;
    *null = 0;  
    return 0;
}

编译并将其下载到Android系统

arm-linux-androideabi-gcc coredump.c -o coredump -pie -fPIE -g
adb push coredump /data/coredump
./coredump

运行查看崩溃日志

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)**

根据崩溃日志定位崩溃位置

崩溃日志中提供了程序崩溃时的函数调用栈,其详细记录了程序运行时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,触发段错误

总结

上面展示了一个完成的Native程序崩溃日志的调试步骤,其中有几点需要注意的地方
1. 编译应用程序时需要制定-g选项,该选项会在应用程序中添加符号信息,而在使用addr2line时需要这些符号信息定位崩溃位置

你可能感兴趣的:(Linux,C/C++)