kdump调试&分析(适用于麒麟,ubuntu等OS)

1. kdump基本原理

1.1 内核崩溃处理机制

当 Linux 系统内核发生崩溃时,通常会触发 panic,系统停止正常运行。Kdump 在这种情况下:

  1. 使用一个备用的内核(称为 crash kernel)来启动最小化的环境。
  2. 从崩溃的主内核中复制内存内容(转储文件)。
  3. 将转储文件保存到预定义的存储位置(如本地磁盘、网络服务器等)。

1.2 Crash Kernel 的作用

Kdump 的核心是依赖 Crash Kernel,这是一段预留的内存和独立的内核,用于在主内核崩溃后接管系统。

  1. 主内核崩溃后,控制权切换到 Crash Kernel。
  2. Crash Kernel 通过访问主内核的内存(物理地址)生成转储文件。

2 Kdump 的工作流程

2.1 内存预留

在系统启动时,通过内核参数(crashkernel)为 Crash Kernel 预留一部分内存(通常是 128M 或更多)。

编辑 GRUB 配置文件,添加 crashkernel 参数预留内存:

GRUB_CMDLINE_LINUX="crashkernel=256M"

2.2 Crash Kernel 加载

系统启动时,Crash Kernel 和主内核一起加载到内存中,但 Crash Kernel处于非活动状态。

2.3 触发崩溃

  • 主内核发生崩溃(如 panic)
  • 或人为触发崩溃(通过 echo c > /proc/sysrq-trigger)

2.4 Crash Kernel 启动

系统重启到 Crash Kernel 环境。
Crash Kernel 通过访问崩溃的主内核内存区域,捕获内存内容并保存。

2.5 保存转储文件

Crash Kernel 将捕获的内存转储文件(vmcore)保存到本地磁盘、NFS、或其他预定义路径。

3. Kdump 的配置

3.1 内核支持

Kdump 的关键组件是 kexec,它允许系统在内核崩溃时直接加载并启动一个新的内核(Crash Kernel)。因此,标准内核必须启用 kexec 功能。
检查是否启用了 kexec
可以通过以下命令检查是否启用了 kexec:

$ grep CONFIG_KEXEC /boot/config-$(uname -r)

CONFIG_KEXEC=y

如果没有启用,您需要重新编译内核并启用该功能,或者安装一个启用了该功能的预编译内核。
检查是否支持 crashkernel
通过检查内核配置文件(如 /boot/config-$(uname -r))确认是否启用支持:

$ grep CONFIG_CRASH_KEXEC /boot/config-$(uname -r)

CONFIG_CRASH_KEXEC=y
## 或者
CONFIG_CRASH_DUMP=y
CONFIG_CRASH_CORE=y

必须启用 CONFIG_DEBUG_INFO
CONFIG_DEBUG_INFO 配置项允许内核生成符号信息。启用此选项后,内核调试符号将被包含在内核映像中,这有助于分析 crash 工具生成的转储文件。

grep CONFIG_DEBUG_INFO /boot/config-$(uname -r)
CONFIG_DEBUG_INFO=y

3.1 下载工具

在基于 Ubuntu/Debian 或 RHEL/CentOS 的系统上,需要安装以下工具:

# Ubuntu/Debian
sudo apt install kdump-tools crash linux-crashdump

# RHEL/CentOS
sudo yum install kexec-tools crash

安装Kdump 时,弹出的GUI 界面都要选是。

3.2 确认内核参数

一般安装后,都会默认配置好内核参数。
确保grub 配置好了下面参数,如果没有配置,需要手动添加。

GRUB_CMDLINE_LINUX="crashkernel=256M"

同时另外一种确认方法是,重启后查看/proc/cmdline 中是否包含对应参数。

3.3 确认Kdump 服务是否启动

 systemctl status kdump-tools
 or
 service kdump status

如果没有启动,请正常启动它。

sudo systemctl enable kdump-tools
sudo systemctl start kdump-tools

至此就完成了对应的配置。

4. 分析kdump 生成的vmcore 文件

4.1 触发崩溃

为了测试,我们可以手动触发奔溃, 如下命令:

## 如果 sysrq 被禁用,需要手动启用它以触发内核崩溃:
#echo 1 > /proc/sys/kernel/sysrq  
echo c > /proc/sysrq-trigger

该指令会导致系统奔溃,并重启。

4.2 验证转储文件

不同系统会有不同的转储文件存储路径,我这边的机器是在下面着该路径:

ls /var/crash/202411261446
dmesg.202411261446  dump.202411261446

有dmesg 和 dump 文件, 器中dump 文件就是要分析的转储文件vmcore。 使用file 查看

