当前位置: 首页 > news >正文

实战演练:用crash命令精读Kdump生成的vmcore内存快照

1. 初识Kdump与vmcore:内核崩溃的"黑匣子"

当服务器突然宕机时,最让人头疼的莫过于找不到崩溃原因。这就好比飞机失事后找不到黑匣子,让人无从查起。Kdump就是Linux内核的"黑匣子记录仪",它能在系统崩溃时自动保存内存快照(vmcore),而crash工具则是我们解读这个黑匣子的"解码器"。

我处理过不少线上崩溃案例,发现很多运维同学面对vmcore文件时常常手足无措。其实只要掌握几个关键命令,就能像侦探破案一样,从内存快照中找出系统崩溃的蛛丝马迹。典型的分析场景包括:

  • 内核Oops信息定位
  • 死锁问题排查
  • 内存泄漏分析
  • 硬件故障诊断

准备分析环境需要三个关键文件:

  1. crash工具:通过yum/apt直接安装
  2. vmcore文件:通常位于/var/crash目录
  3. 带调试信息的内核镜像:建议从发行版官网下载kernel-debuginfo包
# 安装crash工具(CentOS示例) yum install crash -y # 下载调试符号包 debuginfo-install kernel-$(uname -r)

2. 启动分析:进入crash的侦探模式

第一次打开vmcore时,那种感觉就像侦探初次勘察案发现场。执行以下命令即可进入分析环境:

crash /usr/lib/debug/lib/modules/$(uname -r)/vmlinux /var/crash/xxx/vmcore

成功加载后,你会看到类似这样的现场信息:

KERNEL: /boot/vmlinux-3.10.0-1160.el7.x86_64 DUMPFILE: /var/crash/127.0.0.1-2023-07-15-14:22:33/vmcore CPUS: 8 DATE: Sat Jul 15 14:22:33 2023 UPTIME: 18:45:21 LOAD AVERAGE: 0.52, 0.58, 0.59 TASKS: 687 NODENAME: web-server-01 PANIC: "BUG: unable to handle kernel NULL pointer dereference at 0000000000000050"

这里特别要注意PANIC行,它直接告诉我们内核遇到了空指针解引用错误。但具体是哪个模块、哪行代码导致的,还需要深入调查。

3. 基础侦查:五大核心命令实战

3.1 bt命令:回溯犯罪现场

bt(backtrace)是我的第一个必用命令,它能显示崩溃时的调用栈。就像查看监控录像的回放功能,让我们看到崩溃前内核的执行路径。

crash> bt PID: 16824 TASK: ffff88003d8a8000 CPU: 5 COMMAND: "nginx" #0 [ffff88003d8a7c58] crash_kexec at ffffffff810e27e2 #1 [ffff88003d8a7d28] panic at ffffffff81689948 #2 [ffff88003d8a7d50] oops_end at ffffffff81689948 #3 [ffff88003d8a7d78] no_context at ffffffff816793f1 #4 [ffff88003d8a7dc8] __bad_area_nosemaphore at ffffffff81679487 #5 [ffff88003d8a7e10] bad_area_nosemaphore at ffffffff816795f1 #6 [ffff88003d8a7e20] __do_page_fault at ffffffff8168c6ce #7 [ffff88003d8a7e80] do_page_fault at ffffffff8168c863 #8 [ffff88003d8a7ea8] page_fault at ffffffff81688b48 [exception RIP: nginx_http_handler+0x150] RIP: ffffffffc0762150 RSP: ffff88003d8a7f58 RFLAGS: 00010246

关键线索在RIP寄存器值(ffffffffc0762150),它指向导致崩溃的指令地址。注意最后的nginx_http_handler+0x150,说明问题出在nginx内核模块。

3.2 dis命令:反汇编凶器代码

有了地址线索后,用dis命令反汇编相关代码:

crash> dis -l nginx_http_handler+0x150 5 0xffffffffc0762150 <nginx_http_handler+336>: mov 0x50(%rbx),%rax 0xffffffffc0762154 <nginx_http_handler+340>: test %rax,%rax 0xffffffffc0762157 <nginx_http_handler+343>: je 0xffffffffc07621a0 0xffffffffc0762159 <nginx_http_handler+345>: mov (%rax),%rdx 0xffffffffc076215c <nginx_http_handler+348>: mov %rdx,0x18(%rsp)

