[Python] Native Crash Addr2line 自动解析Tombstone文件脚本

本文介绍了一款Python脚本,能够自动解析Android系统的Tombstone文件,支持32位和64位进程,适用于单个文件及批量解析。通过调用addr2line工具,脚本能将崩溃调用栈中的地址转换为可读的函数名和源代码位置,帮助开发者快速定位问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[Python] Native Crash Addr2line 自动解析Tombstone文件脚本

文末附上脚本源码
2019.4.24 更新,32位,64位 进程tombstone的兼容

使用方法

1.解析单个tombstone文件:

python ./as_tomba.py tombstone_file_path symbol_root_path
在tombstone_file_path目录下生成 tombstone文件名_pid_pname.out 的解析之后文件

2.批量解析文件夹中的tombstone文件:

python ./as_tomba.py tombstone_file_dir symbol_root_path
将tombstone_file_dir目录下的含有tombstone调用栈的文件解析输出到该目录下相应的输出文件中

3.兼容logcat中的tombstone调用栈

如logcat中有如下log:

01-09 14:11:02.220 16332 16811 F libc : Fatal signal 6 (SIGABRT), code -6 (SI_TKILL) in tid 16811 (HwBinder:16332_), pid 16332 (provider@2.4-se)
01-09 14:11:02.278 17079 17079 I crash_dump64: obtaining output fd from tombstoned, type: kDebuggerdTombstone
01-09 14:11:02.278 888 888 I /system/bin/tombstoned: received crash request for pid 16811
01-09 14:11:02.280 17079 17079 I crash_dump64: performing dump of process 16332 (target tid = 16811)
01-09 14:11:02.286 17079 17079 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
01-09 14:11:02.286 17079 17079 F DEBUG : Build fingerprint: 'xiaomi/violet/violet:9/PKQ1.181203.001/9.1.9:user/release-keys'
01-09 14:11:02.286 17079 17079 F DEBUG : Revision: '0'
01-09 14:11:02.286 17079 17079 F DEBUG : ABI: 'arm64'
01-09 14:11:02.286 17079 17079 F DEBUG : pid: 16332, tid: 16811, name: HwBinder:16332_ >>> /vendor/bin/hw/android.hardware.camera.provider@2.4-service_64 <<<
01-09 14:11:02.286 17079 17079 F DEBUG : signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
01-09 14:11:02.286 17079 17079 F DEBUG : Abort message: 'Invalid address 0x7be6e0d180 passed to free: value not allocated'
01-09 14:11:02.286 17079 17079 F DEBUG : x0 0000000000000000 x1 00000000000041ab x2 0000000000000006 x3 0000000000000008
01-09 14:11:02.286 17079 17079 F DEBUG : x4 8080808080808080 x5 8080808080808080 x6 8080808080808080 x7 0000000000000008
01-09 14:11:02.286 17079 17079 F DEBUG : x8 0000000000000083 x9 49bf711238106b52 x10 0000000000000000 x11 fffffffc7fffffdf
01-09 14:11:02.286 17079 17079 F DEBUG : x12 0000000000000001 x13 000000005c35b39e x14 000c568e6e9f9200 x15 0000d19ff0bea88d
01-09 14:11:02.286 17079 17079 F DEBUG : x16 0000007c3320f2b8 x17 0000007c3312ec50 x18 ffffffffffffff60 x19 0000000000003fcc
01-09 14:11:02.286 17079 17079 F DEBUG : x20 00000000000041ab x21 0000007be6e0d180 x22 0000000000000000 x23 0000007c3321b8d8
01-09 14:11:02.286 17079 17079 F DEBUG : x24 0000007c254a5eb8 x25 0000007c3092cda0 x26 0000007c254a5eb8 x27 0000007c254a5eb8
01-09 14:11:02.286 17079 17079 F DEBUG : x28 0000007c254a5eb8 x29 0000007c0501f300
01-09 14:11:02.286 17079 17079 F DEBUG : sp 0000007c0501f2c0 lr 0000007c331220c4 pc 0000007c331220ec
01-09 14:11:02.323 711 711 I ConfigStore: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasHDRDisplay retrieved: 0
01-09 14:11:02.325 17079 17079 F DEBUG : 
01-09 14:11:02.325 17079 17079 F DEBUG : backtrace:
01-09 14:11:02.325 17079 17079 F DEBUG : #00 pc 00000000000220ec /system/lib64/libc.so (abort+116)
01-09 14:11:02.325 17079 17079 F DEBUG : #01 pc 00000000000b430c /system/lib64/libc.so (ifree+1172)
01-09 14:11:02.325 17079 17079 F DEBUG : #02 pc 00000000000b4418 /system/lib64/libc.so (je_free+120)
01-09 14:11:02.325 17079 17079 F DEBUG : #03 pc 00000000000cee9c /vendor/lib64/hw/com.qti.chi.override.so (ChxUtils::AndroidMetadata::FreeMetaData(void*)+28)
01-09 14:11:02.325 17079 17079 F DEBUG : #04 pc 0000000000099788 /vendor/lib64/hw/com.qti.chi.override.so (ChiMetadataManager::AndroidMetadataHolder::~AndroidMetadataHolder()+160)
01-09 14:11:02.325 17079 17079 F DEBUG : #05 pc 00000000000de150 /vendor/lib64/hw/com.qti.chi.override.so (std::_1::vector_base<ChiMetadataManager::AndroidMetadataHolder, std::1::allocator<ChiMetadataManager::AndroidMetadataHolder>>::~_vector_base()+72)
01-09 14:11:02.325 17079 17079 F DEBUG : #06 pc 00000000000de034 /vendor/lib64/hw/com.qti.chi.override.so (std::_1::vector<ChiMetadataManager::AndroidMetadataHolder, std::_1::allocator<ChiMetadataManager::AndroidMetadataHolder>>::~vector()+20)
01-09 14:11:02.325 17079 17079 F DEBUG : #07 pc 0000000000099a14 /vendor/lib64/hw/com.qti.chi.override.so (ChiMetadataManager::~ChiMetadataManager()+84)
01-09 14:11:02.325 17079 17079 F DEBUG : #08 pc 0000000000099d9c /vendor/lib64/hw/com.qti.chi.override.so (ChiMetadataManager::Destroy()+28)
01-09 14:11:02.325 17079 17079 F DEBUG : #09 pc 00000000000ad694 /vendor/lib64/hw/com.qti.chi.override.so (Usecase::DestroyObject(int)+1476)
01-09 14:11:02.325 17079 17079 F DEBUG : #10 pc 000000000005d45c /vendor/lib64/hw/com.qti.chi.override.so (ExtensionModule::TeardownOverrideUsecase(camera3_device const*, int)+220)
01-09 14:11:02.325 17079 17079 F DEBUG : #11 pc 00000000000616f4 /vendor/lib64/hw/com.qti.chi.override.so (ExtensionModule::TeardownOverrideSession(camera3_device const*, unsigned long, void*)+164)
01-09 14:11:02.325 17079 17079 F DEBUG : #12 pc 000000000005bde8 /vendor/lib64/hw/com.qti.chi.override.so (chi_teardown_override_session(camera3_device const*, unsigned long, void*)+56)
01-09 14:11:02.326 17079 17079 F DEBUG : #13 pc 00000000000ccd28 /vendor/lib64/hw/camera.qcom.so (CamX::close(hw_device_t*)+1768)
01-09 14:11:03.363 857 1000 E storaged: getDiskStats failed with result NOT_SUPPORTED and size 0
01-09 14:11:02.324 711 711 I chatty : uid=1000(system) /system/bin/surfaceflinger identical 2 lines

