gdb加载core文件必须同时指定原始可执行文件,否则仅显示内存地址而无法解析源码、变量和函数名;核心原则是“core是快照,executable是地图”,二者必须严格匹配同一份带-g编译的二进制。

gdb 加载 core 文件必须同时关联原始可执行文件,否则看不到源码、变量、函数名,只剩一堆内存地址。核心原则是:**core 是快照,executable 是地图;没地图,快照就是废片。**
gdb executable core 是最简且推荐的启动方式
直接在命令行传入两个路径,GDB 会自动读符号表并定位崩溃现场:
gdb /path/to/myapp /var/core/core.myapp.12345
成功后你会看到类似:
#0 0x00005555555546b9 in main () at main.c:12
这说明符号加载正常。注意两点:
- 路径必须准确——
executable必须是生成该core的**同一份二进制**(哪怕只改一行再重编译,符号偏移就可能错) - 如果提示
No symbol table is loaded,大概率是编译时没加-g,或运行时被strip过 - 若可执行文件依赖动态库(如
libfoo.so),而core里记录的库路径已失效,GDB 启动后需手动补:set solib-search-path /path/to/libs
为什么不能只用 gdb 然后 core-file?
可以,但容易漏关键步骤。比如你只输:
gdb (gdb) core-file /var/core/core.myapp.12345
GDB 会报错:Core was generated by 'myapp'.,但紧接着提示 No executable file specified。此时你得再补一句:
(gdb) file /path/to/myapp
顺序不能反——先 core-file 再 file 才能正确映射内存段。反过来(先 file 再 core-file)有时也能工作,但某些版本 GDB 会忽略 core 中的线程/寄存器状态。
常见错误:Cannot access memory at address 或栈帧不全
这不是命令写错了,而是环境不匹配:
-
core是 64 位程序生成的,你却用 32 位gdb打开(或反之)→ 检查file /path/to/myapp输出的架构是否与gdb --version一致 - 可执行文件被
ASLR干扰(尤其容器或 hardened 系统)→ 启动 GDB 前加set disable-randomization off(不过多数现代 GDB 默认已处理) -
core文件被截断(ulimit -c设太小)→ls -lh /var/core/core.myapp.*看大小,file命令输出里若有truncated字样就确认了
调试前务必验证三件事
别急着 bt,先敲这三行:
(gdb) info files # 确认 executable 和 core 的路径、架构、load address 是否对齐<br>(gdb) info registers # 看 rbp/rip 是否合理(比如 rip 不是 0x0 或超大值)<br>(gdb) info proc mappings # 检查关键段(如 .text, heap)是否被标记为 readable/writable
其中任意一项异常,后续所有分析都可能南辕北辙。尤其是 info proc mappings 在排查 SIGBUS 或共享内存问题时,比 bt 有用得多。











