0

0

Linux 内核 panic 后如何从 vmcore 里提取关键调用栈信息

冰川箭仙

冰川箭仙

发布时间:2026-01-18 13:43:02

|

256人浏览过

|

来源于php中文网

原创

内核panic后用crash解析vmcore需四步:先确认vmcore与带符号vmlinux匹配;再用bt -a和log定位触发点;接着用rd/dis查寄存器与反汇编聚焦崩溃现场;最后结合ps/lock/log分析进程、锁及RCU上下文。

linux 内核 panic 后如何从 vmcore 里提取关键调用栈信息

内核 panic 发生后,若已配置 kdump 并成功捕获 vmcore(通常位于 /var/crash/ 下),就可以用 crash 工具解析它,快速定位崩溃时的调用、触发函数和上下文。关键不是“能不能看”,而是“看哪几处最有效”。

确认 vmcore 和 vmlinux 匹配

vmcore 本身不带符号信息,必须搭配对应版本、带调试符号的 vmlinux(不是 /boot/vmlinuz-xxx)才能解析函数名和行号。常见错误是用错内核版本或缺少 debuginfo 包。

  • 检查 vmcore 对应的内核版本:file /var/crash/*/vmcore | grep "Linux version"
  • 查找匹配的 vmlinux:CentOS/RHEL 用 debuginfo-install kernel-$(uname -r);Ubuntu/Debian 安装 linux-image-$(uname -r)-dbgsym 包,vmlinux 通常在 /usr/lib/debug/boot/vmlinux-$(uname -r)
  • 验证是否可用:crash /usr/lib/debug/boot/vmlinux-$(uname -r) /var/crash/*/vmcore —— 若无报错且进入交互界面,说明匹配成功

快速定位 panic 触发点:bt -a 和 log

bt -a(backtrace all)列出所有 CPU 的完整调用栈,panic 通常发生在其中一个 CPU 上,重点看标记为 CRASH 或处于 die/oops_enter 调用链中的线程。

  • 执行 bt -a,扫描各 CPU 栈底(最顶层)是否出现 panicdo_exit__warndie 等函数
  • 运行 log 查看内核日志缓冲区内容,常含 panic 前最后一句提示,例如 "Kernel panic - not syncing: Fatal exception" 或具体原因如 "Unable to handle kernel NULL pointer dereference"
  • 若看到 BUG: unable to handle kernel paging request,结合 bt 中出问题的栈帧,再用 dis -l 反汇编对应代码行

聚焦崩溃现场:查看寄存器与内存状态

调用栈只能告诉你“谁调了谁”,但真正原因常藏在寄存器值或非法内存访问地址里。

LobeHub
LobeHub

LobeChat brings you the best user experience of ChatGPT, OLLaMA, Gemini, Claude

下载
  • bt 输出中找到疑似出问题的栈帧(比如包含驱动名、模块名或 __do_faultmemcpy 等敏感函数),记下其地址(如 #5 []
  • 执行 rd -s $pc 10dis -l ffffffff8123abcd 查看该指令附近源码行(需 vmlinux 符号完整)
  • 若 panic 提示访问了非法地址(如 IP: ),用 sym 查该地址是否属于某个模块,再用 mod -s 检查模块加载状态和符号表

辅助判断:检查进程上下文与锁状态

很多 panic 源于中断上下文误睡、死锁或 RCU stall,需结合上下文交叉验证。

  • ps -m 查看所有进程状态,关注标记为 UN(uninterruptible)或 RU(running in kernel)的进程,尤其是持有锁或刚唤醒的
  • 运行 lock 查当前持有的自旋锁或 mutex,配合 bt 看是否多个 CPU 卡在同一锁上
  • 若怀疑 RCU 问题,执行 rd -f cpu#0 __rcu_pending 或查看 log 中是否有 "INFO: rcu_preempt detected stalls"

解析 vmcore 不依赖复杂工具链,核心是找准入口(bt -a + log)、对齐符号(vmlinux)、验证地址(sym/rd/dis),再结合上下文缩小范围。多数硬件驱动、内存越界、锁误用类 panic,靠这四步就能锁定 root cause。

相关专题

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

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

231

2023.09.22

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

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

436

2024.03.01

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

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

231

2023.09.22

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

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

436

2024.03.01

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

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

391

2023.07.18

堆和栈区别
堆和栈区别

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

572

2023.08.10

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

481

2023.08.10

磁盘配额是什么
磁盘配额是什么

磁盘配额是计算机中指定磁盘的储存限制,就是管理员可以为用户所能使用的磁盘空间进行配额限制,每一用户只能使用最大配额范围内的磁盘空间。php中文网为大家提供各种磁盘配额相关的内容,教程,供大家免费下载安装。

1349

2023.06.21

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

65

2026.01.16

热门下载

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

精品课程

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

共48课时 | 7.3万人学习

Git 教程
Git 教程

共21课时 | 2.8万人学习

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

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