android so库导致的闪退及tombstone分析

news/2024/12/21 21:26:29/

android中有3种crash情况:未捕获的异常、ANR和闪退。未捕获的异常一般用crash文件就可以记录异常信息,而ANR无响应表现就是界面卡着无法响应用户操作,而闪退则是整个app瞬间退出,个人感觉对用户造成的体验最差。闪退一般是由于调用so库出错导致,像类似非法地址访问等。

闪退发生时在logcat中将日志过滤条件选为“No Filters”就可以看到完整的闪退日志,或者叫tombstone(墓碑)文件。
tombstone(墓碑)是当系统 crash 的时候,会保存一个 tombstone 文件到/data/tombstones目录下(Logcat中也会有相应的信息),文件就像墓碑一样记录了死亡了的进程的基本信息(例如进程的进程 号,线程号),死亡的地址(在哪个地址上发生了 Crash),死亡时的现场是什么样的(记录了一系列的堆栈调用信息)等等。

闪退(tombstone)主要日志如下,中间太长部分用省略号省略。

    --------- beginning of crash
2020-01-19 15:22:07.194 14414-14414/com.android.dj.crash.test A/libc: Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xfffffffd in tid 14414 (dj.crashtest), pid 14414 (dj.crashtest)
2020-01-19 15:22:07.249 14414-18253/com.android.dj.crash.test V/IOTCAPIS: [io_recv_proc][297]:
2020-01-19 15:22:07.249 14414-18253/com.android.dj.crash.test V/IOTCAPIS: get remote  packet ICE_SES_MSG_HIT
2020-01-19 15:22:07.303 18260-18260/? I/crash_dump32: obtaining output fd from tombstoned, type: kDebuggerdTombstone
2020-01-19 15:22:07.309 883-883/? I//system/bin/tombstoned: received crash request for pid 14414
2020-01-19 15:22:07.311 18260-18260/? I/crash_dump32: performing dump of process 14414 (target tid = 14414)
2020-01-19 15:22:07.313 1313-1416/system_process W/ActivityTaskManager: Activity pause timeout for ActivityRecord{567b991 u0 com.android.dj.crash.test/com.android.dj.crash.view.CrashTestActivity t2302 f}
···
2020-01-19 15:22:07.330 18260-18260/? A/DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
2020-01-19 15:22:07.330 18260-18260/? A/DEBUG: Build fingerprint: 'HUAWEI/VOG-AL00/HWVOG:10/HUAWEIVOG-AL00/10.0.0.185C00:user/release-keys'
2020-01-19 15:22:07.330 18260-18260/? A/DEBUG: Revision: '0'
2020-01-19 15:22:07.330 18260-18260/? A/DEBUG: ABI: 'arm'
2020-01-19 15:22:07.331 18260-18260/? A/DEBUG: SYSVMTYPE: MapleAPPVMTYPE: Art
2020-01-19 15:22:07.331 18260-18260/? A/DEBUG: Timestamp: 2020-01-19 15:22:07+0800
2020-01-19 15:22:07.331 18260-18260/? A/DEBUG: pid: 14414, tid: 14414, name: dj.crashtest  >>> com.android.dj.crash.test <<<
2020-01-19 15:22:07.331 18260-18260/? A/DEBUG: uid: 10218
2020-01-19 15:22:07.331 18260-18260/? A/DEBUG: signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xfffffffd
2020-01-19 15:22:07.331 18260-18260/? A/DEBUG:     r0  fffffffd  r1  ff99f161  r2  80000000  r3  00660e9d
2020-01-19 15:22:07.331 18260-18260/? A/DEBUG:     r4  ffffffff  r5  b9f33000  r6  867cb252  r7  ff99f108
2020-01-19 15:22:07.331 18260-18260/? A/DEBUG:     r8  00000000  r9  eb283e00  r10 ff99f7a0  r11 eb283e00
2020-01-19 15:22:07.331 18260-18260/? A/DEBUG:     ip  20000000  sp  ff99f0c8  lr  00000002  pc  e9097000
2020-01-19 15:22:07.419 2378-10947/? D/HwRecentsTaskUtils: refreshToCache
2020-01-19 15:22:07.419 2378-10947/? D/HwRecentsTaskUtils: searchFromDate
2020-01-19 15:22:07.427 2302-10215/? E/HsmCoreServiceImpl: onTransact in code is: 103
2020-01-19 15:22:07.427 2302-10215/? I/MediaProcessHandler: playingUids: 
···
2020-01-19 15:22:07.581 14414-18186/com.android.dj.crash.test I/IPCSDK: 1
2020-01-19 15:22:07.582 14414-18186/com.android.dj.crash.test V/IOTCAPIS: [p2p_global_thread][94]:
2020-01-19 15:22:07.582 14414-18186/com.android.dj.crash.test V/IOTCAPIS: p2p_global_thread GLOBAL_EVENT_MSG_CB_EVENT_SESSION_CONNECT_SUCCESS_P2P end
2020-01-19 15:22:07.691 18260-18260/? A/DEBUG: backtrace:
2020-01-19 15:22:07.691 18260-18260/? A/DEBUG:       #00 pc 0004f000  /apex/com.android.runtime/lib/bionic/libc.so (__memcpy_a15+200) (BuildId: f2470da1a22265f8104ce6bb9bcaf63e)
2020-01-19 15:22:07.691 18260-18260/? A/DEBUG:       #01 pc 00023d6f  /data/app/com.android.dj.crash.test-dA-LA_OmHFay2acWJnDeJA==/lib/arm/libipcsdk.so (LoopBuffWrite+138) (BuildId: cf6a63bc513797ba7582c510f377f11c44a12970)
2020-01-19 15:22:07.691 18260-18260/? A/DEBUG:       #02 pc 00031f75  /data/app/com.android.dj.crash.test-dA-LA_OmHFay2acWJnDeJA==/lib/arm/libipcsdk.so (CP2PSessionData::p2p_session_data_write(char*, int, unsigned char)+264) (BuildId: cf6a63bc513797ba7582c510f377f11c44a12970)
2020-01-19 15:22:07.691 18260-18260/? A/DEBUG:       #03 pc 0002a561  /data/app/com.android.dj.crash.test-dA-LA_OmHFay2acWJnDeJA==/lib/arm/libipcsdk.so (IOTC_Session_WriteData+66) (BuildId: cf6a63bc513797ba7582c510f377f11c44a12970)
···2020-01-19 15:22:07.693 18260-18260/? A/DEBUG:       #134 pc 0000202f  /system/bin/app_process32 (_start_main+38) (BuildId: 9979c215af59ed821fac6ea4f956225d)
2020-01-19 15:22:07.693 18260-18260/? A/DEBUG:       #135 pc 00004456  <anonymous:eb84e000>

