红色部分 pc 000007cc 代表当前 pc 指向的位置。libnative-lib.so 代表在哪个库里面。于是我
们就需要知道,libnative-lib.so 库的 pc 000007cc 偏移位置,是个什么代码。
我们从 NDK 开发包中找到
D:\android-ndk-r19c\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\bin
arm-linux-androideabi-addr2line.exe 这个工具。 然后从工程里面,将
build\intermediates\ndkBuild\debug\obj\local\x86 (如果是 armeabi-v7a,去对应目录下找)
下面的 libnative-lib.so 然后 CMD 命令,使
用
参数解释: -e 指定 so 的存放位置
-C 指定当前 pc 在 so 的位置
-f 输出函数方法名
我们可以看到结果里面,输出了方法名:
Java_hellojni_codegg_com_hellojni_MainActivity_myResultFromJNI ,并且打印了文件名
native-lib.c 和出错的代码在 C 文件的行号。
本节主要从分析的方向,将一个异常的分析思路,进行展开。除此之外,我们在分析问题时,
要去看其他线程的堆栈,以及 log 信息,将输出的 log 信息 和 自己的分析进行验证,进一
步确定异常路径。
但这个分析过程,属于本质东西,理解透这个,会用这个去定位分析问题。希望大家能够掌
握,最好跟着课程,一个个敲下来,学到知识。
19. 延伸内容
很快,就到了收尾章节。相信通过前面的课程,一个个实例讲解,拆解分析过程,能够让你
明白,这些工具之间的联系。当然,此课程不会让你一下子全都学透,但是让你明白,配置
的是怎么生效的, JNI 的实现逻辑,这个才是关键的。
在入门之后,如果你的工作,平时就是需要做 NDK 开发,经常跟它打交道,那么以下的一
些分享,会帮助到你。
19.1 一些常用工具
在 NDK 的开发包中,放置了很多有用的工具,我们平时可以看看。具体为:
arm-linux-androideabi-addr2line 分析异常地址arm-linux-androideabi-ar 输出静态库的方法,可以拆包打包
arm-linux-androideabi-objdump 输出动态库的方法
arm-linux-androideabi-ldxxx 链接器,有不同的链接器,实现了不一样的链接规则,arm 的默
认配置的是 bfb。
arm-linux-androideabi-strip 删除无效信息,调试信息,减轻可执行文件大小
如果你要深入研究编译出来的目标结构(这里指 ELF 格式),多使用这里面的工具。同时
如果不想直接用命令,可以试试 IDA Pro 工具。关于上面每个命令的用法,可以用 help 输
出,或者直接百度,比如第一个搜索 GCC addr2line 即可,搜出来的 ARM GCC 基本都能直
接用的。
19.2 gcc 参数官方文档
https://gcc.gnu.org/onlinedocs/gcc-8.3.0/gcc/
https://gcc.gnu.org/onlinedocs/gcc-8.3.0/gcc/Developer-Options.html#Developer-Options
19.3 NDK 注意事项
NDK 版本之间,是不考虑兼容性的。这个是一个注意点,所以 r8 编译能过的项目,很有可
能 r19 编译不过,这个大家要有心理准备。
19.4 abi 的相关配置
https://developer.android.google.cn/ndk/guides/abis
https://blog.csdn.net/afei__/article/details/81272251
19.5 CMake 的参考文档
https://cmake.org/cmake/help/latest/index.html
https://cmake.org/cmake-tutorial/
https://blog.csdn.net/afei__/article/details/81201039
https://www.hahack.com/codes/cmake/#自定义编译选项
19.6 JavaVM 与 JNIEnv 的关系
https://blog.csdn.net/qq_32583189/article/details/53172316
学完了 NDK,基本上打通了 JAVA 和本地的桥梁,于是我们接着来说。