Android Tombstone/Crash的log分析和定位 addr2line工具的使用

这几天同事的一个库崩溃,基本要把他整崩溃了,试着帮他定位一下。

 

拿到日志

2019-05-14 11:51:53.638 28080-28080/? A/DEBUG: Build fingerprint: 'Android/rk3399_firefly_aio_lvds_mid/rk3399_firefly_aio_lvds_mid:8.1.0/OPM6.171019.030.B1/110155:userdebug/test-keys'
2019-05-14 11:51:53.638 28080-28080/? A/DEBUG: Revision: '0'
2019-05-14 11:51:53.638 28080-28080/? A/DEBUG: ABI: 'arm'
2019-05-14 11:51:53.638 28080-28080/? A/DEBUG: pid: 27554, tid: 27848, name: Thread-6  >>>  <<<
2019-05-14 11:51:53.638 28080-28080/? A/DEBUG: signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xfffffffc
2019-05-14 11:51:53.638 28080-28080/? A/DEBUG:     r0 fffffff4  r1 00000000  r2 fffffffc  r3 ef62cae1
2019-05-14 11:51:53.638 28080-28080/? A/DEBUG:     r4 c04df760  r5 c04df75c  r6 c04df730  r7 c04df5c8
2019-05-14 11:51:53.638 28080-28080/? A/DEBUG:     r8 c04e7398  r9 c04e3638  sl c04df738  fp c04df730
2019-05-14 11:51:53.638 28080-28080/? A/DEBUG:     ip bec42cd4  sp c04df5b8  lr be2f7449  pc beadcce4  cpsr 80070030

E//system/bin/tombstoned: Tombstone written to: /data/tombstones/tombstone_6

注意最后一行,崩溃日志的位置。

通过 adb 执行:

adb root

adb pull /data/tombstones/    ./

这个目录下的文件把拖下来;如果是windows一般在C:\Users\Administrator 这个目录下:

打开 tombstone_6

Build fingerprint: 'rockchip/rk3399_firefly_aio_lvds_box/rk3399_firefly_aio_lvds_box:7.1.2/NHG47K/liangk08091540:userdebug/test-keys'
Revision: '0'
ABI: 'arm'
pid: 18192, tid: 19090, name: Thread-6  >>> com.xxxxxxx <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x40080000
    r0 00000000  r1 40080000  r2 c40c867c  r3 c3c03580
    r4 bf70e614  r5 bf70e618  r6 bf70e610  r7 bf70e5c8
    r8 c43c1259  r9 c39020b2  sl 450147b7  fp c3e48305
    ip 00000000  sp bf70a4c0  lr bcc8f8a5  pc bcc8faa0  cpsr 200e0030
    d0  4082607140000000  d1  c39020b2c40c867c
    d2  4097d5a644fb6438  d3  4082db99c351e161
    d4  4097d5a6c393a1ad  d5  3fe0aba344bead32
    d6  c078b1c7c3c569f9  d7  4082d251c3c03580
    d8  3e5236a04415a322  d9  3f055d1f43607d0f
    d10 c3e483053f000000  d11 c338f291c2cfd268
    d12 44788000c32745fe  d13 43f2dc184388ec46
    d14 426566c044c2c5c5  d15 c43c12593f541ab7
    d16 bfeeb31f445aa523  d17 bfeeb31f445aa523
    d18 3ff0000000000000  d19 3fa4f28315ad5a4e
    d20 3feeb0d7cea52a5b  d21 3c5a626331000000
    d22 3f7b6ca377b310c3  d23 0000000400000004
    d24 40001b8400000000  d25 3fd5558841f82cae
    d26 3f7b552b00000000  d27 3fdb6df51da55c96
    d28 000080c2000012a6  d29 0000c3e60000bafd
    d30 bff0000009e56e13  d31 00000000042444fb
    scr 80000013

backtrace:
    #00 pc 007eaaa0  /data/app/com.xxxxxx/lib/arm/libXXXXX.so (_Z15irPackageCheck2RN5boost10shared_ptrIN3pcl10PointCloudINS1_8PointXYZEEEEERSt6vectorIdSaIdEERN2cv3MatESA_R7CCuboid+1695)
    #01 pc 3ffffffd  <unknown>

这里我们主要需要 #00 pc 007eaaa0 这是最后崩溃的地方:

