1、确认 ABI 匹配
崩溃发生在什么架构的手机上(arm64-v8a, x86_64 等),去对应的 obj/[ABI]/ 目录下找那个大的 .so 文件。
2、如何提取符号表
1.1 使用objcopy提取符号表
比如:Android/Sdk/ndk/25.2.9519653/toolchains/llvm/prebuilt/linux-x86_64/bin
$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-objcopy \
--only-keep-debug app.so \
app.so.debug
# 或者用strip保留调试信息
$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip \
--only-keep-debug app.so \
-o app.so.debug
1.2 得到2个文件
app.so # 发布版(剥离符号表,体积小)
app.so.debug # 调试版(包含完整符号表,用于解析)
3、用 ndk-stack 定位
比如:./ndk/25.2.9519653/ndk-stack
将崩溃日志保存为 crash_log.txt
$NDK_HOME/ndk-stack -sym /项目路径/app/build/intermediates/cxx/Debug/[随机ID]/obj/x86_64 -dump crash_log.txt
结果: 它会将 pc 000000000001a4c4地址xxx 这种地址直接翻译成 函数名.cpp:行号。
4、使用 addr2line 解析堆栈 (高版本可能去了)
比如:./ndk/22.0.7026061/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-addr2line
$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/arm-linux-androideabi-addr2line
-e app.so # 指定so文件
-f -C -p # 显示函数名、demangle、完整信息
0x12345678 # 崩溃地址
结果:
CrashFunction() at /src/main.cpp:108
CallerFunction() at /src/utils.cpp:42