Android通过addr2line工具分析native crash log

先上效果图吧

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

最终效果如上图

你可能感兴趣的:(移动开发,操作系统)