一文搞懂应用程序 core dump 和内核 core dump

调试 应用程序 core dump内核 core dump (kdump/vmcore) 需要完全不同的工具链和流程。下面我从 原理 → 准备工作 → 调试流程 → 典型场景 全面讲解。


1. 应用程序 core dump 调试

应用程序 core dump 是指 用户态进程 崩溃后生成的内存镜像,常见原因有 SIGSEGVSIGABRT 等。


1.1 典型触发场景

崩溃原因 常见触发信号 典型表现
空指针/非法内存访问 SIGSEGV (11) 段错误,dmesg 中有 Segfault
除零、浮点异常 SIGFPE (8) 数学运算崩溃
调用 abort() SIGABRT (6) 进程主动中止
内存越界、UAF SIGBUS (7) 总线错误
断言失败 SIGABRT (6) 程序代码 assert() 触发

1.2 Core 文件生成与收集

(1) 检查系统是否允许生成 core

bash 复制代码
ulimit -c
  • 输出 0:不生成 core,需要打开

  • 临时启用:

    bash 复制代码
    ulimit -c unlimited

(2) 设置 core 文件命名与路径

通过 /proc/sys/kernel/core_pattern 配置,例如:

bash 复制代码
cat /proc/sys/kernel/core_pattern

常见输出:

perl 复制代码
|/usr/lib/systemd/systemd-coredump %P %u %g %s %t %e

说明:如果输出以 | 开头,表示 core dump 会交给 systemd-coredump 处理,并压缩到 /var/lib/systemd/coredump/

若想存储到自定义目录:

perl 复制代码
sudo sysctl -w kernel.core_pattern="/var/core/core.%e.%p.%t"

(3) systemd-coredump 方式收集

直接用:

xml 复制代码
coredumpctl list
coredumpctl info <PID>
coredumpctl gdb <PID>
  • list:查看所有 core dump 记录
  • info:查看 core dump 详情
  • gdb:直接进入 GDB 调试(无需手动找 core 文件)

1.3 调试核心步骤

(1) 准备符号文件

必须确保可执行程序是带调试符号的:

复制代码
gcc -g -O0 myapp.c -o myapp

如果是发行版程序,安装 debuginfo 包,例如 SLES:

复制代码
zypper install myapp-debuginfo

(2) 启动 gdb

假设 core 文件是 core.12345,可执行文件是 myapp

复制代码
gdb myapp core.12345

(3) 常用调试命令

命令 作用
bt 打印崩溃线程的调用栈
thread apply all bt 打印所有线程的调用栈
info locals 查看当前函数局部变量
info registers 查看寄存器状态
frame N 切换到栈帧 N
list 查看崩溃点附近的源码
p var 打印变量值
x/16x addr 查看内存内容

示例:

less 复制代码
(gdb) bt
#0  0x00007ffff7a3345d in strlen () from /lib64/libc.so.6
#1  0x0000000000401172 in process_data (str=0x0) at main.c:25
#2  0x00000000004011d5 in main () at main.c:40

结论:调用 strlen(NULL) 导致 SIGSEGV。


(4) 多线程分析

如果程序多线程,必须检查所有线程状态:

scss 复制代码
(gdb) info threads
  Id   Target Id         Frame 
* 1    Thread 0x7ffff7fc2700 (LWP 12345) "myapp" strlen ()
  2    Thread 0x7ffff77c1700 (LWP 12346) __pthread_cond_wait ()

(5) 高级工具

  • gcore:运行中生成 core dump

    xml 复制代码
    gcore <pid>
  • valgrind:检测内存越界、内存泄漏

    ini 复制代码
    valgrind --leak-check=full ./myapp

1.4 应用 core dump 调试总结流程

  1. 确认 core 文件存在,使用 coredumpctl/proc/sys/kernel/core_pattern 检查。

  2. 确认可执行文件和符号包完整。

  3. gdb myapp core.xxx 进入调试。

  4. 重点分析:

    • 崩溃线程调用栈 bt
    • 线程间死锁问题 thread apply all bt
    • 检查局部变量、内存
  5. 根据源码或逻辑定位 bug。


2. 内核 core dump (kdump/vmcore) 调试

内核 core dump 捕获的是 整个系统内核态内存 ,用于分析 Kernel Panic、软锁死、驱动 Bug 等问题。


2.1 典型触发场景

触发问题 常见表现
驱动 Bug 内核 Panic,堆栈指向特定驱动
内核 Null Pointer Kernel NULL pointer dereference
硬件故障 NMI Panic、ECC 错误
调度死锁 Soft Lockup/Hard Lockup
文件系统崩溃 ext4 / xfs 内核函数触发 panic

