先上效果图吧
0. Crash代码以及初步分析crash log
问题jni代码,下面主动第8行主动抛出一个异常
#include
#include
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_zjw_jnitest_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
throw "error";
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
复制代码
运行这个简单的hello world 项目,下面为异常栈信息
2019-01-14 18:27:11.189 32144-32144/? A/DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
//省略不重要的
2019-01-14 18:27:11.806 32144-32144/? A/DEBUG: backtrace:
2019-01-14 18:27:11.806 32144-32144/? A/DEBUG: #00 pc 0000000000026b98 /system/lib64/libc.so (syscall+24)
2019-01-14 18:27:11.806 32144-32144/? A/DEBUG: #01 pc 0000000000029775 /system/lib64/libc.so (abort+101)
2019-01-14 18:27:11.806 32144-32144/? A/DEBUG: #02 pc 000000000000f84b /data/app/com.example.zjw.jnitest-013SXv3KOGmbdSMeUoHolA==/lib/x86_64/libnative-lib.so
2019-01-14 18:27:11.806 32144-32144/? A/DEBUG: #03 pc 000000000000f999 /data/app/com.example.zjw.jnitest-013SXv3KOGmbdSMeUoHolA==/lib/x86_64/libnative-lib.so
2019-01-14 18:27:11.806 32144-32144/? A/DEBUG: #04 pc 000000000000cb92 /data/app/com.example.zjw.jnitest-013SXv3KOGmbdSMeUoHolA==/lib/x86_64/libnative-lib.so
2019-01-14 18:27:11.806 32144-32144/? A/DEBUG: #05 pc 000000000000c4f5 /data/app/com.example.zjw.jnitest-013SXv3KOGmbdSMeUoHolA==/lib/x86_64/libnative-lib.so
2019-01-14 18:27:11.806 32144-32144/? A/DEBUG: #06 pc 000000000000c48e /data/app/com.example.zjw.jnitest-013SXv3KOGmbdSMeUoHolA==/lib/x86_64/libnative-lib.so (__cxa_throw+110)
2019-01-14 18:27:11.806 32144-32144/? A/DEBUG: #07 pc 000000000000c35c /data/app/com.example.zjw.jnitest-013SXv3KOGmbdSMeUoHolA==/lib/x86_64/libnative-lib.so (Java_com_example_zjw_jnitest_MainActivity_stringFromJNI+60)
2019-01-14 18:27:11.806 32144-32144/? A/DEBUG: #08 pc 00000000005ce061 /system/lib64/libart.so (art_quick_generic_jni_trampoline+209)
2019-01-14 18:27:11.806 32144-32144/? A/DEBUG: #09 pc 00000000005c3ab4 /system/lib64/libart.so (art_quick_invoke_stub+756)
2019-01-14 18:27:11.807 32144-32144/? A/DEBUG: #10 pc 00000000000cf5f2 /system/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+226)
2019-01-14 18:27:11.807 32144-32144/? A/DEBUG: #11 pc 00000000002a1b91 /system/lib64/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+321)
//省略不重要的
复制代码
接下来就是如何分析so中哪一行代码报错 看到crash log 中 搜索关键词”backtrace“,查看到so的 这里有2个 libnative-lib.so
这个是自己的so,so名由自己项目中 CMakeLists.text中add_library 决定的,CMakeLists.text内如如下
CMakeLists.text
复制代码
add_library( # Sets the name of the library. native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/cpp/native-lib.cpp)
```
复制代码
生成时给你 native-lib
前面带了一个lib,输出的so就变成了libnative-lib.so
1. 查找目标安卓设备对应ABI的addr2line 工具位置
以mac os为例子 命令行中执行 find . -name *addr2line
zjwdeMacBook-Pro:~ zjw$ find . -name *addr2line
./Library/Android/sdk/ndk-bundle/toolchains/x86-4.9/prebuilt/darwin-x86_64/bin/i686-linux-android-addr2line
./Library/Android/sdk/ndk-bundle/toolchains/x86_64-4.9/prebuilt/darwin-x86_64/bin/x86_64-linux-android-addr2line
./Library/Android/sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-addr2line
./Library/Android/sdk/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/bin/aarch64-linux-android-addr2line
复制代码
找到你目标android设备对应ABI的addr2line工具,例如我运行本demo的安卓设备是PC上的官方模拟器,那么就选./Library/Android/sdk/ndk-bundle/toolchains/x86_64-4.9/prebuilt/darwin-x86_64/bin/x86_64-linux-android-addr2line
找个文本文档记录下来这个路径
2. 查找发生crash的so位置
这里就是crash日志中 我们分析出的libnative-lib.so
,进入项目目录找一下,或者命令行搜一下。这里so所在位置是./AndroidStudioProjects/Aceso/JNITest/app/build/intermediates/transforms/mergeJniLibs/debug/0/lib/x86_64/libnative-lib.so
,经验就是尽量往app/build/intermediates/transforms/mergeJniLibs
这个目录找
3. 通过crash log 记录要定位代码所对应的 偏移地址
这里记录下2019-01-14 18:27:11.806 32144-32144/? A/DEBUG: #07 pc 000000000000c35c /data/app/com.example.zjw.jnitest-
该行的偏移地址 000000000000c35c
4. 执行最终命令
./Library/Android/sdk/ndk-bundle/toolchains/x86_64-4.9/prebuilt/darwin-x86_64/bin/x86_64-linux-android-addr2line -f -e ./AndroidStudioProjects/Aceso/JNITest/app/build/intermediates/transforms/mergeJniLibs/debug/0/lib/x86_64/libnative-lib.so 000000000000c35c
最终效果如上图