Android Native崩溃分析方法记录

Signal含义介绍:https://www.mkssoftware.com/docs/man5/siginfo_t.5.asp


文章目录

      • Native崩溃堆栈解读
      • 分析Native崩溃日志的方法
        • 1. ndk-stack命令
        • 2. objdump命令(关键!!!)
        • 3. addr2line命令

Native崩溃堆栈解读

Android Native崩溃分析方法记录_第1张图片

进程信息:pid表示进程号,tid表示线程号,name表示进程名
错误信号:signal 11表示信号的数字,SIGSEGV表示信号的名字,code 1(SEGV_MAPERR)表示出错代码,fault addr 00000000 表示出错的地址。
寄存器快照:进程收到错误信号时保存下来的寄存器快照,一共有15个寄存器。
堆栈信息:##00表示栈顶,##01调用#00,以此往下都是嵌套的调用关系,直至到栈顶。
#00 pc 00000730 表示出错的地址,后面是库名称,接着后面可以看到函数函数名。

参考:Android Crash之Native Crash分析


分析Native崩溃日志的方法

1. ndk-stack命令

这命令行工具包含在NDK工具的安装目录,和ndk-build和其他一些常用的NDK命令放在一起。
命令:ndk-stack -sym <对应的abi目录> –dump <崩溃日志文件>
注意:要拿对应的abi目录,崩溃信息有abi的(ABI: ‘arm64’)
ndk-stack之后,会有具体报错位置

例如:ndk-stack -sym …/app/build/intermediates/cmake/release/obj/arm64-v8a -dump crash.txt
崩溃信息

2021-09-07 15:09:44.010 18583-18583/? A/DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
2021-09-07 15:09:44.010 18583-18583/? A/DEBUG: Build fingerprint: 'google/coral/coral:10/QQ3A.200805.001/6578210:user/release-keys'
2021-09-07 15:09:44.010 18583-18583/? A/DEBUG: Revision: '0'
2021-09-07 15:09:44.010 18583-18583/? A/DEBUG: ABI: 'arm64'
2021-09-07 15:09:44.010 18583-18583/? A/DEBUG: Timestamp: 2021-09-07 15:09:44+0800
2021-09-07 15:09:44.010 18583-18583/? A/DEBUG: pid: 18520, tid: 18520, name: llk.test  >>> com.llk.test <<<
2021-09-07 15:09:44.010 18583-18583/? A/DEBUG: uid: 10260
2021-09-07 15:09:44.010 18583-18583/? A/DEBUG: signal 5 (SIGTRAP), code 1 (TRAP_BRKPT), fault addr 0x73a5874e78
2021-09-07 15:09:44.010 18583-18583/? A/DEBUG:     x0  0000000000000001  x1  0000007fcc7a0548  x2  0000000000000000  x3  000000740b4b517b
2021-09-07 15:09:44.010 18583-18583/? A/DEBUG:     x4  0000007fcc7a0528  x5  000000740aa5fe70  x6  0000000000000002  x7  0000007fcc7a0378
2021-09-07 15:09:44.010 18583-18583/? A/DEBUG:     x8  0000000000000001  x9  86a242f2ffd5205a  x10 0000000000430000  x11 0000000000000001
2021-09-07 15:09:44.010 18583-18583/? A/DEBUG:     x12 00000000000000a0  x13 0000000000000000  x14 0000000000000004  x15 00000074909530b0
2021-09-07 15:09:44.010 18583-18583/? A/DEBUG:     x16 0000000000000000  x17 000000006f7fb8d8  x18 000000749187a000  x19 000000740be46c00
2021-09-07 15:09:44.010 18583-18583/? A/DEBUG:     x20 0000000000000000  x21 000000740be46c00  x22 0000007fcc7a0970  x23 00000073a5c32cdc
2021-09-07 15:09:44.010 18583-18583/? A/DEBUG:     x24 0000000000000004  x25 0000007490c3a020  x26 000000740be46cb0  x27 0000000000000001
2021-09-07 15:09:44.010 18583-18583/? A/DEBUG:     x28 0000007fcc7a0700  x29 0000007fcc7a0690
2021-09-07 15:09:44.010 18583-18583/? A/DEBUG:     sp  0000007fcc7a0610  lr  00000073a5874e30  pc  00000073a5874e78
2021-09-07 15:09:44.167 18583-18583/? A/DEBUG: backtrace:
2021-09-07 15:09:44.167 18583-18583/? A/DEBUG:       #00 pc 0000000000018e78  /data/app/com.llk.test-a9ThL6CQuZYGzI6r51mU4w==/base.apk!libnative-lib.so (offset 0x29f000) (isActivityJumpFromNative(_JNIEnv*, _jobject*)+496) (BuildId: f79ca1457ec590855af367fb0bd2e5dc8790b9d6)
2021-09-07 15:09:44.167 18583-18583/? A/DEBUG:       #01 pc 000000000001b160  /data/app/com.llk.test-a9ThL6CQuZYGzI6r51mU4w==/base.apk!libnative-lib.so (offset 0x29f000) (Java_com_llk_test_ui_utils_ModUtil_initActivity+32) (BuildId: f79ca1457ec590855af367fb0bd2e5dc8790b9d6)
2021-09-07 15:09:44.167 18583-18583/? A/DEBUG:       #02 pc 000000000013f350  /apex/com.android.runtime/lib64/libart.so (art_quick_generic_jni_trampoline+144) (BuildId: f2cc4756c885e5b910475e3934ccd61e)
...