2.2 kdump 配置与收集

  1. 安装 kdump 组件

    复制代码
    zypper install kdump crash
  2. 启用 kdump 服务

    bash 复制代码
    systemctl enable kdump
    systemctl start kdump
  3. 配置 /etc/kdump.conf

    css 复制代码
    path /var/crash
    core_collector makedumpfile -c --message-level 1 -d 31
  4. 触发 panic 测试

    bash 复制代码
    echo c > /proc/sysrq-trigger

    机器重启后,会在 /var/crash/ 下生成目录:

    bash 复制代码
    /var/crash/2025-09-09-11:02/vmcore
    /var/crash/2025-09-09-11:02/vmcore-dmesg.txt

2.3 调试工具:crash

(1) 启动 crash

bash 复制代码
crash /usr/lib/debug/lib/modules/$(uname -r)/vmlinux /var/crash/2025-09-09-11:02/vmcore

注意:
vmlinux 必须是未剥离符号的内核调试文件,否则无法解析函数名。


(2) 常用命令

命令 功能
bt 当前 CPU 调用栈
bt -a 所有 CPU 调用栈
ps 查看所有进程状态
log 查看内核日志
kmem 查看内存信息
files 查看文件句柄
mod 查看加载的内核模块
irq 查看中断信息
runq 查看调度队列

示例:分析软锁死

less 复制代码
crash> bt -a
PID: 0      TASK: ffffffff81a9f400  CPU: 0  COMMAND: "swapper/0"
#0 [ffff88013fc03d00] schedule at ffffffff8156c6c0
#1 [ffff88013fc03d50] schedule_timeout at ffffffff8156e1d6
#2 [ffff88013fc03dd0] worker_thread at ffffffff8159dfab

(3) 分析软锁死/Hard Lockup

bash 复制代码
cat /proc/softirqs
cat /proc/interrupts

在 crash 工具中:

复制代码
irq
runq

2.4 内核调试总结流程

  1. 确认 /var/crash/ 下的 vmcore 存在。

  2. 确保对应版本的 vmlinux 调试文件。

  3. 使用 crash 打开:

    复制代码
    crash vmlinux vmcore
  4. 分析内容:

    • bt -a 检查所有 CPU 调用栈;
    • ps 检查可疑进程;
    • log 查看 panic 前的 dmesg;
    • kmem 查看内存状态。

3. 应用 core vs 内核 core 对比

特性 应用 core dump 内核 core dump (kdump/vmcore)
调试工具 gdb / coredumpctl crash / gdb
分析粒度 单进程虚拟内存、线程栈 全部 CPU、进程、内核数据结构
触发范围 应用代码 bug 驱动、内核调度、内存管理 bug
文件位置 /var/lib/systemd/coredump /var/crash/vmcore
常见大小 MB ~ 几 GB 接近物理内存大小
分析难度 中等 高,需要深入内核知识

4. 总结流程图

markdown 复制代码
             崩溃发生
                  │
         ┌────────┴─────────┐
         │                  │
  应用程序崩溃 (SIGSEGV)      Kernel Panic
         │                  │
   使用 coredumpctl           使用 kdump
         │                  │
   gdb myapp core.xxx         crash vmlinux vmcore
         │                  │
   分析线程栈/变量            分析CPU栈/调度/内存

5. 总结

  • 应用 core dump 调试:

    1. 确保 core 文件和符号文件存在。
    2. 使用 gdb 打开 gdb myapp core.xxx
    3. 核心命令:btthread apply all bt
  • 内核 core dump 调试:

    1. 启用 kdump 服务,panic 时收集 vmcore。
    2. 使用 crash vmlinux vmcore 分析。
    3. 关注所有 CPU 栈、调度、内存状态。

经验法则:

  • core.xxx.zst → 高度可能是用户态 core dump。
  • vmcore → 一定是内核 core dump。
相关推荐
wdfk_prog8 分钟前
[Linux]学习笔记系列 -- [fs]exec
linux·笔记·学习
looking_for__14 分钟前
【Linux】基础IO
linux
阿豪学编程14 分钟前
【Linux】进程间通信(IPC):从管道到共享内存
linux·运维·服务器
星环处相逢20 分钟前
Ansible-Playbook 剧本编写全攻略:从入门到进阶
linux·服务器·网络
Joren的学习记录21 分钟前
【Linux运维大神系列】docker详解(三)
linux·运维·docker
怪我冷i27 分钟前
最像 Windows 的 Linux 发行版 —— Zorin OS 18 vmware17 安装与体验
linux·ai写作
j_xxx404_1 小时前
Linux:版本控制器Git(第一章)|历史|理解Git|相关git操作|提交冲突解决
linux·运维·git·ai
Robot侠1 小时前
ROS1从入门到精通 1 :ROS1简介与环境搭建(Ubuntu 20.04 + Noetic完整指南)
linux·ubuntu·ros·机器人操作系统
纸带1 小时前
如何理解USB 配置描述符wTotalLength位运算深度
linux·网络·windows
落羽的落羽1 小时前
【C++】深入浅出“图”——图的遍历与最小生成树算法
linux·服务器·c++·人工智能·算法·机器学习·深度优先