将该log贴到指定文件中跑脚本:

python ./as_tombstone_analysis/as_tomba.py ./as_tombstone_analysis/log_demo/ne_log_crash.txt /home/chengang/Documents/f7b_issue/symbols/9.1.9_in/out/target/product/violet/symbols

输出文件:
在这里插入图片描述
文件解析结果:

01-09 14:11:02.325 17079 17079 F DEBUG : #00 pc 00000000000220ec /system/lib64/libc.so (abort+116)abort
bionic/libc/bionic/abort.cpp:73

01-09 14:11:02.325 17079 17079 F DEBUG : #01 pc 00000000000b430c /system/lib64/libc.so (ifree+1172)je_arena_dalloc
external/jemalloc/include/jemalloc/internal/arena.h:1453

01-09 14:11:02.325 17079 17079 F DEBUG : #02 pc 00000000000b4418 /system/lib64/libc.so (je_free+120)je_free
external/jemalloc/src/jemalloc.c:?

01-09 14:11:02.325 17079 17079 F DEBUG : #03 pc 00000000000cee9c /vendor/lib64/hw/com.qti.chi.override.so (ChxUtils::AndroidMetadata::FreeMetaData(void*)+28)ChxUtils::AndroidMetadata::FreeMetaData(void*)
vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxutils.cpp:755