其实ndk-stack之后跟原来的没啥区别,哈哈。


2. objdump命令(关键!!!)

如果想精准定位到出错的位置,用objdump就对了。
objdump文件位置:ndk/21.4.7075529/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/arm-linux-androideabi/bin/objdump
命令:objdump -S 对应so文件 > 信息保存文件

例如:objdump -S …/app/src/main/distribution/lib/arm64-v8a/libnative-lib.so > msg.txt
上边崩溃信息堆栈中,我们知道崩溃发生在地址 #00 0x0000000000018e78

../app/src/main/distribution/lib/arm64-v8a/libnative-lib.so:	file format ELF64-aarch64-little

Disassembly of section .plt:
$x:
   146c0:	f0 7b bf a9 	stp	x16, x30, [sp, #-16]!
   146c4:	d0 01 00 90 	adrp	x16, #229376
   146c8:	11 36 44 f9 	ldr	x17, [x16, #2152]
   146cc:	10 a2 21 91 	add	x16, x16, #2152
   ... //忽略一大波指令
   18e60:	a0 03 5f f8 	ldur	x0, [x29, #-16]
   18e64:	e1 17 40 f9 	ldr	x1, [sp, #40]
   18e68:	16 ef ff 97 	bl	#-17320 <$x+0x400>
; finishActivity(env, activity);
   18e6c:	a0 03 5f f8 	ldur	x0, [x29, #-16]
   18e70:	a1 83 5e f8 	ldur	x1, [x29, #-24]
   18e74:	5b f0 ff 97 	bl	#-16020 <$x+0x920>
   18e78:	20 00 20 d4 	brk	#0x1
; }
   18e7c:	a8 f3 5f 38 	ldurb	w8, [x29, #-1]
   18e80:	29 00 80 52 	mov	w9, #1
   18e84:	08 01 09 0a 	and	w8, w8, w9
   ... //忽略一大波指令
   1b148:	fd 83 00 91 	add	x29, sp, #32
   1b14c:	a0 83 1f f8 	stur	x0, [x29, #-8]
   1b150:	e1 0b 00 f9 	str	x1, [sp, #16]
   1b154:	e2 07 00 f9 	str	x2, [sp, #8]
; isActivityJumpFromNative(env, activity);
   1b158:	a0 83 5f f8 	ldur	x0, [x29, #-8]
   1b15c:	e1 07 40 f9 	ldr	x1, [sp, #8]
   1b160:	2c e8 ff 97 	bl	#-24400 <$x+0xb50>
; }
   1b164:	fd 7b 42 a9 	ldp	x29, x30, [sp, #32]
   1b168:	ff c3 00 91 	add	sp, sp, #48
   1b16c:	c0 03 5f d6 	ret
   ... //忽略剩余指令

分析
从上边我们可以找到地址18e78,就是这里出错了!!!
18e78: 20 00 20 d4 brk #0x1
百度了一下arm的brk指令,是中断产生和返回的指令。
然后在查了一下Signal,Fatal signal 5 (SIGTRAP) code 1 (TRAP_BRKPT) 这个错误是说函数缺少指定的返回值。
然后跑去看看代码,发现isActivityJumpFromNative函数是需要有个bool返回值的,但是我最后忘记给一个默认的返回值,哈哈。

3. addr2line命令

很难用,别用它。
而且结果和ndk-stack是一致的,说明ndk-stack也是通过addr2line来获取代码位置的。

你可能感兴趣的:(android,android,linux)