Android JNI 实践基础(三) - 符号表分析NE crash

ndk 异常日志

模拟一个空指针的场景

arduino 复制代码
void crash() {
    int *p = nullptr;
    *p = 1;
    printf("p:%d \n", p);
}


extern "C"
JNIEXPORT void JNICALL
Java_com_example_ndktest_JNIDynamicLoad_sayHello(JNIEnv *env, jobject thiz) {
    crash();
}

我们在android studio 里看到的崩溃日志是

这里其实有一个技巧,java引发的crash 通常 会有dialog提示,而ne 引发的崩溃 则不会dialog提示,通常表现就是 直接进程退出了

碰到这种情况 我们第一时间应该用命令去查看对应的崩溃信息,as 这个ide里其实过滤掉了很多信息,对ne的查看其实不太方便

adb logcat以后 可以看出来 ne的崩溃信息 主要是三块

信号处理, 寄存器信息,以及 调用堆栈

符号表

ndk 其实本身build 是自带版本号的,多数情况下,我们不会修改这个版本号,下面的链接 可以查看你agp版本中自带的ndk版本号

developer.android.com/studio/proj...

像我这个demo工程就是agp8.1的版本

Library/Android/sdk/ndk/25.1.8937393

这个就是我们的ndk目录了

我们可以 找到我们的addr2line工具

Library/Android/sdk/ndk/25.1.8937393/toolchains/llvm/prebuilt/darwin-x86_64/bin

找到这个目录以后 我们就可以根据崩溃堆栈来定位到到底是哪行代码出的错了

./llvm-addr2line -e /app/build/intermediates/merged_native_libs/debug/out/lib/arm64-v8a/libdynamic-lib.so 00000000000189e0

最后一个参数 就是我们刚才崩溃堆栈中最顶部的那行

执行结果如下:

再看一下 果然是我们代码出错的地方

这里要注意了 strip过的so文件是没有符号表的

可以对比一下下面有没有符号表的体积差别

ndk-stack 命令

前面一小节的addr2line 在使用起来稍微有点麻烦

developer.android.com/ndk/guides/...

更推荐用ndk-stack 来解决

这个命令其实就在 Library/Android/sdk/ndk/25.1.8937393 下,其实内置的就是addr2line ,只不过用起来更方便了

./ndk-stack -sym /app/build/intermediates/merged_native_libs/debug/out/lib/arm64-v8a -dump /Users/11097719/Downloads/ne.txt

大家可以自行试一下 命令的执行结果

其他常用命令

readelf可以获取到 更多符号表的信息

./llvm-readelf -sW NdkTest/app/build/intermediates/merged_native_libs/debug/out/lib/arm64-v8a/libdynamic-lib.so > elfinfo.txt

objdump 也是常用命令之一,可以方便的查看 动态库依赖的信息

./llvm-objdump -p /app/build/intermediates/merged_native_libs/debug/out/lib/arm64-v8a/libdynamic-lib.so

如何搜索代码所在的so文件

比如你怎么知道要引用哪个so文件呢?例如我想调用某个系统的c代码,我搜索到以后 mk文件中怎么知道要链接哪个动态库?

最重要的就是查看Android.bp文件 这里面有重要的信息

我们可以去 cs.android.com/ 查看源码

比如你知道你要使用bitmap.h中的代码

那就直接查找bitmap.cpp的实现 都有哪里在用

相关推荐
温辉_xh9 分钟前
uiautomator案例
android
工业甲酰苯胺1 小时前
MySQL 主从复制之多线程复制
android·mysql·adb
少说多做3432 小时前
Android 不同情况下使用 runOnUiThread
android·java
Estar.Lee3 小时前
时间操作[计算时间差]免费API接口教程
android·网络·后端·网络协议·tcp/ip
找藉口是失败者的习惯4 小时前
从传统到未来:Android XML布局 与 Jetpack Compose的全面对比
android·xml
Jinkey5 小时前
FlutterBasic - GetBuilder、Obx、GetX<Controller>、GetxController 有啥区别
android·flutter·ios
大白要努力!6 小时前
Android opencv使用Core.hconcat 进行图像拼接
android·opencv
天空中的野鸟7 小时前
Android音频采集
android·音视频
小白也想学C8 小时前
Android 功耗分析(底层篇)
android·功耗
曙曙学编程9 小时前
初级数据结构——树
android·java·数据结构