• so 动态库崩溃问题定位(addr2line与objdump)


    一、需求分析

    so 的崩溃并不像 Java 代码那么好定位,我们通常看到的就只是 so 中的一大段崩溃的堆栈信息。那么我们怎么通过这个堆栈信息来定位我们的问题呢?

     
    二、addr2line
    1. 介绍

    Addr2line 工具(它是标准的 GNU Binutils 中的一部分)是一个可以将指令的地址和可执行映像转换成文件名、函数名和源代码行数的工具。
    一般适用于 debug 版本或带有 symbol 信息的库。

     
    2. 工具位置

    我们下载的 NDK 里面已经默认有了这个工具,对应的路径如下,其中 .. 表示你的 NDK 安装的路径(每个人的可能都不一样)

    Windows:
    32位:.. dk-bundle oolchainsarm-linux-androideabi-4.9prebuiltwindows-x86_64inarm-linux-androideabi-addr2line.exe
    64位:.. dk-bundle oolchainsaarch64-linux-android-4.9prebuiltwindows-x86_64inaarch64-linux-android-addr2line.exe
    Linux:
    32位:../android-ndk-r16b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-addr2line
    64位:../android-ndk-r16b/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-addr2line

    当然我们也可以把这个路径配置到环境变量中去。
    3. 指令释义

    4. 使用示例


    5. 实际应用

    例如出现了如下崩溃:

    signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x4d42d8b4
        r0 ead025fc  r1 ead025f0  r2 ead025fd  r3 4d42d8a4
        r4 efba899c  r5 ead025fc  r6 ead0263c  r7 efba8984
        r8 ead00000  r9 ead00000  sl ead025fc  fp 00000001
        ip 00000000  sp ee5ff348  lr 0007ffff  pc efb5e15e  cpsr 800f0030
     
    backtrace:
        #00 pc 0005915e  /system/lib/libc.so (arena_dalloc_bin_locked_impl+345)
        #01 pc 00058ffd  /system/lib/libc.so (je_arena_dalloc_bin_junked_locked+12)
        #02 pc 0007ae27  /system/lib/libc.so (je_tcache_bin_flush_small+366)
        #03 pc 0007ac5b  /system/lib/libc.so (je_tcache_event_hard+58)
        #04 pc 0006a505  /system/lib/libc.so (je_malloc+636)
        #05 pc 00339c7f  /vendor/lib/libstfaceunlock.so
        #06 pc 00282064  /vendor/lib/libstfaceunlock.so
        #07 pc 001fc094  /vendor/lib/libstfaceunlock.so
        #08 pc 002056b0  /vendor/lib/libstfaceunlock.so
        #09 pc 002809d8  /vendor/lib/libstfaceunlock.so
        #10 pc 00103f58  /vendor/lib/libstfaceunlock.so
        #11 pc 00105398  /vendor/lib/libstfaceunlock.so
        #12 pc 001062c4  /vendor/lib/libstfaceunlock.so
        #13 pc 000a4f14  /vendor/lib/libstfaceunlock.so
        #14 pc 0007957c  /vendor/lib/libstfaceunlock.so
        #15 pc 00023d2c  /vendor/lib/libstfaceunlock.so (cv_face_create_tracker+424)


    我们就可以把每个段地址翻译成具体的代码:

       

    signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x4d42d8b4
        r0 ead025fc  r1 ead025f0  r2 ead025fd  r3 4d42d8a4
        r4 efba899c  r5 ead025fc  r6 ead0263c  r7 efba8984
        r8 ead00000  r9 ead00000  sl ead025fc  fp 00000001
        ip 00000000  sp ee5ff348  lr 0007ffff  pc efb5e15e  cpsr 800f0030
     
    backtrace:
        #00 pc 0005915e  /system/lib/libc.so (arena_dalloc_bin_locked_impl+345)
        #01 pc 00058ffd  /system/lib/libc.so (je_arena_dalloc_bin_junked_locked+12)
        #02 pc 0007ae27  /system/lib/libc.so (je_tcache_bin_flush_small+366)
        #03 pc 0007ac5b  /system/lib/libc.so (je_tcache_event_hard+58)
        #04 pc 0006a505  /system/lib/libc.so (je_malloc+636)
        #05 pc 00339c7f  /vendor/lib/libstfaceunlock.so --> /usr/local/google/buildbot/src/android/master-ndk/toolchain/gcc/gcc-4.9/libstdc++-v3/libsupc++/new_op.cc:56
        #06 pc 00282064  /vendor/lib/libstfaceunlock.so --> google::protobuf::internal::StringTypeHandlerBase::New()
        #07 pc 001fc094  /vendor/lib/libstfaceunlock.so --> caffe::LayerParameter::MergePartialFromCodedStream(google::protobuf::io::CodedInputStream*)
        #08 pc 002056b0  /vendor/lib/libstfaceunlock.so --> caffe::NetParameter::MergePartialFromCodedStream(google::protobuf::io::CodedInputStream*)
        #09 pc 002809d8  /vendor/lib/libstfaceunlock.so --> google::protobuf::MessageLite::ParseFromCodedStream(google::protobuf::io::CodedInputStream*)
        #10 pc 00103f58  /vendor/lib/libstfaceunlock.so --> ReadProtoFromBinaryResource(protector::ModelResource&, google::protobuf::MessageLite*)
        #11 pc 00105398  /vendor/lib/libstfaceunlock.so --> protector::CaffeModel::Init(protector::TarModelResource&, std::string const&, protector::NetConfig, bool
        #12 pc 001062c4  /vendor/lib/libstfaceunlock.so --> protector::ModelLoader::LoadByName(std::string const&, bool) const
        #13 pc 000a4f14  /vendor/lib/libstfaceunlock.so --> stsdk::detection::DetectorHunter::Init(protector::ModelLoader&)
        #14 pc 0007957c  /vendor/lib/libstfaceunlock.so --> __appProtect_cv_common_detection_hunter_create_start
        #15 pc 00023d2c  /vendor/lib/libstfaceunlock.so (cv_face_create_tracker+424)

     
    三、objdump
    1. 介绍

    objdump 是 gcc 工具,用来查看编译后目标文件的组成。
    2. 工具位置

    我们下载的 NDK 里面同样默认有了这个工具,对应的路径如下,其中 .. 表示你的 NDK 安装的路径(每个人的可能都不一样)

    Windows:
    32位:.. dk-bundle oolchainsarm-linux-androideabi-4.9prebuiltwindows-x86_64inarm-linux-androideabi-objdump.exe
    64位:.. dk-bundle oolchainsaarch64-linux-android-4.9prebuiltwindows-x86_64inaarch64-linux-android-objdump.exe
    Linux:
    32位:../android-ndk-r16b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-objdump
    64位:../android-ndk-r16b/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-objdump

    当然我们也可以把这个路径配置到环境变量中去。
    3. 指令释义


    4. 使用示例

    通常我们会把输出重定向到一个文本文件中去,使用语法如下:

    arm-linux-androideabi-objdump -d 库文件 > 输出文件

    打开文件,查看汇编执行顺序,找到 23098 地址段


    通过 backtrace 地址里的汇编段和偏移量在上面的汇编顺序里找到对应汇编命令


    这里的方法名不容易看懂,可以使用 c++filt 命令找到实际的代码段可以更方面定位代码

    然后找到具体的代码

    判断是在 gen_statistics 函数之前,所以增加非空判断



    其它:
    ————————————————
    版权声明:本文为CSDN博主「阿飞__」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/afei__/article/details/81181827

  • 相关阅读:
    lua 学习
    IOS表情存入MYSQL数据库失败
    C# string数组转int数组
    打开端口
    win10下设置IIS、安装php7.2
    NET Core 应用程序 IIS 运行报错 502.3-Gateway
    微信小程序(一)--简单的介绍
    C#socket通信
    使用VScode 的插件
    Vue学习笔记:Slot
  • 原文地址:https://www.cnblogs.com/yipianchuyun/p/13130155.html
Copyright © 2020-2023  润新知