Android使用addr2line定位native崩溃堆栈

出现问题

Android在开发native层代码是时很容易报 signal 11 (SIGSEGV) 错误,这种问题单看报错日志是很难定位到问题的。比如如下错误是我在开发过程中遇到的,Android Studio也不知道抽什么风断点调试也不能用,好在之前听说过 addr2line 这个工具,但一直没有用过,没办法只好用这个工具试试。

2022-06-21 15:38:00.197 27730-27790/com.jk.superplayer A/libc: Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x720064 in tid 27790 (Thread-3), pid 27730 (.jk.superplayer)
2022-06-21 15:38:00.262 27798-27798/? A/DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
2022-06-21 15:38:00.262 27798-27798/? A/DEBUG: Build fingerprint: 'xiaomi/lavender/lavender:10/QKQ1.190910.002/V12.0.2.0.QFGCNXM:user/release-keys'
2022-06-21 15:38:00.262 27798-27798/? A/DEBUG: Revision: '0'
2022-06-21 15:38:00.262 27798-27798/? A/DEBUG: ABI: 'arm'
2022-06-21 15:38:00.262 27798-27798/? A/DEBUG: Timestamp: 2022-06-21 15:38:00+0800
2022-06-21 15:38:00.262 27798-27798/? A/DEBUG: pid: 27730, tid: 27790, name: Thread-3  >>> com.jk.superplayer <<<
2022-06-21 15:38:00.262 27798-27798/? A/DEBUG: uid: 10731
2022-06-21 15:38:00.262 27798-27798/? A/DEBUG: signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x720064
2022-06-21 15:38:00.262 27798-27798/? A/DEBUG:     r0  c2e0d400  r1  000002d0  r2  00000500  r3  00000b40
2022-06-21 15:38:00.262 27798-27798/? A/DEBUG:     r4  c370b1e4  r5  0000001a  r6  c370b230  r7  c370b200
2022-06-21 15:38:00.262 27798-27798/? A/DEBUG:     r8  eec83a50  r9  00006c8c  r10 c370b230  r11 00101000
2022-06-21 15:38:00.262 27798-27798/? A/DEBUG:     ip  00720065  sp  c370b190  lr  c39ec9a9  pc  00720064
2022-06-21 15:38:00.264 27798-27798/? A/DEBUG: backtrace:
2022-06-21 15:38:00.264 27798-27798/? A/DEBUG:       #00 pc 00720064  <unknown>
2022-06-21 15:38:00.264 27798-27798/? A/DEBUG:       #01 pc 000db9a7  /data/app/com.jk.superplayer-HfkpzCWGDpsnFPAOI22SdQ==/lib/arm/libsuperplayer.so (VideoChannel::video_play()+258) (BuildId: fcf1af443c8cfbc511f044fbfb24f53015c0d2dd)
2022-06-21 15:38:00.264 27798-27798/? A/DEBUG:       #02 pc 000db89b  /data/app/com.jk.superplayer-HfkpzCWGDpsnFPAOI22SdQ==/lib/arm/libsuperplayer.so (task_video_play(void*)+14) (BuildId: fcf1af443c8cfbc511f044fbfb24f53015c0d2dd)
2022-06-21 15:38:00.265 27798-27798/? A/DEBUG:       #03 pc 000ab98b  /apex/com.android.runtime/lib/bionic/libc.so (__pthread_start(void*)+20) (BuildId: 7103c0ea4dad751f797aed4598de945f)
2022-06-21 15:38:00.265 27798-27798/? A/DEBUG:       #04 pc 000629b3  /apex/com.android.runtime/lib/bionic/libc.so (__start_thread+30) (BuildId: 7103c0ea4dad751f797aed4598de945f)

addr2line

addr2line命令来自于英文词组”address to line“的缩写,其功能是将函数地址解析成文件名或行号的工具。给出一个可执行文件中的地址或一个可重定位对象中的偏移部分的地址,使用调试信息来找出与之相关的文件名和行号。

语法格式

addr2line [参数] [地址]

常用参数:
参数作用
-a在函数名、文件和行号信息之前,显示地址,以十六进制形式
-b指定目标文件的格式为bfdname
-e指定需要转换地址的可执行文件名
-j给出的地址代表指定section偏移,而非绝对地址
-C将低级别的符号名解码为用户级别的名字
-f在显示文件名、行号的同时显示函数名信息
-p每一个地址的信息占一行

addr2line使用步骤

第一步:

addr2line使用步骤在ndk目录中,根据设备abi找到对应目录,由于我的设备是arm架构就到arm-linux-androideabi-4.9文件夹下,比如:E:\Users\Aimee\AppData\Local\Android\Sdk\ndk\21.4.7075529\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\bin,并在此目录下打开命令行窗口。

第二步:

查看报错日志确定发生crash的so,并找到其路径,可以到Android Studio编译的build目录中寻找,比如:build/intermediates/cmake/debug/obj/armeabi-v7a/

第三步:

接下来就是日志分析,可以看backtrace,下面有crash时的调用栈信息

#01 pc 000db9a7  /data/app/com.jk.superplayer-HfkpzCWGDpsnFPAOI22SdQ==/lib/arm/libsuperplayer.so (VideoChannel::video_play()+258) (BuildId: fcf1af443c8cfbc511f044fbfb24f53015c0d2dd)

可以看出是VideoChannel类的video_play方法报错的,但具体是哪一行报错就不知道了,这时我用就可以找到偏移地址(000db9a7)通过addr2line定位到具体行号,在命令行输入以下命令:

$ ./arm-linux-androideabi-addr2line.exe -f -C -e /f/as_project/SuperPlayer/app/build/intermediates/cmake/debug/obj/armeabi-v7a/libsuperplayer.so 000db9a7

命令输出结果如下:
在这里插入图片描述

定位错误

根据以上命令确定了错误在VideoChannel.cpp的111行,分析代码找到问题,原来是因为调用的函数指针没有初始化。解决native问题报错太麻烦了,不像java代码出错打印的日志可以直接定位到错误。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值