可以看到
tombstone文件如何分析
主要看backtrace下面的函数调用,backtrace下的函数调用是从下往上的顺序执行的,所以在最上面的函数是最后执行的。
最后几行的函数调用如下:

2020-01-19 15:22:07.691 18260-18260/? A/DEBUG: backtrace:
2020-01-19 15:22:07.691 18260-18260/? A/DEBUG:       #00 pc 0004f000  /apex/com.android.runtime/lib/bionic/libc.so (__memcpy_a15+200) (BuildId: f2470da1a22265f8104ce6bb9bcaf63e)
2020-01-19 15:22:07.691 18260-18260/? A/DEBUG:       #01 pc 00023d6f  /data/app/com.android.dj.crash.test-dA-LA_OmHFay2acWJnDeJA==/lib/arm/libipcsdk.so (LoopBuffWrite+138) (BuildId: cf6a63bc513797ba7582c510f377f11c44a12970)
2020-01-19 15:22:07.691 18260-18260/? A/DEBUG:       #02 pc 00031f75  /data/app/com.android.dj.crash.test-dA-LA_OmHFay2acWJnDeJA==/lib/arm/libipcsdk.so (CP2PSessionData::p2p_session_data_write(char*, int, unsigned char)+264) (BuildId: cf6a63bc513797ba7582c510f377f11c44a12970)
2020-01-19 15:22:07.691 18260-18260/? A/DEBUG:       #03 pc 0002a561  /data/app/com.android.dj.crash.test-dA-LA_OmHFay2acWJnDeJA==/lib/arm/libipcsdk.so (IOTC_Session_WriteData+66) (BuildId: cf6a63bc513797ba7582c510f377f11c44a12970)

我们需要记住最后几个函数调用的地址00023d6f、00031f75、0002a561,后面用到的工具分析以及反汇编后的文件分析都会用到这几个偏移地址。

分析工具

android的ndk中提供了多个工具可以进行so库导致的crash的分析。

1)addr2line

addr2line 是 用来获得指定动态链接库文件或者可执行文件中指定地址对应的源代码信息的工具