01-09 14:11:02.325 17079 17079 F DEBUG : #04 pc 0000000000099788 /vendor/lib64/hw/com.qti.chi.override.so (ChiMetadataManager::AndroidMetadataHolder::~AndroidMetadataHolder()+160)~AndroidMetadataHolder
vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxmetadata.cpp:814

01-09 14:11:02.325 17079 17079 F DEBUG : #05 pc 00000000000de150 /vendor/lib64/hw/com.qti.chi.override.so (std::_1::vector_base<ChiMetadataManager::AndroidMetadataHolder, std::1::allocator<ChiMetadataManager::AndroidMetadataHolder>>::~_vector_base()+72)std::__1::allocator<ChiMetadataManager::AndroidMetadataHolder>::destroy(ChiMetadataManager::AndroidMetadataHolder*)
external/libcxx/include/memory:1860

01-09 14:11:02.325 17079 17079 F DEBUG : #06 pc 00000000000de034 /vendor/lib64/hw/com.qti.chi.override.so (std::_1::vector<ChiMetadataManager::AndroidMetadataHolder, std::_1::allocator<ChiMetadataManager::AndroidMetadataHolder>>::~vector()+20)~vector
external/libcxx/include/vector:447

01-09 14:11:02.325 17079 17079 F DEBUG : #07 pc 0000000000099a14 /vendor/lib64/hw/com.qti.chi.override.so (ChiMetadataManager::~ChiMetadataManager()+84)~ChiMetadataManager
vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxmetadata.cpp:965

01-09 14:11:02.325 17079 17079 F DEBUG : #08 pc 0000000000099d9c /vendor/lib64/hw/com.qti.chi.override.so (ChiMetadataManager::Destroy()+28)ChiMetadataManager::Destroy()
vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxmetadata.cpp:847

01-09 14:11:02.325 17079 17079 F DEBUG : #09 pc 00000000000ad694 /vendor/lib64/hw/com.qti.chi.override.so (Usecase::DestroyObject(int)+1476)Usecase::DestroyObject(int)
vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxusecase.cpp:172

01-09 14:11:02.325 17079 17079 F DEBUG : #10 pc 000000000005d45c /vendor/lib64/hw/com.qti.chi.override.so (ExtensionModule::TeardownOverrideUsecase(camera3_device const*, int)+220)ExtensionModule::TeardownOverrideUsecase(camera3_device const*, int)
vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxextensionmodule.cpp:2129

01-09 14:11:02.325 17079 17079 F DEBUG : #11 pc 00000000000616f4 /vendor/lib64/hw/com.qti.chi.override.so (ExtensionModule::TeardownOverrideSession(camera3_device const*, unsigned long, void*)+164)ExtensionModule::TeardownOverrideSession(camera3_device const*, unsigned long, void*)
vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxextensionmodule.cpp:2074

