Signal含义介绍:https://www.mkssoftware.com/docs/man5/siginfo_t.5.asp
进程信息:pid表示进程号,tid表示线程号,name表示进程名
错误信号:signal 11表示信号的数字,SIGSEGV表示信号的名字,code 1(SEGV_MAPERR)表示出错代码,fault addr 00000000 表示出错的地址。
寄存器快照:进程收到错误信号时保存下来的寄存器快照,一共有15个寄存器。
堆栈信息:##00表示栈顶,##01调用#00,以此往下都是嵌套的调用关系,直至到栈顶。
#00 pc 00000730 表示出错的地址,后面是库名称,接着后面可以看到函数函数名。
参考:Android Crash之Native Crash分析
这命令行工具包含在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之后跟原来的没啥区别,哈哈。
如果想精准定位到出错的位置,用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返回值的,但是我最后忘记给一个默认的返回值,哈哈。
很难用,别用它。
而且结果和ndk-stack是一致的,说明ndk-stack也是通过addr2line来获取代码位置的。