具体分析Linux中的core dump异常(附 Demo排查)

[复制链接]
发表于 2026-10-3 11:16:08 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×

程序崩了但什么线索都没留下,是最难受的排查场景。Linux 的 core dump 就是干这个的:进程异常终止的瞬间,把内存映像.dump 到磁盘。这篇讲清它是什么、怎么开、文件长什么样、以及怎么用 GDB 定位到具体哪一行。

一、core dump 是什么

core dump(核心转储)指程序异常终止时,操作系统把该程序的内存映像保存到磁盘的机制。它记录了崩溃瞬间的内存状态,是定位程序错误最重要的手段之一。

常见触发原因:

  • 段错误 Segmentation fault:访问无效内存地址,比如未分配或已释放的内存;
  • 空指针引用 Null pointer dereference:拿 null 指针去读数据;
  • 内存访问越界 Out of bounds:数组、结构体访问超出边界;
  • 使用已释放内存 Use after free:释放后还读写;
  • 栈溢出 Stack overflow:递归太深或栈上分配过多;
  • 除以零 Division by zero;
  • 无效指令 Invalid instruction:执行了不存在的机器指令;
  • 硬件故障或内核崩溃:内存损坏等环境异常。

二、怎么让 core 文件生成出来

不是默认就 dump 的,要 ulimit -c 放开。先查当前限制:

ulimit -c

输出含义:

  • 数字(KB):当前用户允许生成的 core 文件大小上限;
  • unlimited:不限大小;
  • 0:不允许生成 core 文件(默认值,所以你通常看不到 core)。

放开:

ulimit -c unlimited

但 ulimit 只对当前 shell 会话有效,想永久生效得写进 /etc/security/limits.conf 或 systemd 的 LimitCORE。

三、core 文件放哪、叫什么

默认在当前工作目录下,文件名一般是 core 或 core.PID(PID 是崩溃进程的 ID)。

想改路径和命名格式,改 /proc/sys/kernel/core_pattern:

echo "core-%e-%p-%t" | sudo tee /proc/sys/kernel/core_pattern

另外 ulimit -c 控制 core 文件最大大小,两个一起决定能不能 dump 出来。

四、怎么分析

用 GDB(GNU Debugger) 加载 core 文件和对应的可执行文件:

gdb ./demo core

进去之后看堆栈跟踪、变量值,崩溃位置和原因基本就浮出来了。注意:可执行文件必须是带调试符号的那一份(-g 编译),发布版 strip 过的定位会很吃力。

五、Demo:从崩溃到定位

一个空指针写操作导致段错误的最小示例:

#include <stdio.h>

void cause_crash() {
    char *ptr = NULL;
    *ptr = 'A';   // 空指针写操作,段错误
}

int main() {
    cause_crash();
    return 0;
}

编译运行:

gcc -g -o demo demo.c
./demo            # 触发 coredump

用 GDB 分析:

gdb ./demo core

在 GDB 里打 bt 看堆栈:

(gdb) bt
#0  0x00005555555546e8 in cause_crash () at demo.c:6
#1  0x0000555555554701 in main () at demo.c:11

堆栈直接告诉你:问题出在 cause_crash 函数的第 6 行(空指针引用导致段错误)。这种简单场景下,修复就是在写操作前加个空指针检查。

六、正常排查流程

  1. 拿到 core 文件:确认它生成在哪(没生成就先看 ulimit 和 core_pattern);
  2. 分析 core:GDB 加载 + bt 看堆栈、p 看变量;
  3. 定位原因:判断是内存访问错误、空指针、还是数据破坏;
  4. 改代码:修内存管理、补错误检查和异常处理;
  5. 回归验证:单测、集成测试确保不再崩。

七、为什么有时候 core 文件生不出来

几种常见原因:

  • core 大小为 0:ulimit 限制,改成 unlimited 试试;
  • 挂载点满了(比如 /dev/loop 相关挂载空间不足),写不进去——这时候日志日志里会一直刷写失败,不是权限问题;
  • core_pattern 指向了不存在的目录或没有写权限;
  • 进程被 SIGKILL(OOM 杀掉):这类通常不产生 core,得看 dmesg 的 OOM 记录。

总结

core dump 排查链:ulimit -c unlimited 开开关 → 崩溃后拿到 core(或用 core_pattern 指定路径)→ gdb 可执行 core + bt 看堆栈 → 定位到源码某一行 → 修 + 回归。记住 ulimit 是临时的、core_pattern 也重启即失效,生产环境要提前把这两条写进配置。加 -g 编译,别用发布版二进制硬猜。

qidao123.com企服评测-应用市场 编辑提示

回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表