01-09 14:11:02.325 17079 17079 F DEBUG : #12 pc 000000000005bde8 /vendor/lib64/hw/com.qti.chi.override.so (chi_teardown_override_session(camera3_device const*, unsigned long, void*)+56)chi_teardown_override_session(camera3_device const*, unsigned long, void*)
vendor/qcom/proprietary/chi-cdk/vendor/chioverride/default/chxextensioninterface.cpp:504

01-09 14:11:02.326 17079 17079 F DEBUG : #13 pc 00000000000ccd28 /vendor/lib64/hw/camera.qcom.so (CamX::close(hw_device_t*)+1768)CamX::close(hw_device_t*)
vendor/qcom/proprietary/camx/src/core/hal/camxhaldevice.cpp:956

自动解析tombstone脚本源码:

# -*- coding: utf-8 -*-
# !/usr/bin/python
import re
import os
import os.path
import time
import gzip
import sys

'''
How to use it?
as_tomba.py tombstone_file_path symbol_file_path
out file :
./tombstone_out.txt
'''
tombstone_file_path = sys.argv[1]
symbols_dir_path = sys.argv[2]

def get_filePath_fileName_fileExt(filename):
    (filepath,tempfilename) = os.path.split(filename);
    (shotname,extension) = os.path.splitext(tempfilename);
    return filepath,shotname,extension

def get_process_pid_name(filename):
    f = open(filename)
    for line in f:
        pattern = re.compile(r"pid:\s([0-9]+?),.+>>> (.+?) <<<")
        rst = pattern.search(line)
        if rst :
            pid = rst.group(1)
            name = rst.group(2).lstrip('/').replace('/','#')
            return pid,name
    return "null","null"

def tomba_dir(ptombstone_file_dir,psymbols_dir_path):
    for file_name in os.listdir(tombstone_file_path):
        target_file = os.path.join(tombstone_file_path,file_name)
        tomba_file(target_file,symbols_dir_path)

def tomba_file(ptombstone_file_path,psymbols_dir_path):
    psymbols_dir_path = psymbols_dir_path.rstrip('/')
    (pid,pname) = get_process_pid_name(ptombstone_file_path)
    f = open(ptombstone_file_path);
    (file_p,file_s,file_e) = get_filePath_fileName_fileExt(ptombstone_file_path)
    out_file_name = file_s+"_"+pid+"_"+pname+".out"
    fp = open(file_p+'/'+out_file_name,'a+')
    fp.truncate()
    for line in f:
        line = line.lstrip()
        line = line.strip('\n')
        if  line.startswith("stack:"):
            break
        else:
            # pattern = re.compile('(#[0-9]{2})(?#调用栈帧数)\s+pc\s+([0-9a-z]{16})(?#pc地址)\s(.+?)\s')
            # 64位和32位机器的pc地址长度不同,64位为16位PC地址,32位为8位PC地址
            pattern = re.compile('(#[0-9]{2})(?#调用栈帧数)\s+pc\s+([0-9a-z]*)(?#pc地址)\s(.+?)\s')
            rst = pattern.search(line)
            if rst:
                symbol_path = psymbols_dir_path + rst.group(3).strip()
                shift_code = rst.group(2)
                print line
                print symbol_path
                print shift_code
                print '\n'
                analysis_result = tomba_so(symbol_path,shift_code)
                fp.write(line)
                fp.write(analysis_result)
                fp.write('\n')
                f.flush()

def tomba_so(symbol_so_path,shift_code):
    if(os.path.exists(symbol_so_path)):
        cmd_line = "addr2line -Cfe %s %s" %(symbol_so_path,shift_code)
        f = os.popen(cmd_line)
        result = f.read()
        return result
    else:
        return "no symbol file!!!"

if os.path.isdir(tombstone_file_path):
	print(tombstone_file_path + " is a dir")
    tomba_dir(tombstone_file_path,symbols_dir_path)
elif os.path.isfile(tombstone_file_path):
    print(tombstone_file_path + " is a file")
    tomba_file(tombstone_file_path,symbols_dir_path)
