You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用GDB映射Android崩溃栈地址至代码行遇异常问题咨询

崩溃地址与符号不匹配问题分析

问题背景

崩溃栈信息

#01 pc 00025b85  /system_ext/lib/libsn100nfc_nci_jni.so (android::nfaDeviceManagementCallback(unsigned char, tNFA_DM_CBACK_DATA*)+792) (BuildId: 49a45aec53f191b56d0e9b3249ebe94d)

本地SO文件信息

$ file libsn100nfc_nci_jni.so 
libsn100nfc_nci_jni.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, BuildID[md5/uuid]=56ba6d380faffef52b19484b178b44b0, with debug_info, not stripped

GDB查询异常结果

$ gdb libsn100nfc_nci_jni.so 

Reading symbols from libsn100nfc_nci_jni.so...
(gdb) info symbol 0x00025b85
xmlSoL + 53 in section .rodata
(gdb) info line *0x00025b85

函数地址查询结果

(gdb) info address android::nfaDeviceManagementCallback
Symbol "android::nfaDeviceManagementCallback(unsigned char, tNFA_DM_CBACK_DATA*)" is a function at address 0x2d294.

疑问

  • 为何崩溃地址处于.rodata段?
  • 函数地址为0x2d294,但崩溃栈显示的地址0x00025b85却小于函数地址,这是怎么回事?

问题分析与解答

核心原因:SO版本不匹配

崩溃栈中的SO和你本地用于调试的SOBuildID完全不同,这意味着两者是不同版本的库文件,编译后的内存布局、符号偏移存在本质差异,导致地址解析完全错误。

1. 崩溃地址落在.rodata段的解释

不同版本的SO,代码段(.text)、只读数据段(.rodata)的地址范围和内容布局完全不同。你用本地SO去解析另一版本SO的崩溃地址,自然会映射到错误的段上,出现“崩溃地址在.rodata”的异常结果。

2. 崩溃地址小于函数地址的解释

崩溃栈中的+792表示崩溃点是android::nfaDeviceManagementCallback函数起始地址偏移792字节的位置,对应版本SO中该函数的起始地址应为0x25b85 - 792 = 0x25849,而你本地SO中该函数的起始地址是0x2d294,这是两个版本SO编译后函数布局差异导致的,并非崩溃地址真的小于函数起始地址。

解决方法

  • 必须获取与崩溃栈中BuildID(49a45aec53f191b56d0e9b3249ebe94d)完全匹配的SO文件,再用GDB解析地址才能得到正确的符号信息。
  • 如果无法直接获取对应版本SO,可以尝试从对应固件包中提取,或者联系厂商获取匹配的符号文件。

内容的提问来源于stack exchange,提问作者lucky1928

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 11:30:55