D:\DJ_Software\Android\Ndk_Download\android-ndk-r10e-windows-x86_64\android-ndk-r10e\toolchains\arm-linux-androideabi-4.8\prebuilt\windows-x86_64\bin>arm-linux-androideabi-addr2line -f -e D:\flash_anr_pc\libipcsdk.so 00023d6f
LoopBuffWrite
??:?D:\DJ_Software\Android\Ndk_Download\android-ndk-r10e-windows-x86_64\android-ndk-r10e\toolchains\arm-linux-androideabi-4.8\prebuilt\windows-x86_64\bin>arm-linux-androideabi-addr2line -f -e D:\flash_anr_pc\libipcsdk.so 00031f75
_ZN15CP2PSessionData22p2p_session_data_writeEPcih
??:?

addr2line 命令及执行结果如上所示,-e参数指定文件名,-f参数显示函数名。只是得到了函数入口,详细运行信息没有。再使用objdump工具看下。

2)objdump

objdump可以将so库进行反汇编,反汇编后得到重定向文件,然后根据偏移地址得到更详细的函数调用上下文信息。

我实际使用ndk 20版本发现addr2line 运行可以,objdump总有一些错误,所以最后使用ndk 10命令执行成功。

D:\DJ_Software\Android\Ndk_Download\android-ndk-r10e-windows-x86_64\android-ndk-r10e\toolchains\arm-linux-androideabi-4.8\prebuilt\windows-x86_64\arm-linux-androideabi\bin>objdump -S -D D:\flash_anr_pc\libipcsdk.so > D:\flash_anr_pc\deassmble_libipc.log

命令执行结果就是将反汇编后的结果写入到D盘对应目录的deassmble_libipc.log文件里。

反汇编后结果分析

仍是重点分析前面提到的那3个函数。实际发现反汇编后不知为何得到的函数偏移地址总是比crash日志中的偏移地址小1。

IOTC_Session_WriteData函数

打开deassmble_libipc.log文件,搜索偏移地址“2a560”。

