dwarf-debug-format
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseDWARF Debug Format
DWARF调试格式
Purpose
用途
Guide agents through understanding and working with DWARF debug information: the key DWARF sections, using and for inspection, split DWARF ( files), for remote symbol servers, and how LTO and stripping affect debug info.
dwarfdumpreadelf.dwodebuginfod指导开发者理解和使用DWARF调试信息:包括关键的DWARF段、使用和进行检查、拆分式DWARF(文件)、用于远程符号服务器的,以及LTO和符号剥离对调试信息的影响。
dwarfdumpreadelf.dwodebuginfodTriggers
触发场景
- "What are the DWARF sections in an ELF binary?"
- "How do I inspect DWARF debug info in a binary?"
- "How does split DWARF work?"
- "How do I set up debuginfod for automatic debug symbols?"
- "Why does GDB say 'no debugging symbols found'?"
- "How does LTO affect DWARF debug information?"
- "ELF二进制文件中的DWARF段有哪些?"
- "如何检查二进制文件中的DWARF调试信息?"
- "拆分式DWARF的工作原理是什么?"
- "如何搭建debuginfod以自动获取调试符号?"
- "为什么GDB提示‘未找到调试符号’?"
- "LTO对DWARF调试信息有什么影响?"
Workflow
操作流程
1. DWARF sections overview
1. DWARF段概述
bash
undefinedbash
undefinedShow all sections in a binary (including DWARF)
显示二进制文件中的所有段(包括DWARF段)
readelf -S prog | grep ".debug"
readelf -S prog | grep ".debug"
Common DWARF sections:
常见的DWARF段:
.debug_info — types, variables, functions (DIEs — Debug Info Entries)
.debug_info — 类型、变量、函数(DIE——调试信息条目)
.debug_abbrev — abbreviation table for .debug_info encoding
.debug_abbrev — .debug_info编码的缩写表
.debug_line — line number table (source line → address mapping)
.debug_line — 行号表(源码行 → 地址映射)
.debug_str — string table for identifiers
.debug_str — 标识符字符串表
.debug_loc — location expressions (where variables live)
.debug_loc — 位置表达式(变量的存储位置)
.debug_ranges — non-contiguous address ranges for CUs
.debug_ranges — 编译单元的非连续地址范围
.debug_aranges — fast lookup: address → compilation unit
.debug_aranges — 快速查找:地址 → 编译单元
.debug_pubnames — global variable and function names
.debug_pubnames — 全局变量和函数名称
.debug_frame — call frame information (for unwinding)
.debug_frame — 调用帧信息(用于栈展开)
.debug_types — type unit entries (DWARF 4+)
.debug_types — 类型单元条目(DWARF 4+)
.debug_rnglists — range lists (DWARF 5)
.debug_rnglists — 范围列表(DWARF 5)
.debug_loclists — location lists (DWARF 5)
.debug_loclists — 位置列表(DWARF 5)
.debug_addr — address table (DWARF 5)
.debug_addr — 地址表(DWARF 5)
.debug_line_str — line number string table (DWARF 5)
.debug_line_str — 行号字符串表(DWARF 5)
undefinedundefined2. Inspecting DWARF with dwarfdump
2. 使用dwarfdump检查DWARF信息
bash
undefinedbash
undefinedInstall dwarfdump
安装dwarfdump
apt-get install dwarfdump # Ubuntu (part of libdwarf)
brew install libdwarf # macOS
apt-get install dwarfdump # Ubuntu(属于libdwarf包)
brew install libdwarf # macOS
Dump all DWARF info
导出所有DWARF信息
dwarfdump prog
dwarfdump prog
Dump specific sections
导出指定段
dwarfdump --debug-info prog # types, variables, functions
dwarfdump --debug-line prog # line number table
dwarfdump --debug-loc prog # variable locations
dwarfdump --debug-frame prog # call frame info
dwarfdump --debug-info prog # 类型、变量、函数
dwarfdump --debug-line prog # 行号表
dwarfdump --debug-loc prog # 变量位置
dwarfdump --debug-frame prog # 调用帧信息
readelf alternatives (less verbose)
readelf替代方案(输出更简洁)
readelf --debug-dump=info prog | head -100
readelf --debug-dump=lines prog | head -50
readelf --debug-dump=info prog | head -100
readelf --debug-dump=lines prog | head -50
llvm-dwarfdump (more readable output)
llvm-dwarfdump(输出更易读)
llvm-dwarfdump prog
llvm-dwarfdump --debug-info prog | grep "DW_AT_name"
llvm-dwarfdump --statistics prog # summarize DWARF sizes
undefinedllvm-dwarfdump prog
llvm-dwarfdump --debug-info prog | grep "DW_AT_name"
llvm-dwarfdump --statistics prog # 汇总DWARF大小
undefined3. Reading DWARF DIE structure
3. 解读DWARF DIE结构
text
undefinedtext
undefinedSample dwarfdump output for a variable
变量的dwarfdump输出示例
DW_TAG_compile_unit
DW_AT_producer : "GNU C17 13.2.0"
DW_AT_language : DW_LANG_C11
DW_AT_name : "main.c"
DW_AT_comp_dir : "/home/user/project"
DW_TAG_subprogram
DW_AT_name : "add"
DW_AT_type : <0x42> → points to int type DIE
DW_AT_low_pc : 0x401130 ← function start address
DW_AT_high_pc : 0x401150 ← function end address
DW_TAG_formal_parameter
DW_AT_name : "a"
DW_AT_type : <0x42>
DW_AT_location : DW_OP_reg5 (rdi) ← lives in register rdi
DW_TAG_formal_parameter
DW_AT_name : "b"
DW_AT_location : DW_OP_reg4 (rsi) ← lives in register rsi
Tags (DW_TAG_*): `compile_unit`, `subprogram`, `variable`, `formal_parameter`, `typedef`, `structure_type`, `member`, `array_type`, `pointer_type`, `base_type`
Attributes (DW_AT_*): `name`, `type`, `location`, `low_pc`, `high_pc`, `byte_size`, `encoding`, `file`, `line`DW_TAG_compile_unit
DW_AT_producer : "GNU C17 13.2.0"
DW_AT_language : DW_LANG_C11
DW_AT_name : "main.c"
DW_AT_comp_dir : "/home/user/project"
DW_TAG_subprogram
DW_AT_name : "add"
DW_AT_type : <0x42> → 指向int类型的DIE
DW_AT_low_pc : 0x401130 ← 函数起始地址
DW_AT_high_pc : 0x401150 ← 函数结束地址
DW_TAG_formal_parameter
DW_AT_name : "a"
DW_AT_type : <0x42>
DW_AT_location : DW_OP_reg5 (rdi) ← 存储在寄存器rdi中
DW_TAG_formal_parameter
DW_AT_name : "b"
DW_AT_location : DW_OP_reg4 (rsi) ← 存储在寄存器rsi中
标签(DW_TAG_*):`compile_unit`、`subprogram`、`variable`、`formal_parameter`、`typedef`、`structure_type`、`member`、`array_type`、`pointer_type`、`base_type`
属性(DW_AT_*):`name`、`type`、`location`、`low_pc`、`high_pc`、`byte_size`、`encoding`、`file`、`line`4. Split DWARF (.dwo files)
4. 拆分式DWARF(.dwo文件)
Split DWARF separates debug info from the linked binary into sidecar files, reducing linker input size:
.dwobash
undefined拆分式DWARF将调试信息与链接后的二进制文件分离为附属文件,减少链接器的输入大小:
.dwobash
undefinedCompile with split DWARF
启用拆分式DWARF编译
gcc -g -gsplit-dwarf -O2 -c main.c -o main.o
gcc -g -gsplit-dwarf -O2 -c main.c -o main.o
Creates: main.o (object without full DWARF) + main.dwo (debug info)
生成:main.o(不含完整DWARF的目标文件) + main.dwo(调试信息)
Link (linker only processes small .o files, not large DWARF)
链接(链接器仅处理体积小的.o文件,不处理大体积的DWARF)
gcc main.o -o prog
gcc main.o -o prog
prog references main.dwo but doesn't embed it
prog会引用main.dwo,但不会嵌入其中
GDB finds .dwo files via DW_AT_GNU_dwo_name attribute in prog
GDB通过prog中的DW_AT_GNU_dwo_name属性查找.dwo文件
gdb prog # works if main.dwo is in the same directory
gdb prog # 如果main.dwo在同一目录下则可正常工作
Inspect the split reference
检查拆分引用
readelf -S prog | grep ".gnu_debuglink|dwo"
dwarfdump prog | grep "dwo_name" # shows path to .dwo files
readelf -S prog | grep ".gnu_debuglink|dwo"
dwarfdump prog | grep "dwo_name" # 显示.dwo文件的路径
Package .dwo files into a single .dwp for distribution
将.dwo文件打包为单个.dwp文件用于分发
dwp -o prog.dwp prog # GNU dwp tool
llvm-dwp -o prog.dwp prog # LLVM version
dwp -o prog.dwp prog # GNU dwp工具
llvm-dwp -o prog.dwp prog # LLVM版本
With .dwp next to prog, GDB finds all debug info
当.dwp文件与prog放在一起时,GDB可找到所有调试信息
undefinedundefined5. debuginfod — remote debug symbol server
5. debuginfod — 远程调试符号服务器
debuginfodbash
undefineddebuginfodbash
undefinedClient: configure to use a debuginfod server
客户端:配置使用debuginfod服务器
export DEBUGINFOD_URLS="https://debuginfod.elfutils.org/"
export DEBUGINFOD_URLS="https://debuginfod.elfutils.org/"
GDB uses it automatically when symbols are missing
当符号缺失时,GDB会自动使用它
gdb /usr/bin/git
gdb /usr/bin/git
GDB will fetch debug symbols from debuginfod if not locally installed
如果本地未安装调试符号,GDB会从debuginfod获取
Explicit fetch
手动获取
debuginfod-find debuginfo /usr/bin/git # fetch debug info
debuginfod-find source /usr/bin/git # fetch source
debuginfod-find debuginfo /usr/bin/git # 获取调试信息
debuginfod-find source /usr/bin/git # 获取源码
Distribution servers
分发服务器
Ubuntu: https://debuginfod.ubuntu.com/
Ubuntu: https://debuginfod.ubuntu.com/
Debian: https://debuginfod.debian.net/
Debian: https://debuginfod.debian.net/
elfutils: https://debuginfod.elfutils.org/
elfutils: https://debuginfod.elfutils.org/
Configure in GDB
在GDB中配置
(gdb) set debuginfod enabled on
(gdb) set debuginfod verbose 1
(gdb) set debuginfod enabled on
(gdb) set debuginfod verbose 1
Set up your own debuginfod server
搭建自己的debuginfod服务器
debuginfod -d /var/cache/debuginfod -p 8002 /path/to/binaries/
export DEBUGINFOD_URLS="http://localhost:8002"
undefineddebuginfod -d /var/cache/debuginfod -p 8002 /path/to/binaries/
export DEBUGINFOD_URLS="http://localhost:8002"
undefined6. LTO and DWARF
6. LTO与DWARF
LTO affects DWARF debug information significantly:
bash
undefinedLTO对DWARF调试信息有显著影响:
bash
undefinedFull LTO: DWARF is generated after link-time optimization
全LTO:DWARF在链接时优化后生成
Variables and functions may be merged, inlined, or eliminated
变量和函数可能被合并、内联或删除
gcc -flto -O2 -g main.c util.c -o prog
gcc -flto -O2 -g main.c util.c -o prog
DWARF in prog reflects post-LTO state (may lose some info)
prog中的DWARF反映LTO后的状态(可能丢失部分信息)
Thin LTO (better for debug info preservation)
瘦LTO(更有利于保留调试信息)
clang -flto=thin -O2 -g main.c util.c -o prog
clang -flto=thin -O2 -g main.c util.c -o prog
For best debug info with LTO: use -Og or separate debug build
要在LTO下获得最佳调试信息:使用-Og或单独的调试构建
gcc -Og -g main.c util.c -o prog_debug # no LTO, full debug
gcc -O2 -flto main.c util.c -o prog_fast # LTO, limited debug
gcc -Og -g main.c util.c -o prog_debug # 无LTO,完整调试信息
gcc -O2 -flto main.c util.c -o prog_fast # 含LTO,调试信息有限
Rust: LTO discard debug info by default in non-release profiles
Rust:默认在非发布配置中LTO会丢弃调试信息
[profile.dev]
lto = "off" # preserves debug info
undefined[profile.dev]
lto = "off" # 保留调试信息
undefined7. Stripping and separate debug files
7. 符号剥离与独立调试文件
bash
undefinedbash
undefinedStrip binary (remove DWARF for distribution)
剥离二进制文件的调试信息(用于分发)
strip --strip-debug prog -o prog.stripped
strip --strip-debug prog -o prog.stripped
Keep separate debug file
保留独立调试文件
objcopy --only-keep-debug prog prog.debug
strip --strip-debug prog
objcopy --only-keep-debug prog prog.debug
strip --strip-debug prog
Link stripped binary to its debug file
将剥离后的二进制文件与调试文件关联
objcopy --add-gnu-debuglink=prog.debug prog
objcopy --add-gnu-debuglink=prog.debug prog
GDB finds debug file automatically
GDB会自动找到调试文件
gdb prog # loads prog.debug via .gnu_debuglink
gdb prog # 通过.gnu_debuglink加载prog.debug
Or use eu-strip (elfutils) — creates both in one step
或使用eu-strip(elfutils)——一步生成两者
eu-strip -f prog.debug prog
eu-strip -f prog.debug prog
Verify debug link
验证调试链接
readelf -n prog | grep "Debug|debuglink"
readelf -n prog | grep "Debug|debuglink"
Check DWARF size contribution
检查DWARF对文件大小的贡献
llvm-dwarfdump --statistics prog | grep "file size"
size --format=SysV prog | sort -k2rn | head -15
undefinedllvm-dwarfdump --statistics prog | grep "file size"
size --format=SysV prog | sort -k2rn | head -15
undefinedRelated skills
相关技能
- Use for debugging with split-DWARF builds
skills/debuggers/debug-optimized-builds - Use for using debuginfod with core dump analysis
skills/debuggers/core-dumps - Use for general ELF section inspection
skills/binaries/elf-inspection - Use for split-DWARF to speed up linking
skills/build-systems/build-acceleration
- 若要调试拆分式DWARF构建,请使用
skills/debuggers/debug-optimized-builds - 若要结合debuginfod进行核心转储分析,请使用
skills/debuggers/core-dumps - 若要进行通用ELF段检查,请使用
skills/binaries/elf-inspection - 若要利用拆分式DWARF加速链接,请使用
skills/build-systems/build-acceleration