0

0

Linux: 深入探讨KDUMP,内核崩溃调试利器

爱谁谁

爱谁谁

发布时间:2025-07-21 11:26:02

|

779人浏览过

|

来源于php中文网

原创

kdump在linux内核中是一个关键功能,用于在系统崩溃时生成内存转储(core dump)。这对于系统管理员和开发人员来说,分析和调试系统崩溃问题至关重要。本文将详细介绍kdump的工作原理、配置方法以及在实际操作中的应用。

一、KDUMP的工作原理 KDUMP利用了kexec机制,使得在内核崩溃后能够直接加载并运行一个新的内核,而无需通过BIOS或固件重新启动系统。KDUMP的主要步骤如下:

预配置崩溃内核(crash kernel):在系统正常运行时,预先分配一部分内存用于崩溃内核。 系统崩溃时切换内核:当主内核发生崩溃时,通过kexec机制加载并启动预先配置的崩溃内核。 生成内存转储:崩溃内核启动后,使用kdump工具生成内存转储文件,并将其保存到预先配置的位置(如本地磁盘、NFS共享或远程服务器)。

Linux: 深入探讨KDUMP,内核崩溃调试利器

二、KDUMP的配置 配置KDUMP主要包括以下几个步骤:

  1. 安装KDUMP工具 在大多数Linux发行版中,KDUMP工具可以通过包管理器安装,例如在CentOS或RHEL中:
sudo yum install kexec-tools
  1. 配置内核参数 编辑GRUB配置文件,添加crashkernel参数以预留内存。例如,在/etc/default/grub文件中:
GRUB_CMDLINE_LINUX="crashkernel=128M"

更新GRUB配置:

sudo grub2-mkconfig -o /boot/grub2/grub.cfg
  1. 配置KDUMP服务 编辑KDUMP配置文件/etc/kdump.conf,指定内存转储文件的保存位置:
path /var/crash

启动并启用KDUMP服务:

sudo systemctl start kdump
sudo systemctl enable kdump

三、验证KDUMP配置 为了验证KDUMP是否正确配置,可以手动触发系统崩溃:

echo c > /proc/sysrq-trigger

系统将会崩溃并重启,KDUMP服务会生成内存转储文件,可以在配置的保存位置查看生成的转储文件。

四、分析内存转储文件 生成的内存转储文件可以使用crash工具进行分析。crash工具提供了一个交互式的命令行界面,用于查看内核数据结构、栈跟踪等信息。

安装crash工具:

陌言AI
陌言AI

陌言AI是一个一站式AI创作平台,支持在线AI写作,AI对话,AI绘画等功能

下载
sudo yum install crash

使用crash工具加载内存转储文件和调试符号文件:

sudo crash /usr/lib/debug/lib/modules/$(uname -r)/vmlinux /var/crash/2023-06-24-10\:00/vmcore

crash工具中,可以使用各种命令查看内存转储文件的详细信息。

logbt命令是两个非常重要的命令。log命令用于查看内核日志,而bt命令用于查看崩溃时的栈跟踪信息。以下是这两个命令的详细介绍及示例。

4.1 log命令 log命令用于显示内核的日志信息,这些日志记录了系统运行过程中发生的各种事件,包括错误、警告和信息性消息。查看内核日志可以帮助我们了解系统崩溃前发生了哪些重要事件。

4.1.1 示例: 假设我们在crash工具中输入log命令,输出可能如下:

crash> log
[   0.000000] Initializing cgroup subsys cpuset
[   0.000000] Initializing cgroup subsys cpu
[   0.000000] Initializing cgroup subsys cpuacct
[   0.000000] Linux version 3.10.0-957.21.3.el7.x86_64 (mockbuild@kbuilder.bsys.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) ) #1 SMP Tue May 14 21:24:45 UTC 2019
...
[  15.625908] SELinux:  Disabled at runtime.
[  15.625914] SELinux:  Unregistering netfilter hooks
[  15.631763] type=1404 audit(1621513042.185:2): selinux=0 auid=4294967295 ses=4294967295
[  15.632076] systemd[1]: Successfully loaded SELinux policy in 13.217130ms.
...
[ 1183.443830] BUG: unable to handle kernel NULL pointer dereference at 0000000000000010
[ 1183.444069] IP: [] __wake_up_common+0x2f/0x80
[ 1183.444332] PGD 0 
[ 1183.444404] Oops: 0002 [#1] SMP 
[ 1183.444529] Modules linked in: ip_tables xfs libcrc32c sd_mod crc_t10dif crct10dif_generic sr_mod cdrom crct10dif_pclmul crct10dif_common crc32_pclmul ghash_clmulni_intel aesni_intel glue_helper lrw gf128mul ablk_helper cryptd serio_raw ahci libahci libata tg3 libphy dm_mirror dm_region_hash dm_log dm_mod
...
[ 1183.447114] RIP  [] __wake_up_common+0x2f/0x80
[ 1183.447369] RSP 
[ 1183.447463] CR2: 0000000000000010
[ 1183.447560] ---[ end trace 19da2b7b7a6f3c54 ]---

4.1.2 讲解: 内核日志初始化:日志开头部分记录了内核子系统的初始化过程。 SELinux信息:中间部分记录了SELinux的状态变更及相关的系统消息。 错误信息:日志的关键部分在最后几行,记录了系统发生BUG的详细信息,包括无法处理的空指针引用错误(unable to handle kernel NULL pointer dereference)、相关的IP地址、模块信息等。 内核调用栈:日志中还包含了错误发生时的内核调用栈信息(RIPRSP等),这些信息对于定位错误源非常有用。

4.2 bt命令 bt命令用于显示崩溃时的栈跟踪(Backtrace)信息,通过栈跟踪可以了解程序在崩溃时的调用链,从而帮助定位问题的根源。

4.2.1 示例: 假设我们在crash工具中输入bt命令,输出可能如下:

crash> bt
PID: 1234   TASK: ffff8801184c0000  CPU: 1   COMMAND: "echo"
 #0 [ffff8801184c3a68] __wake_up_common at ffffffff810dffef
 #1 [ffff8801184c3a98] __wake_up at ffffffff810e0038
 #2 [ffff8801184c3ab8] complete at ffffffff810e3f20
 #3 [ffff8801184c3ad8] i915_gem_object_set_to_gtt_domain at ffffffffa00c872f [i915]
 #4 [ffff8801184c3b08] i915_gem_object_pin_to_display_plane at ffffffffa00c905e [i915]
 #5 [ffff8801184c3b48] intel_prepare_plane_fb at ffffffffa00fa98b [i915]
 #6 [ffff8801184c3b78] drm_atomic_helper_prepare_planes at ffffffffa003eabc [drm_kms_helper]
 #7 [ffff8801184c3ba8] drm_atomic_helper_commit_planes at ffffffffa003eb0f [drm_kms_helper]
 #8 [ffff8801184c3bc8] drm_atomic_commit_tail at ffffffffa004049f [drm_kms_helper]
 #9 [ffff8801184c3c08] commit_tail at ffffffffa00a4f13 [i915]
#10 [ffff8801184c3c38] intel_atomic_commit at ffffffffa00a5df3 [i915]
#11 [ffff8801184c3c68] drm_atomic_commit at ffffffffa003f0b0 [drm_kms_helper]
#12 [ffff8801184c3c98] drm_atomic_connector_commit_dpms at ffffffffa003c8ec [drm_kms_helper]
#13 [ffff8801184c3cc8] drm_mode_obj_set_property_ioctl at ffffffffa002c518 [drm]
#14 [ffff8801184c3d08] drm_ioctl at ffffffffa00207b0 [drm]
#15 [ffff8801184c3d48] do_vfs_ioctl at ffffffff8121f4a8
#16 [ffff8801184c3db8] sys_ioctl at ffffffff8121f822
#17 [ffff8801184c3e18] system_call_fastpath at ffffffff8168ec19
    RIP: 00007f7b59140f07  RSP: 00007ffd4a2e2c38  RFLAGS: 00000246
    RAX: 0000000000000010  RBX: 0000000000000000  RCX: ffffffffffffffff
    RDX: 00007ffd4a2e2c60  RSI: 00000000400464ab  RDI: 0000000000000009
    RBP: 00007ffd4a2e2c60   R8: 0000000000000000   R9: 0000000000000000
    R10: 0000000000000000  R11: 0000000000000246  R12: 0000000000000000
    R13: 0000000000000000  R14: 0000000000000000  R15: 0000000000000000
    ORIG_RAX: 0000000000000010  CS: 0033  SS: 002b

4.2.2 讲解: 任务信息:显示了进程ID(PID)、任务结构地址(TASK)、CPU编号及进程名称(COMMAND)。 调用栈信息:每一行代表一次函数调用,从底部到顶部依次是从当前函数到最初函数的调用顺序。比如: #0:当前函数__wake_up_common在地址ffffffff810dffef#1:调用了__wake_up函数。 #2:然后调用了complete函数,以此类推。 寄存器信息:底部显示了系统调用的快速路径信息,包括各个寄存器的值(如RIP、RSP、RAX等),这些信息对于调试非常重要。

五、KDUMP的实际应用 KDUMP在生产环境中应用广泛,尤其是在需要高可用性和快速故障排除的系统中。以下是一些实际应用场景:

服务器集群:在服务器集群中,KDUMP可以帮助快速定位和解决内核崩溃问题,减少系统停机时间。 嵌入式系统:在嵌入式设备中,KDUMP可以用于捕获和分析偶发的内核崩溃,帮助提高系统稳定性。 开发测试环境:在开发和测试环境中,KDUMP可以帮助开发人员调试内核模块和驱动程序,快速发现和修复问题。

六、结论 KDUMP是Linux系统中一个强大而实用的工具,对于提高系统稳定性和故障排除能力具有重要意义。通过正确配置和使用KDUMP,系统管理员和开发人员可以有效地捕获和分析内核崩溃信息,从而快速解决系统问题,确保系统的高可用性和可靠性。

相关专题

更多
c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

232

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

437

2024.03.01

treenode的用法
treenode的用法

​在计算机编程领域,TreeNode是一种常见的数据结构,通常用于构建树形结构。在不同的编程语言中,TreeNode可能有不同的实现方式和用法,通常用于表示树的节点信息。更多关于treenode相关问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

536

2023.12.01

C++ 高效算法与数据结构
C++ 高效算法与数据结构

本专题讲解 C++ 中常用算法与数据结构的实现与优化,涵盖排序算法(快速排序、归并排序)、查找算法、图算法、动态规划、贪心算法等,并结合实际案例分析如何选择最优算法来提高程序效率。通过深入理解数据结构(链表、树、堆、哈希表等),帮助开发者提升 在复杂应用中的算法设计与性能优化能力。

17

2025.12.22

深入理解算法:高效算法与数据结构专题
深入理解算法:高效算法与数据结构专题

本专题专注于算法与数据结构的核心概念,适合想深入理解并提升编程能力的开发者。专题内容包括常见数据结构的实现与应用,如数组、链表、栈、队列、哈希表、树、图等;以及高效的排序算法、搜索算法、动态规划等经典算法。通过详细的讲解与复杂度分析,帮助开发者不仅能熟练运用这些基础知识,还能在实际编程中优化性能,提高代码的执行效率。本专题适合准备面试的开发者,也适合希望提高算法思维的编程爱好者。

21

2026.01.06

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

392

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

572

2023.08.10

空指针异常处理
空指针异常处理

本专题整合了空指针异常解决方法,阅读专题下面的文章了解更多详细内容。

22

2025.11.16

AO3中文版入口地址大全
AO3中文版入口地址大全

本专题整合了AO3中文版入口地址大全,阅读专题下面的的文章了解更多详细内容。

1

2026.01.21

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Rust 教程
Rust 教程

共28课时 | 4.7万人学习

PostgreSQL 教程
PostgreSQL 教程

共48课时 | 7.5万人学习

Git 教程
Git 教程

共21课时 | 2.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号