在NDK 中找到 arm-linux-androideabi-addr2line.exe(注意这个是 32位的,如果你是64,请用64位的

我的文件位置:E:\ndk\android-ndk-r17b\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\bin

做一个批处理文件,把你的so 拷贝到这个文件,下面是批处理文件内容:

arm-linux-androideabi-addr2line.exe  -C -f -e libxxxx.so 007eaaa0
 pause

注意:libxxxx.so, 007eaaa0  替换成你的 so,和 pc address

执行可以得到崩溃的具体函数;

这个查了一下是 double 变量溢出了,唉不小心。

别人写的一个批处理文件不错 tool_addr2line.bat:

    @echo off  
    rem current direction  
    set cur_dir=%cd%
      
    rem addr2line tool path  
    set add2line_path=E:\ndk\android-ndk-r17b\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\bin\arm-linux-androideabi-addr2line.exe
      
    rem debug file  
    set /p debug_file=input debug filename:
      
    rem debug_file_path  
    set debug_file_path=%cur_dir%\%debug_file%  
      
    rem debug address  
    set /p debug_addr=PC address:
      
    echo ----------------------- addr2line ------------------------  
    echo debug file path: %debug_file_path%  PC=%debug_addr%  
      
    if exist %debug_file_path% (  
    %add2line_path% -e %debug_file_path% -f %debug_addr%   
    ) else (  
    echo debug file is no exist.   
    )  
      
    echo ---------------------------------------------------------  
    pause  

一个更全的:

https://www.cnblogs.com/CoderTian/p/5980426.html

<think>好的,我现在需要解决Android APK在运行时崩溃并生成tombstone文件的问题。首先,我得理解什么是tombstone文件。根据之前学过的知识,tombstone文件是Android系统在应用发生严重错误(如段错误或异常终止)时生成的崩溃日志,包含了程序崩溃时的内存状态、寄存器值、堆栈跟踪等信息,这些对调试很有帮助[^1]。 接下来,我需要知道如何获取分析这些tombstone文件。通常,这些文件位于设备的`/data/tombstones/`目录下,但访问这个目录可能需要root权限。如果没有root权限,可能需要通过adb命令来拉取文件。例如使用`adb pull /data/tombstones/tombstone_XX`命令。不过,现在很多设备可能限制了访问权限,这时候可能需要使用`adb bugreport`来获取完整的系统报告,其中可能包含tombstone信息[^2]。 然后,分析tombstone文件的内容。里面会有崩溃时的堆栈跟踪,这时候需要用到NDK中的工具,比如addr2line或者ndk-stack来将地址转换为具体的代码行。例如,使用`ndk-stack -sym /path/to/symbols -dump tombstone_XX`命令可以解析堆栈信息。这一步可能需要确保有对应的调试符号文件,通常在编译APK时生成的so文件带有符号信息,或者使用带调试信息的构建版本[^3]。 接下来,检查崩溃的原因。常见的崩溃原因包括空指针解引用、数组越界、内存泄漏、多线程竞争条件等。需要根据堆栈信息定位到具体的代码位置,检查相关代码是否符合预期。例如,如果堆栈指向某个JNI函数,那么可能是本地代码中的错误,需要检查C/C++代码部分是否正确处理了内存异常[^4]。 此外,考虑使用Android Studio的调试工具,比如LLDB或者Logcat来实时监控应用运行时的日志崩溃信息。开启详细的日志输出,比如在Logcat中过滤CRASH或ERROR级别的日志,有助于捕捉崩溃前的上下文信息。同时,确保在build.gradle中启用了调试选项符号表生成,例如设置`debuggable true``minifyEnabled false`以便更容易分析问题[^5]。 另外,复现崩溃场景是关键。如果崩溃是偶发的,可能需要多次测试或使用压力测试工具来触发问题。自动化测试框架如Espresso或Monkey测试可以帮助模拟用户操作,增加崩溃复现的概率。一旦复现,及时获取tombstone文件并分析[^6]。 还有,检查是否有第三方库或系统API的兼容性问题。某些崩溃可能只在特定Android版本或设备上出现,查看崩溃设备的型号、系统版本等信息,确认是否存在已知的兼容性问题。更新依赖库到最新版本可能解决已知的问题[^7]。 最后,考虑内存问题。使用Android Profiler检查内存使用情况,查看是否有内存泄漏或溢出。工具如LeakCanary可以帮助检测内存泄漏,特别是在Activity或Fragment没有正确释放的情况下[^8]。 总结步骤大致是:获取tombstone文件,使用工具解析堆栈,定位问题代码,检查常见错误原因,结合调试工具日志分析,复现并验证修复方案。同时,需要注意权限问题环境配置,确保能够有效获取分析所需信息。</think>### Android APK 运行时崩溃及tombstone文件分析解决方案 #### 1. 获取tombstone文件 - **路径**: 设备中tombstone文件通常位于 `/data/tombstones/`,命名格式为 `tombstone_XX`(XX为编号)[^1]。 - **提取方式**: - 通过adb命令拉取: ```bash adb root adb pull /data/tombstones/tombstone_XX ``` - 若无root权限,可通过 `adb bugreport` 生成完整报告,从中提取tombstone文件[^2]。 #### 2. 分析tombstone文件内容 - **关键信息**: - **崩溃线程的堆栈跟踪**(`backtrace` 部分) - **寄存器值**(如`pc`指向崩溃时的指令地址) - **内存映射**(`memory map` 显示模块加载地址) - **工具使用**: - 使用NDK的 `ndk-stack` 解析符号: ```bash ndk-stack -sym <包含符号表的目录> -dump tombstone_XX ``` - 或通过 `addr2line` 定位代码行: ```bash arm-linux-androideabi-addr2line -e <带符号的.so文件> <崩溃地址> ``` #### 3. 常见崩溃原因及排查 - **空指针解引用**: 检查JNI代码或Native层对象是否未初始化。 - **内存越界**: 确认数组/缓冲区操作的边界条件。 - **多线程问题**: 检查锁竞争或异步任务中的资源访问。 - **JNI错误**: 使用 `CheckJNI` 模式验证JNI调用合法性: ```bash adb shell setprop debug.checkjni 1 ``` #### 4. 调试与日志增强 - **Logcat过滤崩溃日志**: ```bash adb logcat -s AndroidRuntime:E *:S ``` - **启用调试模式**: 在 `build.gradle` 中配置: ```groovy android { buildTypes { debug { debuggable true minifyEnabled false } } } ``` #### 5. 复现与测试 - **压力测试**: 使用Monkey命令模拟用户操作: ```bash adb shell monkey -p your.package.name -v 1000 ``` - **兼容性测试**: 针对不同API级别设备型号验证崩溃是否特定于环境。 #### 6. 第三方库与内存分析 - **更新依赖**: 检查第三方库版本,修复已知问题。 - **内存分析工具**: - **Android Profiler**: 实时监控内存/CPU使用。 - **LeakCanary**: 自动检测内存泄漏[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

恋恋西风

up up up

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值