在NDK开发中经常会出现应用Crash的情况,而JNI层的报错信息,不像Java层报错信息那样可以直接在日志中看到错误的行数,JNI层中出现的错误直接看根本定位不到错误的位置。通常来说,JNI报的基本都是堆栈信息,需要NDK的一些工具进行地址转换,转换后即可看到错误的位置。addr2line就是这些地址转换的工具。
一、环境配置
1、工具路径
路径一般都在 Sdk/ndk 下
工具选择
可以看到在 toolchains 下有多个选择,这应该是根据需要解析的 so 库类型进行选择,这里我选择了第一个。
bin 路径
配置环境变量
将上面的 bin 路径复制到环境变量中
环境验证
在 bin 目录下输入如下命令
aarch64-linux-android-addr2line --version
运行结果,表示环境变量配置成功
二、异常分析
1、错误查看
错误信息,主要看 backtrace 部分
DEBUG: backtrace:
DEBUG: #00 pc 0000000000000000 <unknown>
DEBUG: #01 pc 00000000000307cc /system/lib64/libxiaoxu.so (offset 0x15000) (doIp_handle_vehicle_identifica)
DEBUG: #02 pc 000000000003278c /system/lib64/libxiaoxu.so (offset +0x18000) (posix_timers_timeout_func+80)
DEBUG: #03 pc 000000000002bcf0 /system/lib64/libc.so (__timer_thread_start(void*)+56)
DEBUG: #04 pc 000000000008192c /system/lib64/libc.so (__pthread_start(void*)+36)
DEBUG: #05 pc 0000000000023478 /system/lib64/libc.so (__start_thread+68)
2、提取错误信息
#03、#04 和 #05 为 libc.so 异常,这是系统的库我们不用管。#01 和 #02 为 libxiaoxu.so 异常,我们主要分析这个。
pc 后面的十六进制数就是对应 so 库中的具体错误信息地址,我们要做的主要是将这个地址信息转换成 so 库中代码的位置。
三、使用addr2line
1、转换地址的命令
aarch64-linux-android-addr2line -C -f -e ${SOPATH} ${Address}
# 如果前面选择 arm-linux-androideabi-4.9,则用下面命令
arm-linux-androideabi-addr2line -C -f -e ${SOPATH} ${Address}
-C -f //打印错误行数所在的函数名称
-e //打印错误地址的对应路径及行数
${SOPATH} //so库路径
${Address} //需要转换的堆栈错误信息地址,可以添加多个,但是中间要用空格隔开
2、 异常分析
so库路径
# Android项目三方so库
/app/src/main/jniLibs/
# 自己生成的so库
/app/build/intermediates/cmake/debug/obj/
这里我将上面路径下的so库另存到自己新建的文件夹下 F:\sotest\libxiaoxu.so,这里改变 so 路径或修改 so 文件名都没影响。
执行命令
注意要在 aarch64-linux-android-addr2line 工具的 bin 路径下执行,如果没进入到 bin 路径下,命令前面要带上该路径。
aarch64-linux-android-addr2line -C -f -e F:\sotest\libxiaoxu.so 00000000000307cc
运行结果:
Java_com_xiaoxu_sotestdemo_SotestUtil_getUsetName
F:\sotest\SoTestDemo\app\src\main\cpp/native_lib.cpp:33
点击一下转换后的地址就可以跳转到错误的位置了。
3、其他问题
1)提示:不是内部或外部命令,也不是可运行的程序或批处理文件。
环境变量没有配置好,注意选择的bin路径要匹配环境变量和命令中的路径。
2)输出"??0"
注意地址后面对应的是哪个so库,转换的地址显示为 " ? ? 0 ":一个 so 库的错误地址信息与so库不匹配;二是两个错误位置在两个 so 库中的堆栈地址相同。
3)输出"??:?"
说明 so 库不是 debug 版本的看不了。这时候就要修改Applicatiao.mk文件添加下面代码:
APP_OPTIM := debug
4)异常提示:File format not recognized
使用 arm-linux-androideabi-4.9 路径下的 bin 再试一下。注意环境变量和命令中的路径都要修改。
参考文档:
Android studio中NDK开发(四)——使用addr2line分析Crash日志
Jni:05.ndk调试
so库报错根据地址查看,addr2line定位出错位置