tombstone

对native crash的调试,第一步是要拿到tombstone文件。位置在/data/tombstones/, 如果,文件系统没有该目录,需要手动先创建该目录,不然,不会生成tombstone文件。当crash发生的时候,debuggerd service会把进程的现场信息,写入tombstone文件。debuggerd的源文件是"system/core/debuggerd/tomstone.cpp",默认最多生成10个tomstone文件,dump 进程的 memory map。可以对它进行修改,mm 编译后,生成文件是 'out/..../system/bin/debuggerd'。

stack工具

stack是源码树下用来读取tomstone文件的工具,它可以把tomstone文件里面的符号,对应到源文件里面。具体用法:

development/scripts/stack < tombstone_00

先把tombstone_00 拷贝到源码树的根目录,在根目录运行上述命令,可以定位到具体的文件,如:

可以明显地看到, crasher.c的52行导致这次的crash。

下面是原始的tomstone_00文件内容

crasher工具

crasher是一个debuggerd测试工具,用来生成各种crash类型的tombstone文件。如:crasher abort 可以产生因为abort()函数导致的tombstone文件。可以通过 'mm system/core/debuggerd/' 来得到 crasher 程序,把它放入主板系统的 '/system/xbin/' 目录下就可以了。

tombstone 文件类型

tombstone根据产生的原因,可以分成不同的类型,我们简单地研究下,常见的几种类型。

Abort

系统主动终止,如: 调用了 abort(); assert()条件起了作用。日志特征是:

  • 出现singal 6 (SIGABRT),Abort message 信息。
  • libc.so 调用 abort
pid: 1656, tid: 1656, name: crasher >>> crasher <<<
signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
Abort message: 'some_file.c:123: some_function: assertion "false" failed'
     r0 00000000 r1 00000678 r2 00000006 r3 f70b6dc8
     r4 f70b6dd0 r5 f70b6d80 r6 00000002 r7 0000010c
     r8 ffffffed r9 00000000 sl 00000000 fp ff96ae1c
     ip 00000006 sp ff96ad18 lr f700ced5 pc f700dc98 cpsr 400b0010

backtrace:
    #00 pc 00042c98 /system/lib/libc.so (tgkill+12)
    #01 pc 00041ed1 /system/lib/libc.so (pthread_kill+32)
    #02 pc 0001bb87 /system/lib/libc.so (raise+10)
    #03 pc 00018cad /system/lib/libc.so (__libc_android_abort+34)
    #04 pc 000168e8 /system/lib/libc.so (abort+4)
    #05 pc 0001a78f /system/lib/libc.so (__libc_fatal+16)

空指针异常

这个不用多废话,最常见的crash 原因之一。日志特征是:

  • SIGSEGV
  • fault addr 0x0
pid: 25326, tid: 25326, name: crasher >>> crasher <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
     r0 00000000 r1 00000000 r2 00004c00 r3 00000000
     r4 ab088071 r5 fff92b34 r6 00000002 r7 fff92b40
     r8 00000000 r9 00000000 sl 00000000 fp fff92b2c
     ip ab08cfc4 sp fff92a08 lr ab087a93 pc efb78988 cpsr 600d0030

Low-address 空指针异常

同空指针异常类似,只不过程序访问了low-address,而不是空地址--0-address,它的特征是:

  • SIGSEGV
  • fault addr '0x??'
pid: 25405, tid: 25405, name: crasher >>> crasher <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xc
     r0 0000000c r1 00000000 r2 00000000 r3 3d5f0000
     r4 00000000 r5 0000000c r6 00000002 r7 ff8618f0
     r8 00000000 r9 00000000 sl 00000000 fp ff8618dc
     ip edaa6834 sp ff8617a8 lr eda34a1f pc eda618f6 cpsr 600d0030

 

Stack + tombstone是最常见的debug native的手段,更多的调试方法,请参考Android的文档:

https://source.android.com/devices/tech/debug/

 

CheckJNI

通过设置'checkjni' 属性可以让系统得到更多的JNI错误信息,同时调用JNI的时候,也做更多的检查。CheckJNI会导致系统性能下降,默认是关闭的。

   adb shell setprop dalvik.vm.checkjni    true

CheckJNI 还有一个非常有用的Forcecopy 模式,它主动检测数组是否越界,如果数组被越界访问,Forcecopy模式会导致CheckJNI 终止进程。

   adb shell setprop dalvik.vm.jniopts  forcecopy

 

用户评论:
发表评论: (限500字)

注册 忘记密码 登录