so库崩溃问题的定位与分析

文章讲述了在Android应用中遇到so库崩溃问题时,如何通过分析tombstone日志和使用addr2line、ndk-stack工具定位问题,包括堆栈跟踪、内存信息和源代码定位的过程。

so库的崩溃会导致系统功能使用异常,通常logcat日志中会看到一大段崩溃的堆栈信息,并发出警告信号signal。一般是由C层代码以及libc的一些问题导致,我们导出/data/tombstones目录中的文件可以看更详细的堆栈信息,但解决问题还需要借助一些工具来定位分析。

logcat和tombstone日志

遇到如下signal错误,后面只要调用了so库的远程方法,都会不断报android.os.DeadObjectException,导致必须重启进程/设备才能恢复。假如logcat日志被冲掉了,别担心,tombstone日志已经保存为文件了,该文件记录了崩溃的进程的基本信息,堆栈调用信息,内存信息等。

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'rockchip/rk3588_t/rk3588_t:13/TD1A.220804.031/4.0.0.1:userdebug/release-keys'
Revision: '0'
ABI: 'arm64'
Timestamp: 2024-02-02 09:06:01.374766801+0800
Process uptime: 0s
Cmdline: /vendor/bin/hw/vendor.isolution.hardware.imw@1.0-service
pid: 568, tid: 568, name: imw@1.0-service  >>> /vendor/bin/hw/vendor.isolution.hardware.imw@1.0-service <<<
uid: 0
tagged_addr_ctrl: 0000000000000001 (PR_TAGGED_ADDR_ENABLE)
signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr --------
Abort message: 'Scudo ERROR: corrupted chunk header at address 0x20000729809c690'
    x0  0000000000000000  x1  0000000000000238  x2  0000000000000006  x3  0000007fe9f17740
    x4  0080808080808080  x5  0080808080808080  x6  0080808080808080  x7  8080808080808000
    x8  00000000000000f0  x9  00000073e80e9a00  x10 0000000000000001  x11 00000073e8127ce4
    x12 0101010101010101  x13 000000007fffffff  x14 00000000000024d2  x15 0000000000000050
    x16 00000073e818cd60  x17 00000073e8169b70  x18 00000073f0ace000  x19 0000000000000238
    x20 0000000000000238  x21 00000000ffffffff  x22 0000000000000000  x23 0000000000000001
    x24 00000073efd52000  x25 0000000000000000  x26 0000007fe9f18330  x27 0000000000000000
     x28 0000000000000000  x29 0000007fe9f177c0
     lr  00000073e8119868  sp  0000007fe9f17720  pc  00000073e8119894  pst 0000000000001000
 backtrace:
       #00 pc 0000000000051894  /apex/com.android.runtime/lib64/bionic/libc.so (abort+164) (BuildId: 058e3ec96fa600fb840a6a6956c6b64e)
       #01 pc 0000000000041714  /apex/com.android.runtime/lib64/bionic/libc.so (scudo::die()+8) (BuildId: 058e3ec96fa600fb840a6a6956c6b64e)
       #02 pc 0000000000041dc0  /apex/com.android.runtime/lib64/bionic/libc.so (scudo::ScopedErrorReport::~ScopedErrorReport()+32) (BuildId: 058e3ec96fa600fb840a6a6956c6b64e)
       #03 pc 0000000000041ef8  /apex/com.android.runtime/lib64/bionic/libc.so (scudo::reportHeaderCorruption(void*)+96) (BuildId: 058e3ec96fa600fb840a6a6956c6b64e)
       #04 pc 0000000000043914  /apex/com.android.runtime/lib64/bionic/libc.so (scudo::Allocator<scudo::AndroidConfig, &(scudo_malloc_postinit)>::deallocate(void*, scudo::Chunk::Origin, unsigned long, unsigned long)+296) (BuildId: 058e3ec96fa600fb840a6a6956c6b64e)
       #05 pc 0000000000006a7c  /vendor/lib64/vendor.isolution.hardware.imw@1.0-impl.so (vendor::isolution::hardware::imw::V1_0::implementation::ImwManager::readFromImwByCmd(unsigned int, unsigned int, std::__1::function<void (android::hardware::hidl_vec<int> const&, signed char)>)+152) (BuildId: b3fcf5d65fafb16ffa5263bb857312cc)
       #06 pc 000000000002655c  /vendor/lib64/vendor.isolution.hardware.imw@1.0.so (vendor::isolution::hardware::imw::V1_0::BnHwImwManager::_hidl_readFromImwByCmd(android::hidl::base::V1_0::BnHwBase*, android::hardware::Parcel const&, android::hardware::Parcel*, std::__1::function<void (android::hardware::Parcel&)>)+352) (BuildId: 479e6e084f9287d5aed155e7e2045996)
       #07 pc 000000000002d394  /vendor/lib64/vendor.isolution.hardware.imw@1.0.so (vendor::isolution::hardware::imw::V1_0::BnHwImwManager::onTransact(unsigned int, android::hardware::Parcel const&, android::hardware::Parcel*, unsigned int, std::__1::function<void (android::hardware::Parcel&)>)+2588) (BuildId: 479e6e084f9287d5aed155e7e2045996)
       #08 pc 000000000008ee40  /apex/com.android.vndk.v33/lib64/libhidlbase.so (android::hardware::BHwBinder::transact(unsigned int, android::hardware::Parcel const&, android::hardware::Parcel*, unsigned int, std::__1::function<void (android::hardware::Parcel&)>)+156) (BuildId: 3fafcf3a9734f0d41045c2b5f828b363)
       #09 pc 0000000000093dfc  /apex/com.android.vndk.v33/lib64/libhidlbase.so (android::hardware::IPCThreadState::executeCommand(int)+2784) (BuildId: 3fafcf3a9734f0d41045c2b5f828b363)
       #10 pc 00000000000931bc  /apex/com.android.vndk.v33/lib64/libhidlbase.so (android::hardware::IPCThreadState::getAndExecuteCommand()+224) (BuildId: 3fafcf3a9734f0d41045c2b5f828b363)
       #11 pc 0000000000094388  /apex/com.android.vndk.v33/lib64/libhidlbase.so (android::hardware::IPCThreadState::joinThreadPool(bool)+172) (BuildId: 3fafcf3a9734f0d41045c2b5f828b363)
       #12 pc 0000000000001124  /vendor/bin/hw/vendor.isolution.hardware.imw@1.0-service (main+208) (BuildId: aa810ec70bc1d8a8b886da58bf02ac49)
       #13 pc 000000000004a0f4  /apex/com.android.runtime/lib64/bionic/libc.so (__libc_init+96) (BuildId: 058e3ec96fa600fb840a6a6956c6b64e)

