gdb找不到源文件主因是调试信息中的路径与当前源码位置不一致:绝对路径需用set substitute-path映射,相对路径可用dir添加搜索目录;关键先用readelf -p .debug_str确认路径类型。

gdb 找不到源文件,绝大多数情况不是缺代码,而是路径对不上 —— 编译时记录的路径和你当前存放源码的位置不一致。
用 readelf -p .debug_str 确认调试信息里存的是绝对路径还是相对路径
这是最关键的一步。gdb 查源码的行为完全取决于编译器写进 .debug_str 段的内容:
- 如果输出里看到类似
/home/user/project/src/main.c这种完整路径,说明是绝对路径,dir命令基本无效,得用set substitute-path - 如果看到
../src/main.c或main.c,说明是相对路径,dir命令就能生效 - 执行命令:
readelf -p .debug_str ./a.out(把a.out换成你的可执行文件) - 注意:这个命令要运行在目标二进制文件所在机器上,不能只在开发机查
绝对路径不匹配时用 set substitute-path 做路径映射
这是解决跨机器调试、发布机编译/开发机调试等场景最可靠的方式:
- 先用
list看 gdb 报错里显示的原始路径,比如:/build/project/src/utils.h: No such file or directory - 再确认你本地源码实际放在哪,比如:
/home/me/project/src/utils.h - 执行映射:
set substitute-path /build/project/ /home/me/project/ - 可以叠加多条:
set substitute-path /opt/qt/ /usr/src/qt/ - 查看当前规则:
show substitute-path - 注意:路径末尾的
/必须一致,/build/project和/build/project/是不同字符串
相对路径不匹配时用 dir 添加搜索目录
适用于源码被整体移动、但内部相对结构没变的情况:
- 比如编译时源码在
./src/,现在移到了../myproj/src/ - 在 gdb 里执行:
dir ../myproj/src(支持多个路径,用:分隔) - 验证是否生效:
show directories会列出所有已添加的搜索路径 - 注意:
dir只对相对路径起作用;它不会修改路径字符串,只是在前面拼接前缀 - 常见误操作:
dir /home/me/project对/home/me/project/src/main.c这类绝对路径完全无效
启动时自动加载路径配置,避免每次手动输
把常用设置固化到 ~/.gdbinit,省去重复劳动:
- 写入示例:
set substitute-path /build/app/ /home/dev/app/ dir /home/dev/app/src dir /home/dev/app/include
- 注意权限:确保
~/.gdbinit不是 group/o 可写,否则 gdb 为安全会拒绝加载 - 如果用了
set substitute-path却没生效,大概率是因为没加这句:set auto-load safe-path /(尤其在较新 gdb 版本中) - 也可以用命令行参数启动:
gdb -q -d /path/to/src ./a.out,-d等价于dir
真正容易被忽略的点是:gdb 从不“猜”路径,它只做字面替换或拼接。你看到的报错路径,就是它从调试信息里原样读出来的字符串 —— 所以别试图靠改当前工作目录来蒙混过关,必须让 substitute-path 或 dir 精确覆盖那个字符串的开头部分。











