一文搞懂应用程序 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。
相关推荐
云飞云共享云桌面2 小时前
1台电脑10个画图设计用怎么实现
linux·运维·服务器·网络·数据库·自动化·电脑
小MarkK2 小时前
[Ubuntu][mount]ubuntu电脑挂载新硬盘
linux·ubuntu·电脑·mount·硬盘挂载
艾莉丝努力练剑2 小时前
【Linux】初始Linux:从计算机历史发展、操作系统历史脉络的角度详谈Linux相关的话题,附Linux安装和用户创建(环境准备)详解
linux·运维·服务器·经验分享
l1t2 小时前
how to build tbox xml into the demo
xml·linux·c语言·parser·tbox
努力学习的小廉2 小时前
深入了解linux系统—— 线程池
linux·运维·服务器
不是编程家3 小时前
Linux第十五讲:Socket编程UDP
linux·运维·udp
UrSpecial3 小时前
Linux线程
linux·开发语言·c++
格林威3 小时前
Linux使用-MySQL的使用
linux·运维·人工智能·数码相机·mysql·计算机视觉·视觉检测
程序员TNT3 小时前
Shoptnt 促销计算引擎详解:策略模式与责任链的完美融合
linux·windows·策略模式