Linux Core Dump 配置与分析指南
本文介绍 Linux 下 Core Dump 的含义、作用,以及如何配置生成 core 文件、如何用 GDB 分析崩溃现场,并给出常见问题与避坑建议。便于在段错误、内存越界等难以复现的线上崩溃场景中快速定位问题。
目录
[一、什么是 Core Dump](#一、什么是 Core Dump)
[二、如何配置 Core Dump](#二、如何配置 Core Dump)
[三、如何用 GDB 分析](#三、如何用 GDB 分析)
四、常见问题与避坑
小结与延伸阅读
一、什么是 Core Dump
Core Dump (核心转储)是程序异常终止 (如崩溃、收到某些信号)时,操作系统将进程的内存、寄存器、调用栈等状态写入磁盘所生成的文件,相当于崩溃瞬间的"现场快照"。
Core 文件通常包含(示意):
复制代码
┌─────────────────────────────────────────────────┐
│ Core 文件内容(供 GDB 等工具解析) │
├─────────────────────────────────────────────────┤
│ 进程内存镜像 │ 堆、栈、数据段、代码段等 │
│ 寄存器状态 │ PC、SP、通用寄存器等 │
│ 元数据 │ 信号编号、可执行路径、线程信息等 │
└─────────────────────────────────────────────────┘
GDB 据此还原崩溃时刻的调用栈、变量和寄存器,从而定位崩溃原因。
1.1 作用
作用
说明
精准定位
结合 GDB 可查看崩溃时的调用栈、变量、寄存器,定位到具体代码行
应对难复现问题
线上或压测中偶发段错误、内存越界等,无需当场复现即可事后分析
告别"盲猜"
有完整现场,便于区分是空指针、越界、栈溢出还是其他原因
1.2 典型触发场景
进程收到下列信号且未捕获、未忽略 时,默认行为为终止并可能生成 core(取决于 ulimit -c 与 core_pattern):
信号
含义
常见原因
SIGSEGV (11)
段错误
空指针解引用、非法内存访问、栈溢出
SIGABRT (6)
主动中止
abort()、断言失败、C++ std::terminate
SIGBUS (7)
总线错误
未对齐访问、映射失败后的访问等
SIGFPE (8)
算术异常
除零、整数溢出等
SIGILL (4)
非法指令
损坏的代码、不兼容的指令集
生成流程概览(配置正确时):
复制代码
进程崩溃(收到上述信号)
│
▼
内核执行信号默认行为(终止进程)
│
▼
检查 ulimit -c 是否允许生成 core
│
┌────┴────┐
│ 允许 │ 禁止 → 不生成 core
▼ │
按 core_pattern 决定路径与文件名
│
▼
将进程内存、寄存器、栈等写入 core 文件
二、如何配置 Core Dump
2.1 开启 core 文件生成与大小限制
bash
复制代码
# 查看当前限制(若为 0 则不会生成 core 文件)
ulimit -c
# 解除大小限制,允许生成任意大小的 core 文件(当前 shell 及子进程生效)
ulimit -c unlimited
若需持久生效 ,可在用户 shell 配置(如 ~/.bashrc)中写入 ulimit -c unlimited,或在 systemd 服务中通过 LimitCORE=infinity 等配置。
2.2 自定义 core 文件路径与命名
通过 /proc/sys/kernel/core_pattern 指定 core 文件的保存路径和文件名格式:
bash
复制代码
# 查看当前配置
cat /proc/sys/kernel/core_pattern
# 临时修改(需 root)
echo "/var/coredump/core-%e-%p-%t" | sudo tee /proc/sys/kernel/core_pattern
常用占位符:
占位符
含义
%e
可执行文件名
%p
PID
%t
时间戳(通常为 Unix 时间)
%h
主机名
%s
导致 dump 的信号编号
示例:/var/coredump/core-%e-%p-%t 会生成如 core-myapp-12345-1640000000 的文件。需确保目标目录存在且进程有写权限。
2.3 systemd 服务中开启 Core Dump(持久生效)
通过 systemd 管理的服务若需在崩溃时生成 core,可在 unit 中设置 LimitCORE=infinity(或足够大的字节数),并视情况配合 core_pattern 使用。
示例一:在 service 文件里直接写 limit
ini
复制代码
[Unit]
Description=My Demo Service
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/myapp
# 允许生成任意大小的 core 文件
LimitCORE=infinity
# 可选:限制仅本服务生效,不继承 system 默认
# LimitCORE=infinity
[Install]
WantedBy=multi-user.target
示例二:用 drop-in 覆盖已有服务的 limit(不改原 unit 文件)
bash
复制代码
# 创建 drop-in 目录
sudo mkdir -p /etc/systemd/system/myapp.service.d/
# 创建 conf 文件,只写要覆盖的项
sudo tee /etc/systemd/system/myapp.service.d/coredump.conf << 'EOF'
[Service]
LimitCORE=infinity
EOF
# 重载并重启服务
sudo systemctl daemon-reload
sudo systemctl restart myapp.service
示例三:确认生效
bash
复制代码
# 查看该进程的 core 限制(PID 需替换为实际值)
cat /proc/
# 期望看到:Max core file size unlimited unlimited
与 core_pattern 的配合 :LimitCORE 只控制"是否允许生成、最大多大";core 写到哪里、叫什么名字仍由 /proc/sys/kernel/core_pattern 决定。若希望 core 落盘到固定目录,需事先用 sysctl 或 echo ... > /proc/sys/kernel/core_pattern 配置好路径,并保证该目录存在且进程(或 kernel)有写权限。
2.4 配置要点小结
项目
说明
ulimit -c
为 0 则不生成;设为 unlimited 或足够大的数字以允许生成
core_pattern
路径需存在、可写;可用占位符区分不同进程与时间
权限
若 core 含敏感信息,应限制目录权限与访问范围
配置检查清单(生成 core 前建议确认):
检查项
命令或方法
当前 shell 的 core 限制
ulimit -c(应为 unlimited 或非 0)
系统 core 路径与命名
cat /proc/sys/kernel/core_pattern
目标目录是否存在、可写
ls -la /var/coredump(或你配置的目录)
持久化(如 systemd 服务)
见上文 2.3 systemd 示例;或启动脚本中 ulimit -c unlimited
三、如何用 GDB 分析
3.1 加载程序与 core 文件
bash
复制代码
gdb <可执行程序>
# 示例
gdb ./myapp /var/coredump/core-myapp-12345-1640000000
3.2 常用 GDB 命令
命令
说明
bt(backtrace)
查看崩溃时的完整调用栈,快速定位出错函数与层级
bt full
在每帧中打印局部变量等信息
info registers
查看寄存器
frame N
切换到栈帧 N
list
查看当前帧附近源码
print 变量
打印变量值(需带调试符号)
3.3 分析流程简述
推荐步骤可概括为:
复制代码
gdb <程序>
│
▼
bt / bt full → 定位崩溃栈帧与行号
│
▼
frame N → 切换到怀疑的帧
│
▼
print 变量 → 查看指针、关键变量
list → 查看源码上下文
│
▼
判断原因(空指针 / 越界 / 双重释放 / 栈溢出等)→ 修复代码
步骤
目的
bt
看完整调用栈,找到崩溃发生在哪一帧、哪一行
frame N
切换到第 N 帧,便于查看该帧的局部变量
查看指针是否为空、下标是否越界、对象是否已释放
list
查看当前帧附近源码,配合行号理解逻辑
注意 :若编译时未加 -g,GDB 无法显示符号名和行号,只能看到地址,分析会困难很多。
3.4 GDB 分析速查表
场景
常用命令
看调用栈
bt、bt full
看当前帧源码
frame、list
看变量/寄存器
print 变量、info registers
看线程
info threads、thread N
看内存
x/Nx 地址(N 为单位数)
四、常见问题与避坑
4.1 没有生成 core 文件
可能原因
排查与处理
ulimit -c 为 0
当前 shell 执行 ulimit -c unlimited;或检查 systemd/启动脚本中的 limit 配置
目标目录无写权限
检查 core_pattern 中的目录是否存在、进程用户是否有写权限
core_pattern 路径错误
用 cat /proc/sys/kernel/core_pattern 确认,路径中的目录需事先创建
磁盘空间不足
确保目标分区有足够空间;core 文件可能较大
4.2 GDB 中无符号、无行号
原因:可执行文件未带调试信息。
解决 :编译时加上 -g (如 gcc -g -O0 ...),发布时可保留带符号的副本专门用于分析 core,或使用 strip 分离符号文件。
4.3 生产环境风险
风险
建议
敏感信息
core 文件可能包含内存中的密码、密钥等,需严格限制访问与保留时间
磁盘占用
大进程 core 可能数 GB,需监控磁盘与清理策略
性能与稳定性
生成大 core 时可能卡顿,建议仅在测试或受控环境开启,或按需开启
4.4 问题与对策速查表
现象
可能原因
对策
完全没有 core 文件
ulimit -c 为 0;目录不存在或无写权限;core_pattern 错误
见 4.1;逐项检查配置清单
GDB 中无符号、无行号
未带调试信息编译
重新编译加 -g,或保留带符号副本用于分析
core 与可执行文件不匹配
程序已更新,core 是旧版本崩溃
用与崩溃时一致的可执行文件(或同版本 + 符号)加载 core
多线程崩溃难以定位
需看其他线程栈
GDB 中 info threads、thread N、bt 结合分析
小结与延伸阅读
小结
Core Dump 是进程崩溃时的内存与状态快照,用于事后用 GDB 分析调用栈与变量,精准定位段错误、越界等问题。
配置 :ulimit -c unlimited 解除大小限制;通过 core_pattern 指定路径和命名(如 %e-%p-%t)。
分析 :gdb <程序>
避坑:检查 ulimit、目录权限与 core_pattern;生产环境注意敏感信息与磁盘占用,建议在测试或受控环境使用。
延伸阅读
signal(7) 、core(5):Linux man 手册中关于信号与 core 的说明。
GDB 手册:backtrace、examining stack、symbols 等章节。
同目录 Android_Tombstone崩溃日志详解:Android 侧的崩溃快照与分析思路。
根据 Linux Core Dump 相关教程与实操整理。

