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

如何从仅显示APK的Backtrace中获取JNI代码的函数行信息

问题:APK内嵌JNI代码的Backtrace如何解析函数行信息?

我获取到的Backtrace如下:

D callstack-test: #00 pc 000001c5  /system_ext/app/MyService/MyService.apk (offset 0x59c9000)

经测试,该代码属于编译为libjni.so的JNI代码,我预期的Backtrace格式应为:

D callstack-test: #00 pc 0004f049  /system_ext/app/MyService/MyService.apk!libjni.so (offset 0x59e8000)

但实际结果仅显示APK名称,未包含库名,导致无法使用addr2line获取函数行信息。

根据谷歌文档说明:

Frames #00–#03 are from native JNI code that was stored uncompressed in the APK to save disk space rather than being extracted into a separate .so file.

现咨询:当Backtrace仅显示APK名称时,如何获取JNI代码对应的函数行信息?


解决方法

  • 提取APK内的JNI库文件
    由于JNI库未压缩内嵌在APK中,可通过解压工具直接提取目标库。比如用unzip命令:

    unzip MyService.apk lib/arm64-v8a/libjni.so -d extracted_libs
    

    注意替换命令中的架构路径(如arm64-v8a、armeabi-v7a等)为你的实际目标架构。

  • 计算正确的解析地址
    Backtrace中的pc值是相对于APK加载基址的偏移,需要转换为相对于libjni.so基址的地址:
    正确地址 = pc值 + APK的offset - libjni.so在APK中的加载基址偏移
    其中libjni.so的加载基址偏移可通过readelf工具查看:

    readelf -l extracted_libs/lib/arm64-v8a/libjni.so | grep LOAD
    

    取第一个LOAD段的VirtAddr(虚拟地址)作为库的基址,再结合APK的offset计算出最终地址。

  • 使用addr2line解析行号
    用对应架构的addr2line工具(如aarch64-linux-android-addr2line)执行解析:

    aarch64-linux-android-addr2line -f -C -e extracted_libs/lib/arm64-v8a/libjni.so [计算后的十六进制地址]
    

    参数说明:-f显示函数名,-C还原C++符号名,-e指定目标库文件。

  • 可选:借助Android Studio工具简化流程
    将APK和对应的符号文件(.symbols)导入Android Studio的Profiler或Debug面板,IDE会自动识别内嵌库并解析Backtrace,无需手动计算地址。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 20:15:12