Android NDK 开发中的崩溃排查

Android NDK 开发中的崩溃排查

  • 解析崩溃的内存地址(比如 #00 pc 7a3b6c /data/app/.../lib/arm64/libapp.so)

ndk-stack 批量解析

  • ndk-stack 是 NDK 开发用来解析崩溃日志,需要结合未剥离的 .so 文件(确保编译时保留调试符号,避免 strip 剥离符号)中的调试符号,还原堆栈信息(比如 Windows 上的 \AndroidSdk\ndk\27.0.12077973\ndk-stack.cmd 文件)

  • 能够自动匹配 .so 调试符号,批量解析日志中的所有堆栈帧,直接输出文件名、行号和函数名(自动将崩溃 pc 地址映射到源代码的行号和方法名)

  • 1 保存日志到文件后进行解析

  • 最终文件内容必须包含 *** *** *** *** *** 开头那一行才能解析

shell 复制代码
# 将带崩溃日志的 logcat 内容捕获输出(Ctrl+C 停止)
adb logcat > D:/temp/arm64-v8a/crash.log
# 也可以按需捕获筛选出 NDK-StackTrace:E (只保留标签为 NDK-StackTrace 的 Error 级日志,对应代码中 LOGE 输出)的日志
adb logcat -s NDK-StackTrace:E > crash_log.txt

# 可以先确认设备 ABI,以保证选择正确的 .so 文件
adb shell cat /proc/cpuinfo
adb shell getprop ro.product.cpu.abi
adb shell getprop ro.product.cpu.abilist
shell 复制代码
# ndk-stack 存放在 \AndroidSdk\ndk\27.0.12077973 目录下
# -sym 参数(--symbols)指定包含符号表(调试信息)的 .so 文件(或 .debug 文件)的父目录(工具会自动递归查找目录下所有文件,比如 Debug 模式的 .so 或 Release 模式的 .so.debug)
# -dump 指定崩溃日志文件路径
ndk-stack -sym D:/temp/arm64-v8a -dump D:/temp/arm64-v8a/crash.log
shell 复制代码
# 也可以直接将结果输出到指定文件
ndk-stack -sym D:/temp/arm64-v8a -dump D:/temp/arm64-v8a/crash.log > D:/temp/arm64-v8a/crash_dump.log
  • 2 通过 adb logcat 实时输出日志
shell 复制代码
adb logcat | ndk-stack -sym $PROJECT_PATH/app/build/intermediates/cmake/debug/obj/arm64-v8a
adb logcat | ndk-stack -sym $PROJECT_PATH/app/build/intermediates/cxx/debug/obj/arm64-v8a
adb logcat | ndk-stack -sym $PROJECT_PATH/app/build/intermediates/cxx/debug/<hash>/obj/arm64-v8a

addr2line 单个地址解析

  • addr2line 是 NDK 工具链中的底层工具,用于解析单个堆栈地址对应的文件名、行号和函数名,适合快速验证单个地址
  • 新版本的 NDK 统一名为 llvm-addr2line,不再区分架构前缀,所有架构使用同一个命令(比如 Windows 上的 \AndroidSdk\ndk\27.0.12077973\toolchains\llvm\prebuilt\windows-x86_64\bin>llvm-addr2line.exe 文件,旧版本的 NDK 必须使用与 .so 架构一致的工具进行操作)
shell 复制代码
# 00000000011cc48c 是单个堆栈地址
# -e 参数(--exe)指定符号表 .so 文件
llvm-addr2line -e D:/temp/arm64-v8a/libpwrtcsdkandroid.so 00000000011cc48c
# 打印出对应的文件名、行号
/home/ubuntu/rtc-build/paho.mqtt.cpp/include/mqtt/message.h:251
shell 复制代码
# -f 参数(--functions)显示函数名
llvm-addr2line -e D:/temp/arm64-v8a/libpwrtcsdkandroid.so -f 00000000011cc48c
_ZNK4mqtt7message9get_topicEv
/home/ubuntu/rtc-build/paho.mqtt.cpp/include/mqtt/message.h:251
shell 复制代码
# -C 参数(--demangle)解码 C++ 符号(Demangle),就是还原 C++ 符号
llvm-addr2line -e D:/temp/arm64-v8a/libpwrtcsdkandroid.so -f -C 00000000011cc48c
mqtt::message::get_topic() const
/home/ubuntu/rtc-build/paho.mqtt.cpp/include/mqtt/message.h:251
相关推荐
该用户可能存在19 小时前
Blbl-android 更新至 v0.1.24,体验更流畅、更稳定
android·哔哩哔哩·电视app·androidtv·bbll·blbl·bilibilitv
lKWO OMET19 小时前
mysql之字符串函数
android·数据库·mysql
liang_jy1 天前
Android SparseArray
android·源码
liang_jy1 天前
Activity 启动流程扩展篇(一)—— startActivityInner 任务决策全解析
android·源码
NPE~1 天前
[App逆向]脱壳实战
android·教程·逆向·android逆向·逆向分析
木易 士心1 天前
别再只会用 drawCircle 了!一文搞懂 Android Canvas 底层机制
android
AtOR CUES1 天前
MySQL——表操作及查询
android·mysql·adb
怣疯knight1 天前
安卓App无法增加自定义图片作为图标功能
android
jinanwuhuaguo1 天前
OpenClaw联邦之心——从孤岛记忆到硅基集体潜意识的拓扑学革命(第二十三篇)
android·人工智能·kotlin·拓扑学·openclaw
Gary Studio2 天前
安卓HAL C++基础-命名域
android