else:
    print("Wrong Tombstone File Name!")
    sys.exit()
<think>我们正在分析安卓手机崩溃时的dump模式。根据引用内容以及相关知识,安卓系统崩溃时可能产生多种类型的dump文件,用于后续的问题分析。以下将列出常见的dump模式及其特点: 1. **Minidump**: - 由Google Breakpad生成,是一种跨平台的崩溃报告格式[^1]。 - 特点:体积小,只包含崩溃时的关键信息(如线程栈、寄存器状态、模块列表等)。 - 生成场景:通常用于应用程序(包括Native层)的崩溃捕获。 - 解析工具:`minidump_stackwalk`(需要对应的符号文件)。 2. **Tombstone**: - 安卓系统特有的Native崩溃报告文件。 - 存储位置:`/data/tombstones/`(需要root权限访问)。 - 内容:包含详细的崩溃信息,如信号类型、寄存器状态、堆栈回溯、内存映射等。 - 生成场景:当Native进程(包括系统服务)发生严重错误(如SIGSEGV)时产生。 3. **ANR Traces**: - 记录应用无响应(ANR)时的堆栈信息。 - 存储位置:`/data/anr/traces.txt`(需要root权限)。 - 内容:包含所有线程的堆栈状态,用于分析主线程阻塞原因。 4. **内核转储(Kernel Dump)**: - 包括完整内存镜像(vmcore)或部分内存区域。 - 生成方式: - 通过`kdump`机制(需要预先保留内存区域)。 - 通过`pstore`(Persistent Storage)在重启后保留崩溃日志(位于`/sys/fs/pstore/`)。 - 解析工具:`crash`工具(需要vmlinux和vmcore文件)[^3]。 5. **RAM Dump**: - 高通平台设备崩溃时可能生成RAM Dump(如MSM平台)。 - 特点:包含完整物理内存内容,文件较大(通常为内存大小)。 - 解析工具:高通提供的`linux-ramdump-parser-v2`(需指定芯片型号,如msmnile)[^3]。 6. **Heap Dump**: - Java堆内存快照,用于分析内存泄漏。 - 生成方式: - 通过`-XX:+HeapDumpOnOutOfMemoryError`在OOM时自动生成[^2]。 - 使用Android Profiler手动触发。 - 格式:通常为HPROF格式。 - 分析工具:Android Studio Memory Profiler或MAT(Memory Analyzer Tool)。 7. **SysRq Trigger Dump**: - 通过内核SysRq机制手动触发。 - 命令:`echo c > /proc/sysrq-trigger`(强制触发内核崩溃并生成dump)。 - 输出:通常通过`pstore`或网络存储dump。 8. **Ftrace Dump**: - 内核函数跟踪日志,用于分析死锁或性能问题。 - 生成方式:崩溃时自动捕获或通过`--dump-ftrace`选项在解析RAM Dump时提取[^3]。 ### 总结表 | Dump类型 | 生成场景 | 关键特征 | 分析工具 | |----------------|----------------------------|----------------------------|----------------------------| | Minidump | 应用崩溃(Breakpad集成) | 跨平台、体积小 | `minidump_stackwalk` | | Tombstone | Native崩溃 | 详细寄存器/堆栈信息 | `ndk-stack`, `addr2line` | | ANR Traces | 应用无响应 | 线程堆栈快照 | 直接阅读或脚本分析 | | 内核转储 | 内核崩溃 | 完整/部分内存镜像 | `crash`工具 | | RAM Dump | 高通平台崩溃 | 完整物理内存镜像 | 高通专用解析器 | | Heap Dump | Java层OOM | HPROF格式 | MAT, Android Studio | | SysRq Dump | 手动触发内核崩溃 | 按需生成 | 依赖后端存储机制 | | Ftrace Dump | 内核跟踪 | 函数调用序列 | `cat`或内核工具解析 | §§相关问题§§ 1. 如何解析Tombstone文件中的堆栈信息? 2. 如何为高通RAM Dump准备解析环境? 3. Heap Dump分析内存泄漏的具体步骤是什么? 4. 在没有root权限的情况下如何获取ANR日志? 5. Minidump和Tombstone的主要区别是什么?</think>### 安卓手机崩溃时的dump模式分析 根据引用内容和技术实践,安卓系统崩溃时会生成多种类型的dump文件,每种对应不同的崩溃场景。以下是主要的dump模式及其特征: --- #### 一、核心dump模式分类 1. **Minidump** - **生成场景**:应用级崩溃(如Native层崩溃) - **特征**: - 二进制格式,体积小(通常KB级)[^1] - 包含崩溃线程的寄存器状态、堆栈片段、加载模块列表 - **文件示例**:`app_process_1234.dmp` - **分析工具**:`minidump_stackwalk`(需符号文件) 2. **Tombstone文件** - **生成场景**:Native层严重错误(SIGSEGV/SIGABRT) - **特征**: - 文本格式,位于`/data/tombstones/` - 包含: ```text Build fingerprint: ... # 设备指纹 Signal 11 (SIGSEGV), code 1 # 信号类型 backtrace: # 崩溃堆栈 #00 pc 00012345 libnativelib.so memory map: # 内存映射详情 00500000-00600000 r-xp /system/lib/libnativelib.so ``` - **分析工具**:`ndk-stack`或`addr2line` 3. **RAM Dump** - **生成场景**:内核级崩溃(如高通平台死机) - **特征**: - 完整物理内存镜像(GB级) - 需专用硬件解析器(如高通`linux-ramdump-parser-v2`)[^3] - 包含内核状态、所有进程内存页 - **触发条件**:内核Oops或Watchdog超时 4. **Heap Dump** - **生成场景**:Java层OOM(OutOfMemoryError) - **特征**: - HPROF格式(Java堆快照) - 通过JVM参数触发: ```java -XX:+HeapDumpOnOutOfMemoryError // 自动生成[^2] ``` - **分析工具**:Android Studio Memory Profiler 5. **ANR Traces** - **生成场景**:应用无响应(主线程阻塞) - **特征**: - 文本格式,位于`/data/anr/traces.txt` - 包含所有线程的堆栈状态 - 典型标记:`"main" prio=5 blocked` --- #### 二、其他诊断数据 1. **Pstore日志** - 内核崩溃后保留在`/sys/fs/pstore/` - 包含内核最后日志(dmesg片段) 2. **Kernel SysRq Dump** - 手动触发:`echo c > /proc/sysrq-trigger` - 强制生成完整内核状态快照 --- #### 三、dump模式对比表 | 类型 | 触发场景 | 数据量 | 关键内容 | 分析工具 | |---------------|------------------|----------|--------------------------|-----------------------| | **Minidump** | Native崩溃 | KB级 | 线程寄存器/堆栈片段 | minidump_stackwalk | | **Tombstone** | Native严重错误 | MB级 | 完整内存映射/信号原因 | ndk-stack | | **RAM Dump** | 内核死机 | GB级 | 完整物理内存 | 高通平台专用解析器[^3] | | **Heap Dump** | Java OOM | 百MB级 | Java对象引用关系 | MAT工具 | | **ANR Traces**| 应用无响应 | MB级 | 线程阻塞状态 | 直接阅读 | --- #### 四、分析建议 1. **组合分析**: - 例如Native崩溃需同时检查`minidump`和`dmesg`日志 2. **符号文件要求**: - Minidump/Tombstone需对应版本的`.so`符号文件 - 内核转储需`vmlinux`文件[^3] 3. **自动化处理**: ```python # 示例:检测tombstone中的关键信号 import re with open("tombstone_00", "r") as f: if re.search(r"Signal (\d+) \(SIG\w+\)", f.read()): print("检测到致命信号崩溃") ``` > **关键点**:高通平台RAM Dump需指定芯片型号(如`--force-hardware msmnile`),并加载驱动符号(如`wlan.ko`)[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值