如何使用DWARF将目标文件中的指令映射到源代码行
针对未链接目标文件/静态库的指令-源码行映射解决方案
你遇到的addr2line无法正常工作的核心原因是GNU原生addr2line默认适配已链接的可执行文件/动态库的虚拟地址查询,未链接目标的地址都是段内相对地址,使用以下现成工具即可直接满足需求,不需要自行解析DWARF信息:
1 直接使用objdump实现需求
这是最方便的方案,不需要额外安装工具,你已经用过objdump,只要加对应参数即可:
- 仅查看反汇编指令+对应源码行:执行
objdump -d -l <目标文件/静态库路径>,输出会自动在每段对应指令前标注关联的源代码文件路径和行号 - 需要同时查看完整源代码与对应汇编指令:执行
objdump -S <目标文件/静态库路径>,工具会自动把对应源码块插在关联的汇编指令上方,对应关系更直观
注意:上述命令仅要求目标编译时添加了-g参数生成DWARF调试信息,不需要目标文件完成链接,直接支持未链接的.o文件、.a静态库,会自动匹配段内偏移与DWARF行号表的对应关系,不需要处理函数从0x00起始的问题
2 其他可直接使用的工具
如果需要更灵活的批量查询、或者指令级的精准匹配,也可以用以下成熟工具:
- eu-addr2line:属于elfutils工具集,相比GNU原生addr2line对未链接目标的支持更好,直接传入指令在对应段的偏移即可返回行号,不需要拼接函数基址
- llvm-symbolizer:LLVM工具链自带的调试信息查询工具,支持直接指定段名+偏移查询,例如查询test.o的.text段0x20偏移对应的行号,执行
llvm-symbolizer --obj=test.o text+0x20即可,对未链接目标的兼容性更高 - dwarfdump:专门的DWARF信息导出工具,执行
dwarfdump -l <目标路径>可以直接导出完整的DWARF行号表,包含所有段内偏移对应的源码行号,适合批量处理场景
内容的提问来源于stack exchange,提问作者CXWorks
相关产品推荐
相关产品推荐

