Linux Core Dump 配置与分析指南

Linux Core Dump 配置与分析指南

本文介绍 Linux 下 Core Dump 的含义、作用,以及如何配置生成 core 文件、如何用 GDB 分析崩溃现场,并给出常见问题与避坑建议。便于在段错误、内存越界等难以复现的线上崩溃场景中快速定位问题。


目录

  1. [一、什么是 Core Dump](#一、什么是 Core Dump)
  2. [二、如何配置 Core Dump](#二、如何配置 Core Dump)
  3. [三、如何用 GDB 分析](#三、如何用 GDB 分析)
  4. 四、常见问题与避坑
  5. 小结与延伸阅读

一、什么是 Core Dump

Core Dump (核心转储)是程序异常终止 (如崩溃、收到某些信号)时,操作系统将进程的内存、寄存器、调用栈等状态写入磁盘所生成的文件,相当于崩溃瞬间的"现场快照"。

Core 文件通常包含(示意):

复制代码
┌─────────────────────────────────────────────────┐
│  Core 文件内容(供 GDB 等工具解析)               │
├─────────────────────────────────────────────────┤
│  进程内存镜像  │ 堆、栈、数据段、代码段等         │
│  寄存器状态   │ PC、SP、通用寄存器等             │
│  元数据       │ 信号编号、可执行路径、线程信息等  │
└─────────────────────────────────────────────────┘

GDB 据此还原崩溃时刻的调用栈、变量和寄存器,从而定位崩溃原因。

1.1 作用

作用 说明
精准定位 结合 GDB 可查看崩溃时的调用栈、变量、寄存器,定位到具体代码行
应对难复现问题 线上或压测中偶发段错误、内存越界等,无需当场复现即可事后分析
告别"盲猜" 有完整现场,便于区分是空指针、越界、栈溢出还是其他原因

1.2 典型触发场景

进程收到下列信号且未捕获、未忽略 时,默认行为为终止并可能生成 core(取决于 ulimit -ccore_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/<PID>/limits | grep "core file size"
# 期望看到:Max core file size    unlimited    unlimited

与 core_pattern 的配合LimitCORE 只控制"是否允许生成、最大多大";core 写到哪里、叫什么名字仍由 /proc/sys/kernel/core_pattern 决定。若希望 core 落盘到固定目录,需事先用 sysctlecho ... > /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 <可执行程序> <core 文件>
# 示例
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 <程序> <core 文件>
         │
         ▼
  bt / bt full  →  定位崩溃栈帧与行号
         │
         ▼
  frame N       →  切换到怀疑的帧
         │
         ▼
  print 变量    →  查看指针、关键变量
  list          →  查看源码上下文
         │
         ▼
  判断原因(空指针 / 越界 / 双重释放 / 栈溢出等)→ 修复代码
步骤 目的
bt 看完整调用栈,找到崩溃发生在哪一帧、哪一行
frame N 切换到第 N 帧,便于查看该帧的局部变量
print 查看指针是否为空、下标是否越界、对象是否已释放
list 查看当前帧附近源码,配合行号理解逻辑

注意 :若编译时未加 -g,GDB 无法显示符号名和行号,只能看到地址,分析会困难很多。


3.4 GDB 分析速查表

场景 常用命令
看调用栈 btbt full
看当前帧源码 framelist
看变量/寄存器 print 变量info registers
看线程 info threadsthread 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 threadsthread Nbt 结合分析

小结与延伸阅读

小结

  • Core Dump 是进程崩溃时的内存与状态快照,用于事后用 GDB 分析调用栈与变量,精准定位段错误、越界等问题。
  • 配置ulimit -c unlimited 解除大小限制;通过 core_pattern 指定路径和命名(如 %e-%p-%t)。
  • 分析gdb <程序> <core>,用 bt 看调用栈,用 frame/print/list 查变量与源码;编译时加 -g 才能看到符号和行号。
  • 避坑:检查 ulimit、目录权限与 core_pattern;生产环境注意敏感信息与磁盘占用,建议在测试或受控环境使用。

延伸阅读

  • signal(7)core(5):Linux man 手册中关于信号与 core 的说明。
  • GDB 手册:backtrace、examining stack、symbols 等章节。
  • 同目录 Android_Tombstone崩溃日志详解:Android 侧的崩溃快照与分析思路。

根据 Linux Core Dump 相关教程与实操整理。

相关推荐
IMPYLH2 小时前
Linux 的 chcon 命令
linux·运维·服务器
苦逼IT运维2 小时前
SVN 仓库目录迁移,仓库 “降级” 成子目录实战
linux·运维·ci/cd·svn·运维开发
阿拉斯攀登2 小时前
第 13 篇 输入设备驱动(触摸屏 / 按键)开发详解,Linux input 子系统全解析
android·linux·运维·驱动开发·rk3568·瑞芯微·rk安卓驱动
ego.iblacat3 小时前
Nginx 性能优化与深度监控
运维·nginx·性能优化
爱丽_3 小时前
TCP 三次握手与四次挥手
服务器·网络·tcp/ip
智能工业品检测-奇妙智能3 小时前
金属矿山安全智能AI视觉识别
服务器·人工智能·安全·openclaw·奇妙智能
bukeyiwanshui3 小时前
【无标题】
linux·运维·服务器
疯狂吧小飞牛3 小时前
Linux 多网卡同网段配置冲突问题
linux·运维·服务器
-ONLY-¥3 小时前
Nginx性能优化与监控全攻略
linux