dir命令对绝对路径无效,因debug info中存储的是绝对路径,而dir仅在相对路径下查找;应使用set substitute-path from_path to_path进行前缀替换。

源码路径不对,dir 命令基本无效——因为 debug info 里存的是绝对路径,而 dir 只对相对路径起作用。
为什么 dir 设置源码路径后仍找不到文件
编译时(尤其是 CMake 默认行为)会把源文件的完整绝对路径写进 .debug_str 段,GDB list 显示的也是类似 /home/user/project/src/main.cpp 这样的路径。此时执行 dir /path/to/src 不会做字符串替换,只是在该目录下按相对路径查找,自然失败。
验证方法:
- 在 GDB 中运行
list,看提示的路径是不是绝对路径 - 用
readelf -p .debug_str your_binary | grep "\.cpp"确认 debug info 中记录的实际路径
set substitute-path 是唯一可靠的修复方式
它直接对 debug info 中记录的路径做前缀替换,不依赖源码组织方式,也不要求你改编译流程。
操作步骤:
- 先确认 GDB 报错中显示的原始路径,比如
/build/project-abc123/src/log.cpp - 再确认你本地源码实际位置,比如
/home/dev/myproject/src/log.cpp - 执行:
set substitute-path /build/project-abc123/ /home/dev/myproject/ - 重新
list或bt,就能定位到正确行号了
注意:substitute-path 是逐条生效的,路径末尾的斜杠必须一致;可设置多条,GDB 按顺序匹配第一条成功者。
临时方案:用 -grecord-gcc-switches 避免绝对路径问题(仅限新编译)
如果你能控制编译过程,且不希望后续每次调试都手动设 substitute-path,可以在 GCC/G++ 中加这个参数:
gcc -g -grecord-gcc-switches -o app app.c- 它会让 debug info 尽量记录相对路径或构建上下文,降低对源码摆放位置的依赖
- 但对已发布的二进制、CMake 默认构建、或用了
-fdebug-prefix-map的情况,此法不生效
更彻底的构建期控制是 -fdebug-prefix-map=old_path=new_path,效果等价于运行时的 set substitute-path,但需提前知道映射关系。
容易被忽略的细节:core 文件 + 调试符号必须匹配
即使路径修好了,如果 core 对应的可执行文件被 strip 过、或调试符号被单独剥离(.debug 文件未加载),set substitute-path 也无济于事。
务必确认:
-
file your_binary输出中包含 “with debug_info” -
readelf -S your_binary | grep debug应看到多个.debug_*段 - 若用分离符号,启动 GDB 时加
-ex "add-symbol-file /path/to/debug-file"
路径映射只是“找得到源码”,符号存在才是“看得懂调用栈”。两者缺一不可。


















