Android Tombstone 分析
Posted yunshouhu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android Tombstone 分析相关的知识,希望对你有一定的参考价值。
转自:https://www.cnblogs.com/CoderTian/p/5980426.html
1.什么是tombstone
当一个动态库(native 程序)开始执行时,系统会注册一些连接到 debuggerd 的 signal handlers,当系统 crash 的时候,会保存一个 tombstone 文件到/data/tombstones目录下(Logcat中也会有相应的信息),文件的确就像墓碑一样记录了死亡了的进程的基本信息(例如进程的进程号,线程号),死亡的地址(在哪个地址上发生了 Crash),死亡时的现场是什么样的(记录了一系列的堆栈调用信息)等等。
2.tombstone文件长什么样
一个tombstone文件大概包含以下信息
--------- beginning of crash F/libc ( 244): invalid address or address of corrupt block 0xb82f54a0 passed to dlfree I/libc ( 244): debuggerd_signal_handler called: signal=11, fn=0xb6fbdaa1 F/libc ( 244): Fatal signal 11 (SIGSEGV), code 1, fault addr 0xdeadbaad in tid 244 (mediaserver) I/libc ( 244): exit from debuggerd_signal_handler W/NativeCrashListener( 916): Couldn't find ProcessRecord for pid 244 I/DEBUG ( 241): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** E/DEBUG ( 241): AM write failure (32 / Broken pipe) I/DEBUG ( 241): Build fingerprint: XXXXXXXXX I/DEBUG ( 241): Revision: '0' I/DEBUG ( 241): ABI: 'arm' I/DEBUG ( 241): pid: 244, tid: 244, name: mediaserver >>> /system/bin/mediaserver <<< I/DEBUG ( 241): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xdeadbaad I/art ( 3078): now dumpable=1 I/DEBUG ( 241): Abort message: 'invalid address or address of corrupt block 0xb82f54a0 passed to dlfree' I/DEBUG ( 241): r0 00000000 r1 b6f20dec r2 deadbaad r3 00000000 I/DEBUG ( 241): r4 b82f54a0 r5 b6f220f8 r6 00000000 r7 42424242 I/DEBUG ( 241): r8 ffffffff r9 b82f5460 sl 00000030 fp 00000000 I/DEBUG ( 241): ip 00000000 sp beb2c020 lr b6ef1fa7 pc b6ef1fa8 cpsr 600e0030 I/DEBUG ( 241): d0 0000000000000000 d1 6f2073736572646c I/DEBUG ( 241): d2 707572726f632066 d3 206b636f6c622072 I/DEBUG ( 241): d4 4242424242424242 d5 4242424242424242 I/DEBUG ( 241): d6 4242424242424242 d7 3ecccccd42424242 I/DEBUG ( 241): d8 0000000000000000 d9 0000000000000000 I/DEBUG ( 241): d10 0000000000000000 d11 0000000000000000 I/DEBUG ( 241): d12 0000000000000000 d13 0000000000000000 I/DEBUG ( 241): d14 0000000000000000 d15 0000000000000000 I/DEBUG ( 241): d16 0000000000000000 d17 3ff0000000000000 I/DEBUG ( 241): d18 7e37e43c8800759c d19 bfd5f3f082400000 I/DEBUG ( 241): d20 3e66376972bea4d0 d21 bf66b12699b6468f I/DEBUG ( 241): d22 3fc54aa75950670f d23 bfd73498f0a5ef3a I/DEBUG ( 241): d24 3fe0000000000000 d25 bfaaf3ec933c988f I/DEBUG ( 241): d26 0000000000000000 d27 4000000000000000 I/DEBUG ( 241): d28 4002e6931e14bde7 d29 3faaf3ec9198f99c I/DEBUG ( 241): d30 3ff0000000000000 d31 3fd29572efd86cee I/DEBUG ( 241): scr 20000010 I/DEBUG ( 241): I/DEBUG ( 241): backtrace: I/DEBUG ( 241): #00 pc 00028fa8 /system/lib/libc.so (dlfree+1239) I/DEBUG ( 241): #01 pc 0000f2cb /system/lib/libc.so (free+10) I/DEBUG ( 241): #02 pc 0000a1cb /system/lib/libstagefright_foundation.so (_ZN7android7ABufferD2Ev+42) I/DEBUG ( 241): #03 pc 0000a211 /system/lib/libstagefright_foundation.so (_ZN7android7ABufferD0Ev+4) I/DEBUG ( 241): #04 pc 0000d68d /system/lib/libutils.so (_ZNK7android7RefBase9decStrongEPKv+40) I/DEBUG ( 241): #05 pc 0005adfd /system/lib/libstagefright.so (_ZN7android2spINS_13GraphicBufferEED2Ev+10) I/DEBUG ( 241): #06 pc 0007cd0f /system/lib/libstagefright.so (_ZN7android14MPEG4Extractor10parseChunkEPxi+634) I/DEBUG ( 241): #07 pc 0007d43d /system/lib/libstagefright.so (_ZN7android14MPEG4Extractor10parseChunkEPxi+2472) I/DEBUG ( 241): #08 pc 0007e873 /system/lib/libstagefright.so (_ZN7android14MPEG4Extractor12readMetaDataEv+58) I/DEBUG ( 241): #09 pc 0007eaa1 /system/lib/libstagefright.so (_ZN7android14MPEG4Extractor11countTracksEv+4) I/DEBUG ( 241): #10 pc 000acf9d /system/lib/libstagefright.so (_ZN7android13ExtendedUtils29MediaExtractor_CreateIfNeededENS_2spINS_14MediaExtractorEEERKNS1_INS_10DataSourceEEEPKc+60) I/DEBUG ( 241): #11 pc 0008e3f5 /system/lib/libstagefright.so (_ZN7android14MediaExtractor6CreateERKNS_2spINS_10DataSourceEEEPKc+624) I/DEBUG ( 241): #12 pc 0006ace9 /system/lib/libstagefright.so (_ZN7android13AwesomePlayer15setDataSource_lERKNS_2spINS_10DataSourceEEE+12) I/DEBUG ( 241): #13 pc 0006c0dd /system/lib/libstagefright.so (_ZN7android13AwesomePlayer13setDataSourceEixx+228) I/DEBUG ( 241): #14 pc 0003d647 /system/lib/libmediaplayerservice.so (_ZN7android18MediaPlayerService6Client13setDataSourceEixx+362) I/DEBUG ( 241): #15 pc 0005ea03 /system/lib/libmedia.so (_ZN7android13BnMediaPlayer10onTransactEjRKNS_6ParcelEPS1_j+478) I/DEBUG ( 241): #16 pc 00017fad /system/lib/libbinder.so (_ZN7android7BBinder8transactEjRKNS_6ParcelEPS1_j+60) I/DEBUG ( 241): #17 pc 0001cfdb /system/lib/libbinder.so (_ZN7android14IPCThreadState14executeCommandEi+562) I/DEBUG ( 241): #18 pc 0001d12f /system/lib/libbinder.so (_ZN7android14IPCThreadState20getAndExecuteCommandEv+38) I/DEBUG ( 241): #19 pc 0001d171 /system/lib/libbinder.so (_ZN7android14IPCThreadState14joinThreadPoolEb+48) I/DEBUG ( 241): #20 pc 00001721 /system/bin/mediaserver I/DEBUG ( 241): #21 pc 0000f411 /system/lib/libc.so (__libc_init+44) I/DEBUG ( 241): #22 pc 00001998 /system/bin/mediaserver I/DEBUG ( 241): I/DEBUG ( 241): stack: I/DEBUG ( 241): beb2bfe0 00000000 I/DEBUG ( 241): beb2bfe4 29ec038f I/DEBUG ( 241): beb2bfe8 0009eb34 I/DEBUG ( 241): beb2bfec b82f54a0 [heap] I/DEBUG ( 241): beb2bff0 b6f220f8 I/DEBUG ( 241): beb2bff4 00000000 I/DEBUG ( 241): beb2bff8 42424242 I/DEBUG ( 241): beb2bffc b6edb3d1 /system/lib/libc.so (__libc_fatal_no_abort+16) I/DEBUG ( 241): beb2c000 b6f12f97 /system/lib/libc.so I/DEBUG ( 241): beb2c004 beb2c014 [stack] I/DEBUG ( 241): beb2c008 b6f167be /system/lib/libc.so I/DEBUG ( 241): beb2c00c b6ef1fa7 /system/lib/libc.so (dlfree+1238) I/DEBUG ( 241): beb2c010 b6f12f97 /system/lib/libc.so I/DEBUG ( 241): beb2c014 b82f54a0 [heap] I/DEBUG ( 241): beb2c018 b6f167be /system/lib/libc.so I/DEBUG ( 241): beb2c01c b82f54b0 [heap] I/DEBUG ( 241): #00 beb2c020 b82f5460 [heap] ......
它包含了发生问题的进程ID信息
I/DEBUG ( 241): pid: 244, tid: 244, name: mediaserver >>> /system/bin/mediaserver <<<
当 tid == pid 时,问题发生在父进程,反之问题发生在子进程,从上面的日志信息可以看出发生问题的进程是mediaserver的子进程。
Terminated signal 和 fault address 信息
F/libc ( 244): Fatal signal 11 (SIGSEGV), code 1, fault addr 0xdeadbaad in tid 244 (mediaserver)
这里的信息说明出现进程 Crash 的原因是因为程序产生了段错误的信号,访问了非法的内存空间,而访问的非法地址是 0xdeadbaad。
信号机制是 Linux 进程间通信的一种重要方式,Linux 信号一方面用于正常的进程间通信和同步,如任务控制(SIGINT, SIGTSTP,SIGKILL, SIGCONT,……);另一方面,它还负责监控系统异常及中断。 当应用程序运行异常时, Linux 内核将产生错误信号并通知当前进程。 当前进程在接收到该错误信号后,可以有三种不同的处理方式。
(1)忽略该信号。
(2)捕捉该信号并执行对应的信号处理函数(signal handler)。
(3)执行该信号的缺省操作(如 SIGSEGV, 其缺省操作是终止进程)。
当 Linux 应用程序在执行时发生严重错误,一般会导致程序 crash。其中,Linux 专门提供了一类 crash 信号,在程序接收到此类信号时,缺省操作是将 crash 的现场信息记录到 core 文件,然后终止进程。
crash 信号列表:
Signal | Description |
---|---|
SIGSEGV | Invalid memory reference. |
SIGBUS | Access to an undefined portion of a memory object. |
SIGFPE | Arithmetic operation error, like divide by zero. |
SIGILL | Illegal instruction, like execute garbage or a privileged instruction |
SIGSYS | Bad system call. |
SIGXCPU | CPU time limit exceeded. |
SIGXFSZ | File size limit exceeded. |
定义在prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8/sysroot/usr/include/bits/signum.h
/* Signals. */ #define SIGHUP 1 /* Hangup (POSIX). */ #define SIGINT 2 /* Interrupt (ANSI). */ #define SIGQUIT 3 /* Quit (POSIX). */ #define SIGILL 4 /* Illegal instruction (ANSI). */ #define SIGTRAP 5 /* Trace trap (POSIX). */ #define SIGABRT 6 /* Abort (ANSI). */ #define SIGIOT 6 /* IOT trap (4.2 BSD). */ #define SIGBUS 7 /* BUS error (4.2 BSD). */ #define SIGFPE 8 /* Floating-point exception (ANSI). */ #define SIGKILL 9 /* Kill, unblockable (POSIX). */ #define SIGUSR1 10 /* User-defined signal 1 (POSIX). */ #define SIGSEGV 11 /* Segmentation violation (ANSI). */ #define SIGUSR2 12 /* User-defined signal 2 (POSIX). */ #define SIGPIPE 13 /* Broken pipe (POSIX). */ #define SIGALRM 14 /* Alarm clock (POSIX). */ #define SIGTERM 15 /* Termination (ANSI). */ #define SIGSTKFLT 16 /* Stack fault. */ #define SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */ #define SIGCHLD 17 /* Child status has changed (POSIX). */ #define SIGCONT 18 /* Continue (POSIX). */ #define SIGSTOP 19 /* Stop, unblockable (POSIX). */ #define SIGTSTP 20 /* Keyboard stop (POSIX). */ #define SIGTTIN 21 /* Background read from tty (POSIX). */ #define SIGTTOU 22 /* Background write to tty (POSIX). */ #define SIGURG 23 /* Urgent condition on socket (4.2 BSD). */ #define SIGXCPU 24 /* CPU limit exceeded (4.2 BSD). */ #define SIGXFSZ 25 /* File size limit exceeded (4.2 BSD). */ #define SIGVTALRM 26 /* Virtual alarm clock (4.2 BSD). */ #define SIGPROF 27 /* Profiling alarm clock (4.2 BSD). */ #define SIGWINCH 28 /* Window size change (4.3 BSD, Sun). */ #define SIGPOLL SIGIO /* Pollable event occurred (System V). */ #define SIGIO 29 /* I/O now possible (4.2 BSD). */ #define SIGPWR 30 /* Power failure restart (System V). */ #define SIGSYS 31 /* Bad system call. */ #define SIGUNUSED 31 #define _NSIG 65 /* Biggest signal number + 1 (including real-time signals). */
3.怎么分析tombstone文件
我们主要关注 backtrace 下面的内容,它保存了发生 crash 时候的函数调用关系,但是需要注意的是它的调用顺序是从下向上执行的(#XX pc -->#00 pc),通过这些函数调用关系,我们就可以大概定位出问题发生的地方,在本次 tombstone 日志中,我们通过
I/DEBUG ( 241): #00 pc 00028fa8 /system/lib/libc.so (dlfree+1239) I/DEBUG ( 241): #01 pc 0000f2cb /system/lib/libc.so (free+10) I/DEBUG ( 241): #02 pc 0000a1cb /system/lib/libstagefright_foundation.so (_ZN7android7ABufferD2Ev+42) I/DEBUG ( 241): #03 pc 0000a211 /system/lib/libstagefright_foundation.so (_ZN7android7ABufferD0Ev+4) I/DEBUG ( 241): #04 pc 0000d68d /system/lib/libutils.so (_ZNK7android7RefBase9decStrongEPKv+40)
可以分析出问题是在调用free函数时发生了指针错误,还可以看出问题发生的原因是libstagefright_foundation.so中释放了两次ABuffer引用,接着就去分析是谁谁释放的AUbffer强指针。
I/DEBUG ( 241): #05 pc 0005adfd /system/lib/libstagefright.so (_ZN7android2spINS_13GraphicBufferEED2Ev+10) I/DEBUG ( 241): #06 pc 0007cd0f /system/lib/libstagefright.so (_ZN7android14MPEG4Extractor10parseChunkEPxi+634) I/DEBUG ( 241): #07 pc 0007d43d /system/lib/libstagefright.so (_ZN7android14MPEG4Extractor10parseChunkEPxi+2472) I/DEBUG ( 241): #08 pc 0007e873 /system/lib/libstagefright.so (_ZN7android14MPEG4Extractor12readMetaDataEv+58)
可以看出来在 libstagefright 动态库中的MPEG4Extractor.cpp 的 parseChunk函数出现的错误。
以上是关于Android Tombstone 分析的主要内容,如果未能解决你的问题,请参考以下文章
Android NDK 开发NDK C/C++ 代码崩溃调试 - Tombstone 报错信息日志文件分析 ( 使用 addr2line 命令行工具查找动态库中的报错代码位置 )
Android NDK 开发NDK C/C++ 代码崩溃调试 - Tombstone 报错信息日志文件分析 ( 使用 addr2line 命令行工具查找动态库中的报错代码位置 )