dwarf4和dwarf5差异,以及应用
不使用DEBUG_INFO,和使用dwarf4、dwarf5对问题调试定位影响很大。
在嵌入式环境下,尽量使用dwarf5,对最终Image大小影响很小,调试定位收益较大。
1 DWARF4 与 DWARF5 核心差异对比
DWARF 是一种调试信息格式,专门用于描述可执行程序(如编译后的 C、C++、Rust 等程序)的结构和状态,以便调试器(如 GDB、LLDB)或其他工具(如性能分析器)能够理解程序的源代码与机器码之间的映射关系。
DWARF 的主要作用:
- 映射机器码到源代码:
- 告诉调试器某段机器指令对应源代码的哪一行、哪个函数。
- 允许你在源代码级别设置断点、单步执行。
- 描述数据类型:
- 提供程序中定义的结构体(struct)、联合体(union)、类(class)、枚举(enum)、基本类型(int, float 等)的大小、布局、成员名称和偏移量等信息。
- 调试器据此可以显示变量的值及其内部成员。
- 定位变量和参数:
- 描述局部变量、全局变量、函数参数在内存中的位置(例如在栈帧中的偏移、在特定寄存器中、或在全局数据区)。
- 调试器据此可以读取和修改变量的值。
- 描述调用栈:
- 提供栈帧布局信息(如返回地址、前一个栈帧指针的位置),使调试器能够展开调用栈(backtrace)。
- 支持高级调试功能:
- 内联函数展开、模板实例化调试、跨语言调试(如 C++ 调用 Rust)等。
特性 | DWARF4 | DWARF5 | 调试意义 |
---|---|---|---|
行号表 | .debug_line 段 |
拆分到 .debug_line + .debug_line_str |
减少冗余字符串,加速行号查询 |
变量位置描述 | DW_AT_location 使用复杂表达式 |
引入 .debug_loclists 专用段 |
更紧凑存储位置信息,降低解析开销 |
类型签名 | 依赖 DW_AT_signature (非标准) |
标准化的 DW_FORM_ref_sig8 |
提升模板/复杂类型调试准确性 |
宏定义支持 | 有限支持(.debug_macinfo ) |
改进的 .debug_macro 段 |
支持预处理器宏的完整展开 |
分裂 DWARF | 无原生支持 | 原生支持 .dwo 文件(Debuginfo Only) |
分离调试信息,减少主二进制大小 |
压缩效率 | 依赖外部工具压缩 | 内置更高效的数据结构 | 相同信息量下体积减少 5-15% |
2 不同DWARF配置对内核镜像大小的影响
配置状态 | vmlinux/Image大小 |
关闭 DWARF |
25610208 Image |
CONFIG_DEBUG_INFO_DWARF4=y |
25610208 Image |
CONFIG_DEBUG_INFO_DWARF5=y |
25610208 Image |
3 导出调试信息
通过如下命令,导出详细的调试信息辅助调试:
objdump -d -S -l --source-comment=" C: " --all-headers --wide <二进制文件>
- -d: 反汇编代码段(.text 等)
- -S: 混合源代码与汇编(需编译时加 -g)
- -l: 显示源代码行号信息
- --source-comment=" C: ": 在汇编上方标注对应 C 代码
- --all-headers: 显示所有头部信息(ELF 头、段头、节头)
- --wide: 避免截断长符号名
联系方式:arnoldlu@qq.com