GDB报“not a core dump”说明文件非真实core,因缺失ELF魔数或NT_PRSTATUS等关键段;应先用file和readelf -n验证文件本质,再检查core_pattern是否被管道拦截、磁盘权限及setuid限制。

gdb报错“not core dump”说明文件格式不对
这个错误不是GDB拒绝调试,而是它读取到的文件根本不符合Linux core dump的二进制结构。常见于:手动创建空文件、重命名非core文件为core、或程序崩溃时被apport等服务拦截后伪造的残留文件。GDB会直接校验ELF魔数和NT_PRSTATUS等核心note段,缺失任一就报此错。
确认文件是否真是core dump
别依赖文件名,用file命令看本质:
file core
正常core文件输出应含core file字样,例如:core: ELF 64-bit LSB core file x86-64, version 1 (SYSV), SVR4-style, from 'test'。如果显示data、empty或ASCII text,那就不是core。
进一步验证可用readelf:
readelf -n core 2>/dev/null | head -5
有输出且含NT_PRSTATUS或NT_AUXV才可信。若报Not an ELF file或无输出,直接放弃调试。
- 检查
/proc/sys/kernel/core_pattern是否被设为管道(如|/usr/share/apport/apport),这种模式下不会落盘真实core,只会传给脚本处理 - 运行
cat /proc/sys/kernel/core_pattern,输出是路径才可能生成文件;含|字符就是被拦截了 - 临时绕过:用
echo "/tmp/core.%e.%p" | sudo tee /proc/sys/kernel/core_pattern切回文件模式
ulimit -c unlimited之后仍没生成有效core
即使ulimit -c unlimited生效,还有三个关键点常被忽略:
-
/tmp或目标目录磁盘满、无写权限(GDB不报错,但内核静默丢弃core) - 进程以
setuid/setgid方式运行(内核默认禁用其core dump,需配fs.suid_dumpable=1) - 容器环境(如Docker)未挂载
/proc/sys或未加--privileged,导致core_pattern设置无效
快速自检命令:
grep "core" /proc/self/status
看CapBnd是否含cap_sys_admin,以及Seccomp是否为0——非0表示seccomp策略可能屏蔽了sys_prctl调用,从而禁用core生成。
gdb加载core时必须指定原始可执行文件
gdb命令格式严格是gdb <binary><core></core></binary>,不能反过来,也不能省略binary。哪怕binary已删除,只要符号表没丢,就得用原文件(或带.debug链接的stripped版)。
常见误操作:
-
gdb core→ 缺binary,GDB无法解析内存布局,直接报错或显示乱码栈 -
gdb ./a.out core-1234但a.out是后来重新编译的(无-g或地址偏移不同)→ 栈帧错位,bt显示函数名但行号不准 - binary被strip过且没保留
.debug文件 →bt只能看到函数名,看不到源码行,用info registers和x/10i $rip查汇编是唯一办法
验证binary与core匹配性:
readelf -h ./a.out | grep Type
输出应为EXEC (Executable file);而readelf -h core | grep Type应为CORE (Core file)。两者Class(32/64位)、Data(LSB/MSB)必须一致,否则GDB拒绝加载。
真正麻烦的不是“找不到core”,而是“以为找到了却不是core”。很多团队花几小时在假core上反复bt,不如先用file和readelf -n两步确认——这比任何GDB技巧都管用。


