这里清楚显示崩溃发生在mov 0x50(%rbx),%rax指令,试图从RBX寄存器+0x50的位置读取数据,但RBX此时为NULL。这就是典型的空指针解引用问题。

3.3 log命令:查看系统日志

log命令相当于查看案发现场的监控日志:

crash> log | tail -20 [ 3452.671234] nginx: module verification failed: signature and/or required key missing - tainting kernel [ 3452.671345] nginx: loading out-of-tree module taints kernel. [ 3452.671456] nginx: module license 'Proprietary' taints kernel. [ 3452.671567] BUG: unable to handle kernel NULL pointer dereference at 0000000000000050 [ 3452.671678] IP: [<ffffffffc0762150>] nginx_http_handler+0x150/0x320 [nginx] [ 3452.671789] PGD 3d8a80067 PUD 3d8a81067 PMD 0 [ 3452.671900] Oops: 0000 [#1] SMP [ 3452.672011] Modules linked in: nginx(OE) vhost_net vhost tap...

日志验证了我们的发现,还显示nginx模块是未经签名的第三方模块(taints kernel),这往往是稳定性问题的根源。

3.4 ps命令:排查涉案进程

ps命令可以查看崩溃时的进程状态:

crash> ps | grep nginx 16824 16823 5 ffff88003d8a8000 RU 0.3 120384 24576 nginx 16825 16824 3 ffff88003d8a9000 RU 0.2 119872 20480 nginx 16826 16824 7 ffff88003d8aa000 RU 0.2 119872 20480 nginx

RU状态的进程是崩溃时的活跃进程。结合之前的分析,可以确定是nginx工作进程16824号触发了内核崩溃。

3.5 struct命令:查看数据结构

最后用struct命令检查相关数据结构:

crash> struct nginx_http_ctx ffff88003d8a8000 struct nginx_http_ctx { req = 0x0, resp = 0xffff88003d8a8120, backend = 0xffff88003d8a8200, ... }

这里req指针为NULL,而崩溃代码正尝试访问req->header_len(偏移0x50处),完美印证了我们的推断。

4. 高级侦查:内存与模块分析

4.1 kmem命令:检查内存健康

当怀疑内存问题时,kmem是首选工具:

crash> kmem -i PAGES TOTAL PERCENTAGE TOTAL MEM 511276 2 GB FREE 506631 1.9 GB 99% of TOTAL MEM USED 4645 18.1 MB 0% of TOTAL MEM SLAB 1930 7.5 MB 0% of TOTAL MEM

重点关注SLAB内存使用情况,异常增长可能预示内存泄漏:

crash> kmem -s CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE kmalloc-8192 8192 128 256 32 32k kmalloc-4096 4096 512 1024 64 16k nginx_ctx_cache 256 2048 2048 32 8k <-- 异常增长

4.2 mod命令:检查内核模块

对于模块相关的问题,mod命令必不可少:

crash> mod ffffffffc0762000 nginx 12740 /var/lib/nginx/nginx.ko ffffffffc07a8000 faulty 8765 /lib/modules/faulty.ko

特别注意标记为(OE)的模块,表示它们是Out-of-tree模块,稳定性风险较高。

4.3 files命令:查看打开文件

当怀疑文件描述符泄漏时:

crash> files 16824 PID: 16824 COMMAND: "nginx" ROOT: / CWD: /var/log/nginx FD FILE DENTRY INODE TYPE PATH 0 ffff88003d8a7000 ffff88003d8a7120 ffff88003d8a7240 CHR /dev/null 1 ffff88003d8a7000 ffff88003d8a7120 ffff88003d8a7240 CHR /dev/null 2 ffff88003d8a7000 ffff88003d8a7120 ffff88003d8a7240 CHR /dev/null 3 ffff88003d8a8000 ffff88003d8a8120 ffff88003d8a8240 SOCK 4 ffff88003d8a9000 ffff88003d8a9120 ffff88003d8a9240 REG /var/log/nginx/access.log ... 1023 ffff88003d8af000 ffff88003d8af120 ffff88003d8af240 REG /var/lib/nginx/cache.data

5. 实战案例:OOM杀手事件分析

最近遇到一个典型案例:服务器频繁重启,vmcore显示是被OOM Killer终止。用以下命令组合快速定位:

crash> log | grep -i oom [ 6852.123456] Out of memory: Kill process 18921 (java) score 789 or sacrifice child crash> ps 18921 PID: 18921 TASK: ffff88003d8b0000 CPU: 3 COMMAND: "java" %MEM: 78.9 VSZ: 32168472 RSS: 25321472 crash> kmem -i PAGES TOTAL PERCENTAGE TOTAL MEM 511276 2 GB FREE 1024 4 MB 0% of TOTAL MEM USED 510252 1.99 GB 99% of TOTAL MEM

结合vm命令查看进程内存使用细节:

crash> vm 18921 PID: 18921 TASK: ffff88003d8b0000 COMMAND: "java" MM PGD RSS TOTAL_VM ffff88003d8b1000 ffff88003d8b2000 25321472 32168472 VMA START END FLAGS FILE ffff88003d8b3000 00400000 01400000 8001875 ffff88003d8b4000 01400000 01c00000 8000871 /usr/lib/jvm/java-11-openjdk/lib/server/classes.jsa ...

最终发现是Java进程内存泄漏导致。通过这几个命令的组合使用,不到10分钟就定位到了根本原因。

http://www.gsyq.cn/news/1601509.html

相关文章:

  • Shimmy:4.8MB的Rust原生AI推理引擎,如何重塑边缘计算与本地大模型应用生态
  • Cadence SPB17.4 Allegro:从单孔到阵列,高效过孔放置全攻略
  • Java计算机毕设之基于 SpringBoot 的个人音乐收藏平台设计与开发 在线音乐点播管理系统的设计与实现(完整前后端代码+说明文档+LW,调试定制等)
  • OneMore插件:重新定义OneNote笔记效率的革命性工具
  • AMD Ryzen处理器深度调试:从硬件工程师视角掌握系统管理单元
  • Linux 网络协议栈调优:从内核参数到零拷贝
  • GPT-5首批17家灰度合作伙伴技术简报解密(含非公开latency benchmark、function calling失败率热力图与fallback降级策略)
  • Minecraft Region Fixer终极指南:快速修复你的损坏世界文件
  • AirPodsDesktop:让Windows用户也能享受苹果生态的完整耳机体验
  • 如何在一台电脑上实现多人游戏:终极免费分屏解决方案指南
  • 开源游戏兼容性修复工具终极指南:让老游戏在现代Windows系统完美运行
  • JMeter性能测试从零到一:环境搭建、脚本编写与实战避坑指南
  • Performance-Fish终极指南:三步让你的RimWorld告别卡顿
  • 3步搞定Windows和Office永久激活:KMS智能激活完整指南
  • DataGrip之一个提升SQL可读性的格式化模板,速来收藏
  • Unity Mod Manager:重新定义Unity游戏模组管理的技术解决方案
  • 3步解锁RPG Maker MV加密资源:免费网页工具让你的游戏素材触手可及
  • 终极指南:如何使用apt-offline实现离线包管理
  • 280 美元的 TMD 链条锁值不值?优缺点大揭秘!
  • Magics新手避坑指南:从界面汉化到核心编辑(设置、布局、缩放与拉伸)
  • 3D打印革命:SketchUp STL插件完整使用指南
  • TLV320AIC3105音频编解码器:架构、配置与工程实践全解析
  • 【联邦学习实战】混合加密FedAvg:从Paillier同态加密到差分隐私的工程化部署
  • 深入剖析Prometheus时序冲突:从重复样本与无序时间戳的根源到精准排查
  • 2026免费图片去水印工具推荐:在线电脑手机全覆盖,无广告免费图片去水印网站、安卓iOS手机免费去水印APP合集
  • Python+半导体数据工具完整自学路线(零基础→实战)
  • 京东抢购助手:3步实现Python自动化抢单的终极指南
  • TMP821两相无刷电机驱动芯片实战:锁相检测与速度传感应用指南
  • FFmpeg 4.4实战:剖析MP4文件AES-CTR加密与流式加密的配置差异与避坑指南
  • 鸣潮自动化助手ok-ww:5分钟掌握智能后台挂机全攻略