android NDK崩溃 调试 主要利用 tombstones,可以看成是普通linux上利用core文件调试查问题类似
一、tombstones简介
1.什么是tombstone
当独立ndk bin方式或者jni方式开始运行时,系统会注册一些信息连接到 debuggerd 的 signal handlers,当系统 crash 的时候,会生成一个 tombstone 文件并保存到/data/tombstones目录下,文件的确就像墓碑一样记录了死亡了的进程的基本信息(例如进程的进程号,线程号),死亡的地址(在哪个地址上发生了 Crash),死亡时的现场是什么样的(记录了一系列的堆栈调用信息)等等。
2.tombstone文件长什么样
一个tombstone文件大概包含以下信息
console:/
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'Allwinner/petrel_p1/petrel-p1:9/PPR1.181005.003/20210826-112106:eng/test-keys'
Revision: '0'
ABI: 'arm'
pid: 1893, tid: 2906, name: bonjour >>> /system/bin/ndktest <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xacc03064
r0 000003ff r1 acc0311c r2 00000004 r3 f3cec54f
r4 acbcb640 r5 000000b8 r6 000007c0 r7 ef57f3f8
r8 acbcc8b4 r9 acbd53fc r10 00000400 r11 acbc83d8
ip f3d32638 sp ef57f3b0 lr acb47c5f pc acb47c6a
backtrace:
stack:
ef57f370 00000000
ef57f374 00000000
ef57f378 00000000
ef57f37c 00010000
ef57f380 612709a0
1). 发生问题的进程ID信息
pid: 1893, tid: 2906, name: bonjour >>> /system/bin/ndktest <<<
当 tid == pid 时,问题发生在父进程,反之问题发生在子进程,从上面的日志信息可以看出发生问题的进程是子进程。
2). 崩溃原因
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xacc03064
这里的信息说明出现进程 Crash 的原因是因为程序产生了段错误(SIGSEGV)的信号,访问了非法的内存空间(0xacc03064)。 当 Linux 应用程序在执行时发生严重错误,一般会导致程序 crash。其中,Linux 专门提供了一类 crash 信号,在程序接收到此类信号时,缺省操作是将 crash 的现场信息记录到 core 文件,然后终止进程。
3).查看崩溃的地方
backtrace:
这里可以看到崩溃前最后的堆栈地址是 ndktest的000a8c6a 和 000532e5,怎样查找这两个地址对应的函数呢,这就需要用到工具addr2line了,可以用如下命令查看
PS D:\xxx\ndktest\android9.0> D:\xx\android-ndk-r21e\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\bin\arm-linux-androideabi-addr2line.exe -e .\obj\local\armeabi-v7a\ndktest 000a8c6a -Cfip
crash_test_func at D:\xxx/ndktest.c:47
上面的信息可以看到000a8c6a地址对应的是ndktest.c 47行crash_test_func函数。
4).注意 这里 在用add2line工具时,不要用.\libs\armeabi-v7a\ndktest,而是要用.\obj\local\armeabi-v7a\下的ndktest,因为libs下的文件已经去掉了调试信息,你可以对比下,libs下的ndktest比obj下的要小的多。
5). tombstone_00里还有logcat最后时刻都记录,结合多种方法更容易分析问题
|