android ndk stack trace and crash log analyzer

一、How to read Android crash log and stack trace

Android系统崩溃时常常会产生如下的crash log信息,这些信息可以通过"adb logcat"或者从/data/tombstones目录下找到对应的tombstones文件,这里简单描述了如何分析这些信息以及如何通过工具将对应的地址翻译成symbol信息。

crash log最开始是build信息:

I/DEBUG   (   64): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG   (   64): Build fingerprint: '.......20130914.171352:eng/test-keys'
I/DEBUG   (   64): Revision: '0'

紧接着是PID(process id)和TID(thread id),如果PID和TID一样则表明crash发生在父进程中,否则crash发生在子进程中,对于进程信息可以在/proc/<pid>中查看,pid必须是crash发生之前的pid。
I/DEBUG   (   64): pid: 69, tid: 2126, name: OMXCallbackDisp  >>> /system/bin/mediaserver <<<

下面则是crash发生的signal类型和寄存器值,这里的signal 11是段错误(segmentation fault),SIGSEGV是当一个进程执行了一个无效的内存引用,或发生段错误时发送给它的信号。

I/DEBUG   (   64): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000008
I/DEBUG   (   64):     r0 00000004  r1 42f2c8a0  r2 00000001  r3 46166d88
I/DEBUG   (   64):     r4 00000004  r5 00000000  r6 451d00e0  r7 00000001
I/DEBUG   (   64):     r8 00000000  r9 00000000  sl 00000000  fp 0005eb81
I/DEBUG   (   64):     ip 00000000  sp 46f9cbb0  lr 4090a8f1  pc 4090a738  cpsr 60000030

下面是crash发生时最后的函数调用堆栈信息,"#00"表示堆栈深度,函数调用关系是从"#14" -->> "#00","pc xxxxxxxx"表示指针地址,紧接着是函数所在的库文件。android为了节省空间在生成的img文件中会将symbols信息删除,我们可以通过"stack"或者“arm-eabi-addr2line”工具来将pc地址转换为函数调用名称的symbols信息。

I/DEBUG   (   64): backtrace:
I/DEBUG   (   64):     #00  pc 0000c738  /system/lib/libstagefright_omx.so
I/DEBUG   (   64):     #01  pc 0000c8ed  /system/lib/libstagefright_omx.so
I/DEBUG   (   64):     #02  pc 00079ffb  /system/lib/libstagefright.so
I/DEBUG   (   64):     #03  pc 0007a179  /system/lib/libstagefright.so
I/DEBUG   (   64):     #04  pc 0007abb5  /system/lib/libstagefright.so
I/DEBUG   (   64):     #05  pc 0007b653  /system/lib/libstagefright.so
I/DEBUG   (   64):     #06  pc 0007bfd1  /system/lib/libstagefright.so
I/DEBUG   (   64):     #07  pc 0007c275  /system/lib/libstagefright.so
I/DEBUG   (   64):     #08  pc 0007c915  /system/lib/libstagefright.so
I/DEBUG   (   64):     #09  pc 0000c845  /system/lib/libstagefright_omx.so
I/DEBUG   (   64):     #10  pc 0000adcb  /system/lib/libstagefright_omx.so
I/DEBUG   (   64):     #11  pc 00011267  /system/lib/libutils.so
I/DEBUG   (   64):     #12  pc 00010dcd  /system/lib/libutils.so
I/DEBUG   (   64):     #13  pc 0000e3b8  /system/lib/libc.so
I/DEBUG   (   64):     #14  pc 0000dab0  /system/lib/libc.so

二、函数call back转换和分析

1、使用arm-eabi-addr2line工具转换地址为函数名称:

1)首先在android工程中执行source build/envsetup.sh, lunch xxx配置好对应的环境,arm-eabi-addr2line工具在android工程(以4.2.2为例)的prebuilts/gcc/linux-86/arm/arm-eabi-4.6/bin/目录下。

2)执行需要转换的pc地址(可以同时转换多个地址),指定含symbols信息的库文件(编译时生成,通常在out/target/product/[PROJECT]/symbols/system/lib/目录下),如:

android-project$ arm-eabi-addr2line -C -f -e out/target/product/TARGET_PRODUCT/symbols/system/lib/libstagefright.so 0007abb5 0007a179 00079ffb 

执行成功后会得到对应的函数调用信息,从上到下依次为0007abb5  0007a179  00079ffb地址对应的函数名和函数所在的文件:

android::OMXCodec::onStateChange(OMX_STATETYPE)
android-project/frameworks/av/media/libstagefright/OMXCodec.cpp:2676
android::OMXCodec::freeBuffersOnPort(unsigned long, bool)
android-project/frameworks/av/media/libstagefright/OMXCodec.cpp:2768
android::OMXCodec::freeBuffer(unsigned long, unsigned int)
android-project/frameworks/av/media/libstagefright/OMXCodec.cpp:2786

2、通过google提供的python脚本(parse_stack.py)来转换调用的函数堆栈:

1)下载python脚本:http://code.google.com/p/android-ndk-stacktrace-analyzer/

2)保存含crash的log信息:

adb shell logcat > logcat_crash.log
3)转换.so为汇编代码:

arm-eabi-objdump -S libstagefright.so > libstagefright.asm
4)执行脚本:

python parse_stack.py libstagefright.asm logcat_crash.asm


如果log中含有多个crash信息,所有的crash信息都会被解析。


你可能感兴趣的:(android ndk stack trace and crash log analyzer)