Android JNI 异常定位(2) ——ndk-stack

本文介绍了如何利用ndk-stack工具对Android native层的崩溃进行定位,强调了需要使用带符号表的so文件,并通过一个实例展示了ndk-stack转换log信息的过程,使错误定位更加精确。
摘要由CSDN通过智能技术生成

前言

之前介绍了使用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报错很像了?

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值