$ file  dump.202411261446 
dump.202411261446: Kdump compressed dump v6, system Linux, node aa, ..., machine x86_64, domain (none)

4.3 查看vmcore 文件

crash /usr/lib/debug/boot/vmlinux-5.4.0-150-generic  /var/crash/202411261446/dump.202411261446

crash> bt # 查看栈回朔信息
crash> log #打印系统消息缓冲区,如log | tail -n 30。
crash> ps #显示进程的状态,>表示活跃的进程,如ps | grep RU。
crash> sym #转换虚拟地址为符号。
crash> dis #对给定函数或者地址进行反汇编,如dis -l [func | addr]

5. 其它

5.1 关于/proc/sys/kernel/panic

生产环境:设为 5 或 10,快速恢复。
将 /proc/sys/kernel/panic 的值设置为 0 时,系统在发生 内核 panic 后不会自动重启,而是保持崩溃状态。这种行为适用于调试和分析内核崩溃问题,因为系统会保留现场,开发人员可以查看崩溃时的内存、寄存器和其他状态信息。

调试环境:设为 0,保留崩溃现场。
将 /proc/sys/kernel/panic 的值设置为 0 时,表示 系统在发生内核 panic 后,输出 panic 相关的日志信息到控制台(如堆栈回溯、错误原因等);会等待 1 秒钟,然后自动重启。

永久设置

$ sudo nano /etc/sysctl.conf
kernel.panic = 0

#重新加载配置
$ sudo sysctl -p

5.2 关于/proc/sys/kernel/sysrq

这一功能允许系统管理员通过特定的键盘组合或命令,向 Linux 内核发出紧急命令来执行一些低级操作,如重启、同步磁盘、杀死进程等,即使系统处于某种无法正常操作的状态时也能使用。
默认情况下,Linux 系统可能会禁用这一功能,出于安全考虑或为了防止误操作。
常见的 SysRq 操作

  • Reboot (重启):Alt + SysRq + b 立即重启系统。
  • Sync (同步磁盘):Alt + SysRq + s 将所有的文件系统缓存数据同步到磁盘,防止数据丢失。
  • Unmount (卸载文件系统):Alt + SysRq + u 将所有挂载的文件系统标记为只读,确保在重新启动时不会发生数据损坏。
  • Kill (杀死进程):Alt + SysRq + k 杀死当前用户的所有进程。
  • Emergency Sync (紧急同步):Alt + SysRq + o 关闭系统并同步数据。

SysRq 级别
SysRq 的行为可以通过文件 /proc/sys/kernel/sysrq 中的值来控制。具体值如下:

  • 0:禁用 SysRq。
  • 1:启用基本的 SysRq 操作(例如重启、同步磁盘)。
  • 2:启用更多高级操作(如卸载文件系统、杀死进程)。
  • 3:启用所有 SysRq 操作,包括完整的内核调试命令等。
  • 255: 全部功能都打开;

该值的不同位域表示不同的功能:

位Bit)位置值/十进制功能描述
01允许重启系统(b)。
12允许控制控制台日志级别(0-9)。
24允许同步磁盘(s)。
38允许将文件系统切换为只读模式(u)。
416允许内存信息转储(m)。
532允许进程终止(f、k)。
664允许显示任务列表(t)。
7128允许立即关闭系统(o)。

永久设置

sudo nano /etc/sysctl.conf
kernel.sysrq = 1

#重新加载配置
$ sudo sysctl -p

这将确保 kernel.sysrq 的值在每次系统启动时都被设置为 1。

方法 2:创建一个 sysctl.d 配置文件

sudo nano /etc/sysctl.d/99-sysrq.conf
kernel.sysrq = 1
## 重新加载 sysctl 设置
sudo sysctl --system

麒麟系统位于/etc/sysctl.d/10-magic-sysrq.conf.

5.3 关于/proc/sysrq-trigger使用

使用help 帮助

echo  h > /proc/sysrq-trigger 
dmesg #查看可以输入的参数
sysrq: HELP : loglevel(0-9) reboot(b) crash(c) terminate-all-tasks(e) memory-full-oom-kill(f) kill-all-tasks(i) thaw-filesystems(j) sak(k) show-backtrace-all-active-cpus(l) show-memory-usage(m) nice-all-RT-tasks(n) poweroff(o) show-registers(p) show-all-timers(q) unraw(r) sync(s) show-task-states(t) unmount(u) force-fb(V) show-blocked-tasks(w) dump-ftrace-buffer(z) 

5.4 配置内核参数

当内核发生一些死锁,系统并不会重启,只会卡死。这种情况下并不会造成内核
panic,需要构造条件使内核panic,这样才能生成vmcore文件。
内核提供了多种场景构造panic