初步定位为hardware.imw so库发生了错误:‘Scudo ERROR: corrupted chunk header at address 0x20000729809c690’,这个问题只知道内存释放时的检测环节发生了地址头错误,具体哪一行怎么定位呢?

addr2line工具

addr2line工具可用来获得指定动态链接库文件指定地址对应的源代码信息。AOSP源码或NDK下已自带该工具,配置环境变量或者直接使用即可。
1、我们定位日志中的这一行打印信息和地址0000000000006a7c

 #05 pc 0000000000006a7c  /vendor/lib64/vendor.isolution.hardware.imw@1.0-impl.so (vendor::isolution::hardware::imw::V1_0::implementation::ImwManager::readFromImwByCmd(unsigned int, unsigned int, std::__1::function<void (android::hardware::hidl_vec<int> const&, signed char)>)+152) (BuildId: b3fcf5d65fafb16ffa5263bb857312cc)

2、关联调试版本的so库并使用命令对准地址:

 ./prebuilts/clang/host/linux-x86/clang-r450784d/bin/llvm-addr2line -e ./out/target/product/rk3588_t/symbols/vendor/lib64/vendor.isolution.hardware.imw@1.0-impl.so 0000000000006a7c

3、最后问题暴露在ImwManager.cpp中的第246行
在这里插入图片描述

4、查看对应的源代码,free函数回收时发生了错误。
在这里插入图片描述

ndk-stack工具

Android NDK自带的工具,通常用于native C/C++应用程序和库的崩溃调试。控制台使用会打印Crash dump信息。

ndk-stack -sym C:\Users\ist\Desktop\so\vendor.isolution.hardware.imw@1.0-impl.so -dump C:\Users\ist\Desktop\so\test.txt

在这里插入图片描述

总结

了解tombstone日志中关键信息的含义,配合addr2line或ndk-stack这两个工具的使用,那么定位分析崩溃问题就非常容易了。工欲善其事,必先利其器。

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值