调试 应用程序 core dump 和 内核 core dump (kdump/vmcore) 需要完全不同的工具链和流程。下面我从 原理 → 准备工作 → 调试流程 → 典型场景 全面讲解。
1. 应用程序 core dump 调试
应用程序 core dump 是指 用户态进程 崩溃后生成的内存镜像,常见原因有
SIGSEGV
、SIGABRT
等。
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,需要打开 -
临时启用:
bashulimit -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 dumpxmlgcore <pid>
-
valgrind
:检测内存越界、内存泄漏inivalgrind --leak-check=full ./myapp
1.4 应用 core dump 调试总结流程
-
确认 core 文件存在,使用
coredumpctl
或/proc/sys/kernel/core_pattern
检查。 -
确认可执行文件和符号包完整。
-
gdb myapp core.xxx
进入调试。 -
重点分析:
- 崩溃线程调用栈
bt
- 线程间死锁问题
thread apply all bt
- 检查局部变量、内存
- 崩溃线程调用栈
-
根据源码或逻辑定位 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 配置与收集
-
安装 kdump 组件
zypper install kdump crash
-
启用 kdump 服务
bashsystemctl enable kdump systemctl start kdump
-
配置
/etc/kdump.conf
csspath /var/crash core_collector makedumpfile -c --message-level 1 -d 31
-
触发 panic 测试
bashecho 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 内核调试总结流程
-
确认
/var/crash/
下的 vmcore 存在。 -
确保对应版本的
vmlinux
调试文件。 -
使用
crash
打开:crash vmlinux vmcore
-
分析内容:
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 调试:
- 确保 core 文件和符号文件存在。
- 使用
gdb
打开gdb myapp core.xxx
。 - 核心命令:
bt
、thread apply all bt
。
-
内核 core dump 调试:
- 启用 kdump 服务,panic 时收集 vmcore。
- 使用
crash vmlinux vmcore
分析。 - 关注所有 CPU 栈、调度、内存状态。
经验法则:
- core.xxx.zst → 高度可能是用户态 core dump。
- vmcore → 一定是内核 core dump。