## 进程出现挂起时引发panic
echo 1 > /proc/sys/kernel/hung_task_panic
## 进程hangtask机制超时时间
echo 60 > /proc/sys/kernel/hung_task_timeout_secs
## 软锁(soft lockup)触发panic
echo 1 > /proc/sys/kernel/softlockup_panic
## 设置Kernel遇到OOM触发panic
echo 1 > /proc/sys/vm/panic_on_oom
## 设置内核中出现警告产生panic
echo 1 > /proc/sys/kernel/panic_on_warn

对应的sysctl.conf

kernel.hung_task_panic=1
kernel.hung_task_timeout_secs=60
kernel.softlockup_panic=1
vm.panic_on_oom=1
kernel.panic_on_warn=1
<think>好的,用户现在想了解如何使用kdump进行调试。我之前已经回答过关于ftrace的问题,现在需要转向kdump。首先,我需要回忆kdump的基本概念和它在Linux内核调试中的作用。kdump主要用于在内核崩溃时捕获内存转储,这对于分析崩溃原因非常重要。接下来,我需要考虑用户可能的背景。他们可能是系统管理员或开发人员,遇到内核崩溃的问题,需要利用kdump来获取崩溃时的内存信息。 用户的需求可能包括如何配置kdump、如何触发崩溃转储,以及如何分析生成的vmcore文件。此外,用户可能对相关的工具(如crash工具)不太熟悉,需要详细的使用步骤。我需要确保覆盖这些方面,同时提供实际的操作示例,帮助他们逐步完成配置和分析过程。 我需要检查是否有常见的配置错误或注意事项需要提及,比如内存保留问题,或者不同发行版之间的配置差异。例如,CentOSUbuntukdump配置上可能有不同的包管理工具和配置文件路径。此外,还要提醒用户在生产环境中谨慎操作,避免误触发系统崩溃。 另外,用户可能对如何分析vmcore文件感到困惑,所以需要详细说明使用crash工具的基本命令,比如如何加载内核和vmcore,如何查看堆栈跟踪、寄存器状态等。还要考虑是否提到高级分析技巧,比如查找特定符号或跟踪任务状态,但需要保持回答的简洁性,避免信息过载。 最后,我需要确保回答结构清晰,分步骤讲解,每个部分都有示例代码和解释,这样用户能够按照步骤操作。同时,注意事项和常见问题也需要突出显示,帮助用户避免常见陷阱。可能还需要对比kdump与其他调试工具(如ftrace)的不同使用场景,帮助用户理解何时使用kdump更合适。</think>#### 一、kdump 核心机制解析 ```text [崩溃转储原理] │ ├── 主内核(Production Kernel): 运行中的业务系统 └── 备内核(Crash Kernel): 保留内存区域,主内核崩溃时接管系统 ├── 内存转储触发机制 ├── /proc/vmcore 生成 └── 转储文件保存(vmcore) ``` --- #### 二、环境配置步骤 ##### 1. **内核启动参数配置** ```bash # 编辑grub配置文件(以CentOS为例) vi /etc/default/grub GRUB_CMDLINE_LINUX="crashkernel=256M" # 更新grub配置 grub2-mkconfig -o /boot/grub2/grub.cfg ``` **参数说明**: - `crashkernel=256M`:保留256MB内存用于崩溃内核 - 推荐值:物理内存≤2GB时保留128M,>2GB时保留256-512M ##### 2. **安装必要组件** ```bash # RedHat/CentOS yum install kexec-tools crash # Ubuntu/Debian apt install kdump-tools crash ``` ##### 3. **服务状态验证** ```bash systemctl status kdump # 正常输出应显示 active (exited) ``` --- #### 三、核心操作流程 ##### 1. **手动触发崩溃(测试环境)** ```bash # 方法1:SysRq触发 echo c > /proc/sysrq-trigger # 方法2:内核panic echo 1 > /proc/sys/kernel/sysrq echo o > /proc/sysrq-trigger # 立即重启(慎用!) ``` ##### 2. **转储文件定位** ```text 默认存储路径: ├── /var/crash/YYYY-MM-DD-HH:MM/vmcore └── /var/crash/YYYY-MM-DD-HH:MM/vmcore-dmesg.txt ``` ##### 3. **分析工具准备** ```bash # 安装调试符号包(示例为CentOS) debuginfo-install kernel-$(uname -r) # Ubuntu需要配置符号源 codename=$(lsb_release -cs) echo "deb http://ddebs.ubuntu.com ${codename} main restricted" > /etc/apt/sources.list.d/ddebs.list ``` --- #### 四、crash 工具深度分析 ##### 1. **基础会话启动** ```bash crash /usr/lib/debug/lib/modules/$(uname -r)/vmlinux /var/crash/.../vmcore ``` **界面示例**: ```text crash> sys KERNEL: /usr/lib/debug/lib/modules/3.10.0-1160.el7.x86_64/vmlinux DUMPFILE: /var/crash/202309011200/vmcore [PARTIAL DUMP] CPUS: 4 DATE: Mon Sep 1 12:00:45 2023 ``` ##### 2. **关键调试命令** ```text [内存分析] │ ├── bt : 显示崩溃时堆栈回溯 ├── log : 查看内核日志缓冲区 ├── kmem -i : 显示内存使用统计 └── vm -p : 进程虚拟内存分析 [进程分析] │ ├── ps : 显示所有进程状态 ├── task : 查看特定任务结构体 └── waitq : 分析等待队列 ``` ##### 3. **典型问题定位** **案例1:空指针解引用分析** ```text crash> bt -f PID: 14321 TASK: ffff88003d4d8000 CPU: 2 COMMAND: "buggy_driver" #0 [ffff88003d4d9d50] crash_kexec at ffffffff8105c7d9 #1 [ffff88003d4d9dc0] oops_end at ffffffff8152d3e8 #2 [ffff88003d4d9df0] no_context at ffffffff81053b34 #3 [ffff88003d4d9e40] __bad_area_nosemaphore at ffffffff81053e65 #4 [ffff88003d4d9e90] bad_area at ffffffff810540d3 #5 [ffff88003d4d9ec0] __do_page_fault at ffffffff81054567 #6 [ffff88003d4d9f50] do_page_fault at ffffffff81533d1e #7 [ffff88003d4d9f80] page_fault at ffffffff81530668 [exception RIP: unknown or invalid address] RIP: 0000000000000000 RSP: ffff88003d4d9f90 RFLAGS: 00010246 ``` --- #### 五、高级调试技巧 ##### 1. **符号地址解析** ```text crash> sym 0xffffffff8105c7d9 ffffffff8105c7d9 (T) crash_kexec /usr/src/debug/kernel-3.10.0/linux-3.10.0-1160.el7.x86_64/kernel/kexec_core.c: 1024 ``` ##### 2. **数据结构遍历** ```text crash> list task_struct.thread_group -s task_struct.comm,pid -h 0xffff88003d4d8000 ffff88003d4d8000 comm = "buggy_driver" pid = 14321 ``` ##### 3. **寄存器状态分析** ```text crash> irq CPU 0: No irq stack for cpu 0 CPU 1: IRQ: 0 SIE: 00000000 CIE: ffff88003f800000 CPU 2: IRQ: timer SIE: 00000008 CIE: ffff88003f800000 ``` --- #### 六、生产环境最佳实践 1. **自动化配置**: ```bash # 配置自动转储保存到NFS echo "nfs mynas:/crash_dumps" > /etc/kdump.conf ``` 2. **转储文件压缩**: ```bash # 修改kdump配置文件 core_collector makedumpfile -c --message-level 1 -d 31 ``` 3. **内存过滤策略**: ```text # /etc/kdump.conf -d 31 # 过滤页缓存等非必要内存页 ``` 4. **云环境适配**: ```bash # AWS EC2 特殊配置 echo "ext4 /dev/xvda1" > /etc/kdump.conf ``` --- #### 七、常见问题排查 ##### 问题1:crashkernel内存预留失败 **现象**: `dmesg | grep -i crash` 显示 "crashkernel reservation failed" **解决方案**: ```bash # 调整内存分配方式 crashkernel=256M,high crashkernel=128M,low ``` ##### 问题2:vmcore文件不完整 **检测方法**: ```bash makedumpfile --check /var/crash/.../vmcore ``` **修复步骤**: ```bash # 重新配置转储级别 echo "-d 31" > /etc/kdump.conf systemctl restart kdump ``` --- > **关键注意事项**: > 1. 预留内存不足时系统启动会失败,需通过控制台调整grub参数 > 2. 虚拟机环境需启用嵌套虚拟化支持 > 3. 转储文件分析需要严格匹配内核版本和调试符号 > 4. 生产环境触发崩溃前需确认业务影响范围 ```mermaid graph TD A[内核崩溃事件] --> B{kdump机制激活} B -->|成功| C[启动捕获内核] C --> D[生成vmcore] D --> E[存储到本地/NFS] E --> F[使用crash分析] B -->|失败| G[系统重启无转储] F --> H[定位错误函数] H --> I[分析寄存器状态] I --> J[检查内存泄露] ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值