带-s编译的剥离与未剥离二进制反汇编地址不一致问题求解
解决Stripped与Unstripped二进制地址不匹配的问题
1. 修正编译流程:先编译带符号二进制,再手动剥离
不要在编译阶段通过-s参数直接生成stripped二进制,正确流程是:
- 编译Release版本时不添加
-s,生成完整的带符号、调试信息的二进制(记为app_unstripped) - 使用NDK自带的
strip工具(路径通常为$NDK/toolchains/llvm/prebuilt/<host-triple>/bin/llvm-strip)对app_unstripped进行剥离,得到发布用的stripped二进制(app_stripped)
这种方式下,stripped与unstripped版本的代码段、数据段布局完全一致,仅stripped移除了符号表、调试信息等冗余内容,崩溃回溯的地址可直接对应到unstripped版本的反汇编或调试信息。
2. 分离调试符号文件(兼顾体积与调试能力)
若担心unstripped二进制体积过大,可将调试符号单独分离:
- 编译时添加
-g生成调试信息,同时用-Wl,--split-dwarf让链接器将调试信息拆分到独立的.dwp文件 - 或用
objcopy工具从unstripped二进制提取符号与调试信息:$NDK/toolchains/llvm/prebuilt/<host-triple>/bin/llvm-objcopy --only-keep-debug app_unstripped app.debug $NDK/toolchains/llvm/prebuilt/<host-triple>/bin/llvm-strip --strip-debug app_unstripped -o app_stripped
后续解析崩溃地址时,结合分离的调试文件使用addr2line:
$NDK/toolchains/llvm/prebuilt/<host-triple>/bin/llvm-addr2line -e app.debug <崩溃地址>
3. 验证地址一致性
处理完成后,可通过objdump对比两者的反汇编结果,确认布局一致:
# 反汇编unstripped版本的.text段 $NDK/toolchains/llvm/prebuilt/<host-triple>/bin/llvm-objdump -d --section=.text app_unstripped > unstripped_disasm.txt # 反汇编stripped版本的.text段 $NDK/toolchains/llvm/prebuilt/<host-triple>/bin/llvm-objdump -d --section=.text app_stripped > stripped_disasm.txt
对比两个文件的指令地址与机器码,确保布局完全匹配。
4. CMake配置示例
修改CMake的Release配置,自动完成“生成带符号二进制+剥离”流程:
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O2 -g") # -g生成调试信息,O2开启优化 set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2 -g") # 编译后自动剥离生成发布用二进制 add_custom_command(TARGET your_target POST_BUILD COMMAND ${CMAKE_STRIP} $<TARGET_FILE:your_target> -o $<TARGET_FILE_DIR:your_target>/your_target_stripped COMMENT "Stripping binary for release" )
编译完成后,目标目录会同时生成带符号的your_target和stripped的your_target_stripped,两者地址布局完全一致。
内容的提问来源于stack exchange,提问作者xxxLD
相关产品推荐
相关产品推荐

