Linux C GDB Debug Info 学习笔记
1. Debug 信息的设置与有无对比
编译选项
| 选项 | 说明 |
|---|
-g / -g2 | 生成标准 DWARF debug 信息(推荐) |
-g1 | 仅生成最小调试信息(函数名、行号) |
-g3 | 包含宏定义等额外信息 |
-O0 | 关闭优化,保证源码与指令一一对应 |
-O2/-O3 | 开启优化,可能导致调试时变量被优化掉 |
验证命令
gcc -g -O0 demo.c -o demo_debug # 带 debug 信息
gcc demo.c -o demo_release # 不带 debug 信息
readelf -S demo_debug | grep debug # 查看 .debug_* 段
2. 为什么要分离 Debug 信息
- 减小发布体积:debug 信息通常占二进制 50%~80%
- 保护源码:避免源码路径、变量名泄露
- 按需加载:GDB 仅在需要时加载,减少内存占用
- 独立更新:代码小改无需重新分发完整 debug 包
3. 分离 Debug 信息的方法
使用 objcopy
# 1. 提取 debug 信息到独立文件
objcopy --only-keep-debug demo demo.debug
# 2. 从原文件中剥离 debug 段
objcopy --strip-debug demo demo_stripped
# 3. 添加关联链接(让 GDB 自动找到 debug 文件)
objcopy --add-gnu-debuglink=demo.debug demo_stripped
验证关联
readelf -x .gnu_debuglink demo_stripped
# 输出包含 debug 文件名 + CRC32 校验值
4. GDB 如何使用分离的 Debug 信息
自动查找顺序
- 同目录下
demo_stripped.debug
.debug/ 子目录
/usr/lib/debug/ 系统目录
- build-id 匹配(
.build-id/xx/yyyy.debug)
手动指定
# 方式1:启动后加载
(gdb) symbol-file demo.debug
# 方式2:设置搜索目录
(gdb) set debug-file-directory /path/to/debug/files
# 方式3:启动时指定
gdb -ex "set debug-file-directory ./debug" demo_stripped
验证加载成功
(gdb) info sources # 应显示源码文件列表
(gdb) list main # 能正常显示源码
(gdb) print variable # 能查看变量值
5. 最佳实践总结
| 场景 | 建议 |
|---|
| 开发阶段 | gcc -g3 -O0 全量调试 |
| 测试/预发 | gcc -g2 -O1 平衡性能与调试 |
| 生产发布 | 分离 debug + strip,保留 .gnu_debuglink |
| 崩溃分析 | 确保 debug 文件版本与二进制严格匹配 |
| CI/CD | 自动归档 debug 文件到符号服务器 |
⚠️ 关键提醒:debug 文件必须与对应二进制同一次编译产物,否则 CRC 校验失败或符号错位