一、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'
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.log3)转换.so为汇编代码:
arm-eabi-objdump -S libstagefright.so > libstagefright.asm4)执行脚本:
python parse_stack.py libstagefright.asm logcat_crash.asm
如果log中含有多个crash信息,所有的crash信息都会被解析。