前言
之前介绍了使用addr2line定位,今天介绍下怎么使用ndk-stack对native崩溃进行定位。
不管使用addr2line还是ndk-stack都要用到我们报错版本的动态库,也就是so文件。需要注意的我们分析bug使用的so文件需要带符号表的so文件。如图:
stripped目录下so文件应该(可能后面还会有处理我不知道,但可以确定最终用的不是debug下的)最终打包到apk的文件。可以看到stripped后的so文件体积更小,但是也没有了debug信息,因此native出了错,这个文件也用不上。我们要用的是debug时产生的so文件,所以如果是自己生成的so文件,那么为了防止出错后无法定位,最好每个版本留存一份带符号表的so文件,便于排错。
ndk-stack
先写个错误:
run起来,发现崩了,这是log:
--------- beginning of crash
2021-12-10 16:07:10.322 6171-6171/com.example.myapplication A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 6171 (e.myapplication)
2021-12-10 16:07:10.392 6187-6187/? A/DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
2021-12-10 16:07:10.392 6187-6187/? A/DEBUG: Build fingerprint: 'Android/rk3399_all/rk3399_all:7.1.2/NHG47K/a01sw006301344:userdebug/test-keys'
2021-12-10 16:07:10.392 6187-6187/? A/DEBUG: Revision: '0'
2021-12-10 16:07:10.392 6187-6187/? A/DEBUG: ABI: 'arm64'
2021-12-10 16:07:10.392 6187-6187/? A/DEBUG: pid: 6171, tid: 6171, name: e.myapplication >>> com.example.myapplication <<<
2021-12-10 16:07:10.392 6187-6187/? A/DEBUG: signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
2021-12-10 16:07:10.392 6187-6187/? A/DEBUG: x0 0000000000000000 x1 0000000000000000 x2 0000000000000008 x3 0000000000000010
2021-12-10 16:07:10.392 6187-6187/? A/DEBUG: x4 0000007ffe86ef88 x5 0000007ce3acabe4 x6 00000000734478f8 x7 0000000000000000
2021-12-10 16:07:10.392 6187-6187/? A/DEBUG: x8 0000007ffe86eae8 x9 0000000000000000 x10 0000000000430000 x11 0101010101010101
2021-12-10 16:07:10.393 6187-6187/? A/DEBUG: x12 00000000000000c4 x13 0000000000000096 x14 0000007d0223e170 x15 507f604830b8952b
2021-12-10 16:07:10.393 6187-6187/? A/DEBUG: x16 0000007cfd07be80 x17 0000007cffb6a368 x18 0000000000000000 x19 0000007cfe695a00
2021-12-10 16:07:10.393 6187-6187/? A/DEBUG: x20 0000007cfe0a8cb0 x21 0000007cfe695a00 x22 0000007ffe86edbc x23 0000007ce3acabe4
2021-12-10 16:07:10.393 6187-6187/? A/DEBUG: x24 0000000000000004 x25 58fa941a45bf0cd5 x26 0000007cfe695a98 x27 58fa941a45bf0cd5
2021-12-10 16:07:10.393 6187-6187/? A/DEBUG: x28 0000000000000001 x29 0000007ffe86ea20 x30 0000007cfd056f00
2021-12-10 16:07:10.393 6187-6187/? A/DEBUG: sp 0000007ffe86ea10 pc 0000007cffb6a378 pstate 0000000040000000
2021-12-10 16:07:10.395 6187-6187/? A/DEBUG: backtrace:
2021-12-10 16:07:10.395 6187-6187/? A/DEBUG: #00 pc 000000000001b378 /system/lib64/libc.so (strlen+16)
2021-12-10 16:07:10.395 6187-6187/? A/DEBUG: #01 pc 000000000000fefc /data/app/com.example.myapplication-2/lib/arm64/libnative-lib.so (_ZNSt6__ndk111char_traitsIcE6lengthEPKc+20)
2021-12-10 16:07:10.395 6187-6187/? A/DEBUG: #02 pc 000000000000fa20 /data/app/com.example.myapplication-2/lib/arm64/libnative-lib.so (_ZNSt6__ndk112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC2IDnEEPKc+48)
2021-12-10 16:07:10.395 6187-6187/? A/DEBUG: #03 pc 0000000000010634 /data/app/com.example.myapplication-2/lib/arm64/libnative-lib.so (Java_com_example_myapplication_MainActivity_errorTest+56)
2021-12-10 16:07:10.395 6187-6187/? A/DEBUG: #04 pc 00000000004467b0 /data/app/com.example.myapplication-2/oat/arm64/base.odex (offset 0x3e2000)
或者从tombstone文件中查看:
这个log还算清楚,至少可以知道大概错误的地方了。不过怎么能让错误更清楚一点?ndk-stack上场了。
1.新建个txt,将log信息放进来,这里是jnilog.txt。(也可以直接使用tombstone文件)
2.跳转到ndk目录下(配置过ndk环境的略过)
3.打开cmd,执行:
ndk-stack -sym D:\astest\jni\MyApplication\app\build\intermediates\cmake\debug\obj\arm64-v8a -dump C:\Users\admin\Desktop\jnilog.txt
其中
(1) D:\astest\jni\MyApplication\app\build\intermediates\cmake\debug\obj\arm64-v8a是放着上文提到的带符号表的so文件所在目录
(2) C:\Users\admin\Desktop\jnilog.txt是记录log信息的文件
4.转换后的信息如下:
整理后如图:
D:/astest/jni/MyApplication/app/src/main/cpp\TestError.cpp:13:25
直接定位到错误行数:13。是不是和java报错很像了?