0002a51e <IOTC_Session_WriteData>:2a51e:   b5b0        push    {r4, r5, r7, lr}2a520:   af02        add r7, sp, #82a522:   b08a        sub sp, #40 ; 0x282a524:   469c        mov ip, r32a526:   4696        mov lr, r22a528:   460c        mov r4, r1
···2a560:   f7ea ef62   blx 15428 <_ZN15CP2PSessionData22p2p_session_data_writeEPcih@plt>2a564:   9009        str r0, [sp, #36]   ; 0x242a566:   e7ff        b.n 2a568 <IOTC_Session_WriteData+0x4a>2a568:   9809        ldr r0, [sp, #36]   ; 0x242a56a:   b00a        add sp, #40 ; 0x282a56c:   bdb0        pop {r4, r5, r7, pc}

可以看到IOTC_Session_WriteData函数在2a560行(crash日志中是0002a561)调用了p2p_session_data_write函数,p2p_session_data_write函数是C++类中的成员函数,所以在汇编中的函数名与纯C函数的函数名有所区别。

p2p_session_data_write函数

00031e6c <_ZN15CP2PSessionData22p2p_session_data_writeEPcih>:31e6c:   b5f0        push    {r4, r5, r6, r7, lr}31e6e:   af03        add r7, sp, #1231e70:   f84d bd04   str.w   fp, [sp, #-4]!31e74:   b098        sub sp, #96 ; 0x6031e76:   469c        mov ip, r331e78:   4696        mov lr, r2
···31f66:   d923        bls.n   31fb0 <_ZN15CP2PSessionData22p2p_session_data_writeEPcih+0x144>31f68:   e7ff        b.n 31f6a <_ZN15CP2PSessionData22p2p_session_data_writeEPcih+0xfe>31f6a:   9808        ldr r0, [sp, #32]31f6c:   f500 7067   add.w   r0, r0, #924    ; 0x39c31f70:   a914        add r1, sp, #80 ; 0x5031f72:   2209        movs    r2, #931f74:   f7e2 ea0c   blx 14390 <LoopBuffWrite@plt>31f78:   9910        ldr r1, [sp, #64]   ; 0x4031f7a:   2901        cmp r1, #131f7c:   9005        str r0, [sp, #20]31f7e:   db09        blt.n   31f94 <_ZN15CP2PSessionData22p2p_session_data_writeEPcih+0x128>

 可以看到实际的LoopBuffWrite函数调用在31f74行(crash日志中的00031f75)。

LoopBuffWrite函数

00023ce4 <LoopBuffWrite>:23ce4:   b5d0        push    {r4, r6, r7, lr}23ce6:   af02        add r7, sp, #823ce8:   b08c        sub sp, #48 ; 0x3023cea:   4613        mov r3, r223cec:   468c        mov ip, r123cee:   4686        mov lr, r0
···23d64:   3a01        subs    r2, #123d66:   4010        ands    r0, r223d68:   4408        add r0, r123d6a:   990a        ldr r1, [sp, #40]   ; 0x2823d6c:   9a08        ldr r2, [sp, #32]23d6e:   f7f0 ecde   blx 1472c <__aeabi_memcpy@plt>23d72:   990b        ldr r1, [sp, #44]   ; 0x2c23d74:   6809        ldr r1, [r1, #0]23d76:   9a0a        ldr r2, [sp, #40]   ; 0x2823d78:   f8dd e020   ldr.w   lr, [sp, #32]

中间部分代码省略,可以看到在23d6e行(crash日志中为00023d6f),也是差一行。LoopBuffWrite在此处执行了__aeabi_memcpy,估计是执行数据拷贝时发生了错误,再继续深入就需要对汇编语言有所了解。
最后,还有一个工具ndk-stack可以简化分析过程。使用参见
https://blog.csdn.net/u010144805/article/details/80763956


http://www.ppmy.cn/news/48302.html

相关文章

Revit构件显隐:参数和插件控制构件显隐性操作

一、如何通过参数来控制族中不同构件的显隐性? 在这里&#xff0c;将它分享给大家~ 首先&#xff0c;我们在项目中任意绘制一道墙&#xff0c;然后任意布置一个带有门把手的门&#xff0c;如下图&#xff1a; 接着&#xff0c;我们【双击】进入这个门族的编辑界面&#xff0c;…

海格里斯HEGERLS高速穿梭车按需定制|四向穿梭车货架和子母穿梭车货架别傻傻分不清?

随着物流行业和仓储行业的发展&#xff0c;越来越多的企业用户对仓储自动化程度要求越来越高。而近年来&#xff0c;各式各样的穿梭车AGV小车也现身各大物流展&#xff0c;备受各大中小型企业用户的青睐。且为了进一步提高仓库仓储的存储率&#xff0c;越来越多的仓储货架和仓储…

校园小助手【GUI/Swing+MySQL】(Java课设)

系统类型 Swing窗口类型Mysql数据库存储数据 使用范围 适合作为Java课设&#xff01;&#xff01;&#xff01; 部署环境 jdk1.8Mysql8.0Idea或eclipsejdbc 运行效果 本系统源码地址&#xff1a; 更多系统资源库地址&#xff1a;骚戴的博客_CSDN_更多系统资源 更多系统…

电容笔和触控笔有什么区别?2023平价好用的电容笔测评

无论是导电的材料&#xff0c;还是工作的原理&#xff0c;还是操作的方式&#xff0c;甚至是价格&#xff0c;电容笔都和一般的触控笔有着明显的区别。电容笔具有更小的笔尖&#xff0c;并且具有更好的耐磨性。而且现在科技进步很快&#xff0c;IPAD的市场也越来越大&#xff0…

android sdl编译

SDL&#xff08;Simple DirectMedia Layer&#xff09;是一套开放源代码的跨平台多媒体开发库&#xff0c;使用C语言写成。SDL提供了数种控制图像、声音、输出入的函数&#xff0c;让开发者只要用相同或是相似的代码就可以开发出跨多个平台。 1 下载SDL源码 http://www.libsd…

【go科学计算】详解 gonum 科学计算工具包

目录 1、详解 gonum 2、文件构成 1、详解 gonum Gonum 是一个由 Go 语言编写的数值计算和科学计算工具包,包含了多个子库,提供了丰富的数值计算、线性代数、统计学、优化、网络分析等功能。以下是 Gonum 中常见子库的一些主要功能: Gonum/mat:提供了矩阵和向量计算相关的…

CRM系统能帮助企业解决哪些问题?

随着信息化技术的不断发展和全球化的推进&#xff0c;市场竞争越来越激烈&#xff0c;客户需求也在不断变化。为了应对这种情况&#xff0c;越来越多的企业开始使用CRM系统来管理与客户的关系。那么&#xff0c;CRM系统到底解决了企业哪些问题呢&#xff1f; 一、提高客户满意…

程序员跳槽薪水涨了一倍,谈谈java工程师找新工作的八大技巧

大家好&#xff0c;这几天发生了一些事情&#xff0c;我找到了一份新工作&#xff0c;明天是第一天上班。我想先谈一下我的新工作待遇&#xff0c;因为我觉得相对来说还算比较满意。接下来我想谈一下我的个人经历&#xff0c;从毕业到现在的工作经历。第三个话题是我最近半个月…