庖丁解CORE · 初见全牛:vmcore前世今生 庖丁解CORE · 第一篇 初见全牛vmcore 是什么从哪里来庖丁始解牛时所见无非全牛。三年之后未尝见全牛也。——《庄子·养生主》初学者打开一个 vmcore往往被它的体量震慑——动辄数 GB文件类型标注 ELFfile命令返回的是core file却和应用程序的 core dump 截然不同。你不知道它从何而来也不知道里面藏着什么。这就是庖丁最初所见一头完整的、令人茫然的全牛。本文将讲清楚三件事vmcore 是什么、它如何被生成、影响它质量的关键参数与常见故障。文章也顾及了架构差异x86_64 与 ARM64会在相关环节单独说明。一、vmcore 内容及格式1.1 vmcore 是什么vmcore 是 Linux 内核在崩溃瞬间的内存快照以 ELF 格式存储。更准确地说它是一个经过筛选的内存转储包含内核崩溃时所有 CPU 的寄存器状态通过 ELF PT_NOTE 段存储内核使用的物理内存页按过滤级别选择性保留vmcore-dmesg崩溃前的内核日志缓冲区它不是完整的物理内存镜像用户态进程内存默认被过滤掉应用程序的 core dump那是单个进程的地址空间快照实时系统状态它是崩溃那一刻的冻结帧之后的一切都不存在1.2 vmcore 的常见存储形式根据其获取与生成方式、数据过滤程度以及应用场景的不同业界主要将其划分为以下六大核心类型完整内存转储 (Full Dump)最原始、最完整的转储方式。它不经过任何过滤直接将系统崩溃瞬间的全部物理内存数据全量写入存储。其优点在于保留了百分之百的内存现场包括所有的用户态、内核态数据及缓存信息最为完整缺点是体积庞大与物理内存大小等同在数百 GB 或 TB 级大内存服务器上采集与写盘时间极长。kdump 压缩转储 (Compressed Dump)目前生产环境最常用的标准格式通常由 makedumpfile 配合 kdump 生成。它在捕获阶段对内存数据进行压缩支持 zlib、lzo、lz4、zstd 等算法并在保留核心内核元数据的同时过滤掉无关数据极大地节省了磁盘空间提升了转储效率。makedumpfile 过滤转储 (Filtered Dump)通过特定的过滤规则如 high、low 或自定义级别有选择地剥离掉对内核调试无用的数据页例如零页、用户态进程数据、文件缓存等。这使得生成的 vmcore 体积显著减小兼顾了快速落盘与核心内核现场的保留。远程传输转储 (Remote Dump)适用于本地磁盘空间不足或无盘服务器。捕获内核通过网络协议如 NFS、SSH、Netcat、TFTP 等将转储数据实时流式传输到远程存储服务器。其不依赖本地存储但转储成功率受制于网络架构的稳定性。分区转储 (Partial Dump)在极端或受限场景下仅捕获指定的一部分物理内存范围或只读取特定的物理内存区域。其体积极小、捕获极快但由于丢弃了大量内存数据无法进行全栈的深度死锁和链路还原。dmesg / vmcore-dmesg (日志提取)这是一种极其轻量级的降级转储。它仅保存并提取内核崩溃前的 dmesg 环形缓冲区日志Log Buffer。它几乎不占用空间在无法生成完整 core 的极端硬件故障场景下作为纯文本提供最后的线索但无法进行寄存器、内存块等高级调试。此外在虚拟化平台如 KVM/QEMU、VMware ESXi上根据崩溃主体的不同Host 崩溃、Guest 内部 panic、或者通过宿主机 virsh dump/QEMU Monitor 强行导出的物理镜像vmcore 还会衍生出虚拟机内核 ELF 镜像和宿主机层面的 Raw 原始镜像等形态。1.3 ELF 格式的 vmcore 内部结构综述ELF 格式的 vmcore 是 Linux 标准转储体系kdump的核心产物。它严格遵循标准的 64 位 Executable and Linkable Format (ELF64) 规范将崩溃瞬间的物理内存空间映射、CPU 寄存器状态以及内核元数据组织成一个标准化、可被 crash、gdb 等工具直接解析的核心转储文件ET_CORE 类型。标准 ELF64 规范的通用度堪称现代计算底座的硬通货。它超越了物理硬件的藩篱在 x86_64、ARM64、RISC-V 乃至 LoongArch 等截然不同的芯片架构之间构建了一套高度统一的二进制格式标准。从磁盘上的可执行程序、运行时的动态链接库到内核动态加载的 .ko 驱动模块直至系统崩溃瞬间凝固的 vmcore 转储现场皆由同一套Elf64_Ehdr和Elf64_Phdr结构体作为其元数据骨架实际存储时可能包含 makedumpfile 私有头。这种将通用的数据外壳与异构的体系现场完美分离的解耦设计使得 ELF64 成为纵穿操作系统从编译到崩溃、横跨所有主流处理器架构的内核转储通用语言。其内部拓扑结构由外至内主要由以下四个关键部件无缝交织构成------------------------------------------------------------------------ | 1. ELF Header (ELF头部) | | - 标识魔数(e_ident)、机器架构(e_machine: x86_64/AARCH64)、e_phoff 等 | ------------------------------------------------------------------------ | 2. Program Header Table (PHT / 程序头表) | | - 整个文件的索引总纲描述并指向所有 PT_NOTE 与 PT_LOAD 段的物理偏移| ------------------------------------------------------------------------ | 3. PT_NOTE Segment (元数据元段) | | ---------------------------------------------------------------- | | | NT_PRSTATUS : 捕获崩溃瞬间每个 CPU 核心的通用寄存器快照 | | | | (x86_64: RIP/RSP/CR3; ARM64: PC/SP/TTBR0/1) | | | ---------------------------------------------------------------- | | | NT_VMCOREINFO : 存放内核符号(如 init_task)、KASLR 偏移、页表 | | | | 级数、内核版本等关键调试索引的“黑盒子” | | | ---------------------------------------------------------------- | | | NT_AUXV / NT_FILE / NT_TASKSTRUCT 等其他辅助元数据 | | | ---------------------------------------------------------------- | ------------------------------------------------------------------------ | 4. PT_LOAD Segments (物理内存段) | | - 包含1到N个连续或断续的物理地址映射块直接映射崩溃瞬间的真实物理内存 | ------------------------------------------------------------------------ELF HeaderELF 头部位于文件起始位置固定大小。它定义了文件的基本元数据包括 ELF 魔数Magic、文件类别64 位、大端/小端序、目标机器架构例如 EM_X86_64 或 EM_AARCH64以及程序头表PHT在文件中的偏移量e_phoff和数量e_phnum。Program Header TablePHT / 程序头表整个文件的活地图。它由一系列程序头项Program Header Entries组成不包含具体的物理内存数据而是精确描述了后续所有段Segment的类型、文件偏移p_offset、物理/虚拟地址基址p_paddr/p_vaddr以及段大小p_memsz。PT_NOTE Segment元数据段存放系统关键状态和调试上下文的黄金核心区。它内部通过 Name-Type-Value 的内嵌结构包裹了多个至关重要的 Note 节点NT_PRSTATUS进程/核心状态最为关键。它保存了崩溃瞬间全机每一个 CPU 核心的实时运行快照保存寄存器集及少量 task 上下文信息以及最重要的处理器寄存器状态Register Sets。在 x86_64 上表现为 RIP、RSP、CR3页表基址等在 ARM64 上则表现为 PC、SP、PSTATE 以及 TTBR0/TTBR1。这是 crash 工具重建崩溃现场函数调用栈Backtrace的唯一数学依据。NT_VMCOREINFO内核关键元数据存放内核的核心符号表物理地址保存内核关键符号、结构偏移、页模型参数等、内存模型的配置参数如九级或三级页表、Linux 内核版本号以及对抗安全攻击的 KASLR内核地址空间布局随机化偏移量kernel_offset。调试工具必须读取此节点才能正确消除地址随机化带来的偏移把二进制内存反向推演回 C 语言源码。其他 Note如 NT_AUXV、NT_FILE、NT_TASKSTRUCT保存辅助向量、内存映射文件信息等扩展上下文。PT_LOAD Segments物理内存段占据了 vmcore 99% 以上体积的实体内容。每一个 PT_LOAD 段对应一段连续的物理内存银行Memory Bank。程序头表中的每一项分别映射到这些段调试工具通过读取这些段的内容在应用层虚拟重构出系统崩溃那一刻的全局物理内存全景。二、生成机制kexec kdumpvmcore 的生成依赖两个机制的协同kexec内核执行链和 kdump崩溃转储框架。2.1 两个内核的世界Linux 系统正常运行时内存中实际上准备着两套内核捕获内核capture kernel / crash kernel在系统启动时由 kdump 服务通过kexec -p预加载进保留区域处于待命状态。2.2 崩溃触发到 vmcore 的完整路径① 生产内核触发 panic │ ▼ ② 调用 crash_kexec() ├── 保存当前 CPU 寄存器到 crash_notes 区域 ├── 向其他 CPU 发送 IPI/NMI令其保存寄存器后停机 └── 通过 kexec 机制热切换到捕获内核 │ ▼ ③ 捕获内核启动极简环境无需完整初始化 ├── 通过 /proc/vmcore 接口访问生产内核的物理内存 └── 捕获内核的内存在保留区域内与生产内核的内存不重叠 │ ▼ ④ makedumpfile 读取 /proc/vmcore ├── 按过滤级别丢弃无关页零页、用户态页等 ├── 压缩剩余内存页 └── 写入目标路径本地磁盘 / NFS / SSH 远端 │ ▼ ⑤ 捕获内核重启系统恢复正常启动2.3 /proc/vmcore 是桥梁/proc/vmcore是捕获内核暴露出的一个特殊虚拟文件它将生产内核的物理内存映射为可读的 ELF 文件视图。makedumpfile 读它就像读一个普通文件——但背后是对整个物理内存的访问。三、vmcore 的产生方式内核 panic 并非只有一条触发路径。从生产实践来看vmcore 的来源可以分为四类内核自发崩溃、看门狗超时、手动触发、虚拟化平台导出。理解这四类来源在分析时就能判断崩溃是系统自己倒下的还是被外力推倒的——二者的根因分析思路截然不同。3.1 内核自发崩溃这是最常见的 vmcore 来源。内核检测到自身状态异常时主动调用panic()终止运行。主要包含如下几种Oops 升级为 panic内核遇到可恢复错误时产生 Oops如非法内存访问、除零默认情况下 Oops 只打印错误信息不触发 panic。但开启以下参数后Oops 会直接升级为 panic# 查看当前值0只打印1触发panicsysctlkernel.panic_on_oops# 永久开启写入 /etc/sysctl.confkernel.panic_on_oops1生产环境强烈建议开启此参数。因为 Oops 之后内核状态已不可信继续运行可能导致数据损坏且不会留下 vmcore 供分析。BUG() / BUG_ON() / WARN_ON()内核代码中的断言宏触发时的行为需panic_on_oops1宏默认行为受参数控制BUG()触发 Oops直接 panic否属于必然 panic 行为BUG_ON(cond)条件成立时触发 panic否属于确定性断言机制WARN() / WARN_ON()打印警告系统继续运行kernel.panic_on_warn1 升级# WARN 升级为 panic有助于捕获早期异常kernel.panic_on_warn1空指针解引用NULL pointer dereference访问虚拟地址 0或极低地址触发 page fault内核无法处理后产生 Oops进而开启panic_on_oops时触发 panic。这是生产环境中最高频的 vmcore 来源之一。内核栈溢出内核默认为每个线程分配 8KBx86_64或 16KBARM64的内核栈。栈末尾有 canary 保护字溢出时 canary 被破坏内核检测后触发 panic。若开启了CONFIG_VMAP_STACK虚拟地址映射栈溢出会触发硬件 page fault更早被捕获。RCU stallRCURead-Copy-Update是内核的关键同步机制。若某个 CPU 在读侧临界区内停留时间过长默认 21 秒内核打印 RCU stall 警告# 开启后 RCU stall 直接触发 panic便于捕获死循环或中断关闭过久的场景kernel.panic_on_rcu_stall13.2 看门狗超时触发内核内置多层看门狗监控不同粒度的卡死状态触发后产生 panic 并生成 vmcore。软锁Soft Lockup监控对象调度器是否在预期时间内运行。默认超时20 秒内若某 CPU 未调度过其他任务判定为 soft lockup。kernel.softlockup_panic1# 检测到后触发 panic默认关闭kernel.watchdog_thresh10# 超时阈值秒soft lockup 2×此值硬锁Hard Lockup监控对象CPU 是否在关中断状态下长时间运行NMI 看门狗。默认超时watchdog_thresh秒默认 10 秒内若 CPU 未响应 NMI判定为 hard lockup。实现机制x86_64 使用 PMU性能计数器产生 NMIARM64 使用 arch timer 产生 FIQEL3。kernel.hardlockup_panic1# 检测到后触发 panic生产环境建议开启kernel.nmi_watchdog1# 启用 NMI 看门狗hung taskD 状态进程监控对象长期处于不可中断睡眠D 状态的进程。默认超时120 秒。常见于 NFS 挂起、存储设备无响应等场景。kernel.hung_task_panic1# D 状态超时后触发 panickernel.hung_task_timeout_secs120OOM killer内存耗尽时OOM killer 选择进程并将其杀死。若开启以下参数OOM 事件直接升级为 panicvm.panic_on_oom1# OOM 触发 panic适合内存泄漏定位# 0 只杀进程默认# 1 内存耗尽时触发 panic# 2 强制 panic忽略 cpuset/mempolicy 限制各类看门狗的超时对比时间轴秒 0────5────10────20────30────..────120 │ │ │ │ │ └── hung_taskD 状态进程默认 120s │ └── soft lockup默认 20s 2 × watchdog_thresh └── hard lockup默认 10s watchdog_thresh3.3 手动触发某些场景下系统处于活锁状态——没有触发 panic但已经失去响应。此时需要人工强制触发 vmcore。SysRq 触发最常用# 方式一直接写入需要 root 权限echoc/proc/sysrq-trigger# 方式二键盘物理或串口控制台Alt SysRq C# 需要满足以下前提条件# 确认 SysRq 已启用0禁用1全部启用或按位组合sysctlkernel.sysrq# 至少需要开启 crash dump 位bit 7 128kernel.sysrq1echo c向内核写入字符 ccrash内核调用panic(sysrq triggered crash\n)之后走标准 kdump 流程生成 vmcore。这是最干净、最常用的手动触发方式。NMI 按钮物理服务器部分服务器主板提供物理 NMI 按钮。按下后 CPU 收到 NMI触发nmi_panic()。适用于系统完全失去网络响应、SysRq 也无法操作的场景。需要提前开启kernel.unknown_nmi_panic1# 收到未知 NMI 时触发 panicIPMI/BMC 注入 NMI远程触发无需物理接触服务器通过带外管理接口远程触发# 通过 ipmitool 发送 NMI需要 BMC 支持ipmitool chassis power diag# 或通过 Redfish API现代服务器curl-XPOST https://BMC_IP/redfish/v1/Systems/System.Embedded.1/Actions/ComputerSystem.Reset\-d{ResetType: Nmi}收到 NMI 后若内核配置了unknown_nmi_panic1触发 panic 并生成 vmcore。这是生产环境中处理系统失联最常用的手段。注意手动触发的 vmcorecrash 报告中 panic 原因会显示为sysrq triggered crash或NMI: IOCK error而非真实业务错误。分析时要结合崩溃前的 dmesg 日志判断真实根因。3.4 虚拟化平台的 vmcore 导出在虚拟化或云环境中获取 vmcore 的路径有所不同。KVM/libvirtvirsh dump# 在宿主机上导出虚拟机内存快照virshdumpdomain-name/tmp/vm.dump --memory-only# 导出为 kdump 兼容格式virshdumpdomain-name/tmp/vm.dump--formatkdump-zlibvirsh dump导出的是虚拟机的物理内存视图格式与 kdump 生成的 vmcore 兼容可直接用 crash 分析。但它不依赖虚拟机内部的 kdump 配置即使虚拟机内部 kdump 未启用也可导出。适用场景虚拟机内核卡死、无法自动触发 kdump 时由宿主机介入强制导出。VMware内存快照VMware 的虚拟机内存快照.vmem 文件格式与 ELF vmcore 不同需要转换工具如vmss2core转为 crash 可读格式后才能分析。云平台ECS/EC2 等公有云厂商通常提供控制台的发送 NMI功能等同于 IPMI NMI 注入触发后走虚拟机内部的 kdump 流程vmcore 写入虚拟机本地磁盘。部分云厂商还支持将 vmcore 直接上传到对象存储OSS/S3。3.5 产生方式汇总与对比产生方式触发者需要预配置vmcore 完整性典型场景内核 panic自发内核自身需 kdump 就绪高空指针、BUG()、栈溢出soft/hard lockup看门狗需开启 panic 参数高死循环、关中断过久hung task看门狗需开启 panic 参数高NFS 挂起、存储无响应SysRq运维人员需 sysrq 启用高系统无响应但 SSH 可达IPMI/BMC NMI运维带外需 unknown_nmi_panic高系统完全失联virsh dump宿主管理员无需客户机配置中无寄存器虚拟机卡死物理 NMI 按钮运维现场需 unknown_nmi_panic高现场处理四、x86_64 架构下的工作细节4.1 CPU 停机机制x86_64 上生产内核 panic 时触发 panic 的 CPUBSP 或任意 CPU调用crash_kexec()通过 APIC IPI处理器间中断向所有其他 CPU 发送REBOOT_VECTOR其他 CPU 收到中断后执行crash_nmi_callback()将自身寄存器保存到crash_notes每 CPU 一块区域后进入 cpu_idle 等待若某颗 CPU 在规定时间内未响应 IPI主 CPU 通过 NMI 强制触发crash_notes的物理地址通过内核符号crash_notes导出捕获内核启动时从elfcorehdr参数获取这块区域的位置。APIC 的全称是 Advanced Programmable Interrupt Controller高级可编程中断控制器。简单来说它是现代多核Multi-core计算机中负责管理和分发中断信号的核心硬件机制。如果把 CPU 的每个核心比作流水线上的工人那么 APIC 就是那个精密的任务调度员决定哪个紧急任务中断该发给哪个工人、谁的优先级更高、以及工人之间如何通过暗号核间中断协同工作。4.2 内存布局与 KASLRx86_64 默认开启 KASLR内核地址空间随机化。每次启动时内核的虚拟地址基址会随机偏移。crash 工具需要通过以下方式确定偏移量vmcore 的 PT_NOTE 中记录了KERNELOFFSETcrash 工具读取该值后配合未随机化的符号表vmlinux计算真实地址若 vmlinux 符号地址与 vmcore 中的地址对不上通常是 KASLR 偏移未被正确处理而非 vmlinux 版本不匹配KASLR 的核心逻辑在于以开机时的动态信息熵打破黑客对静态内存地址的绝对预测。当开启 KASLR 后系统每次引导启动Boot时内核的早期引导加载程序Decompressor会利用硬件随机数生成器如 CPU 的 RDRAND 指令产生一个随机的偏移量Offset称为 Entropy熵值。内核会利用这个随机偏移量对核心区域的虚拟地址有时也包括物理地址进行整体平移和打乱。4.3 crashkernel 参数x86_64要保证 kdump 机制正常工作需要在 GRUB 启动参数中设置crashkernel参数。crashkernel是 Linux 内核启动参数其核心功能是为 kdump 机制预留一块物理内存用于在系统崩溃时运行捕获内核并生成 vmcore。x86_64 上保留区域默认放在物理内存高端4G 处避免与 DMA 区域冲突。也可显式指定物理地址# 方式 1静态指定大小不限位置crashkernel256M# 方式 2静态指定大小 强制指定物理起始地址crashkernel256M2G# 方式 3阶梯式自动匹配根据总内存大小决定预留大小crashkernel512M-2G:64M,2G-8G:128M,8G-:256M# 方式 4高级拆分配置区分高低端内存常见于大内存服务器crashkernel512M,highcrashkernel128M,low关键字由发行版预设规则自动计算crashkernelauto让系统根据总内存大小全自动、阶梯式地在物理内存大内存时会自动区分高/低端中预留 kdump 空间优点是免维护、省心缺点是大小由内核黑盒决定、容易隐形侵占业务内存。推荐值参考x86_64物理内存总量推荐 crashkernel 大小 4 GB128M4 ~ 64 GB256M64 ~ 1 TB512M 1 TB1G 或更大注意保留区域过小会导致捕获内核无法启动最常见的 kdump 失败原因之一。五、ARM64 架构下的工作细节5.1 异常级别与 panic 路径ARM64 使用异常级别Exception Level模型EL3 — 安全监控Secure Monitor固件层 EL2 — Hypervisor虚拟化层 EL1 — 内核Kernel ← Linux 运行于此 EL0 — 用户态User内核 panic 发生在 EL1。ARM64 没有 x86_64 的 APIC 机制CPU 停机通过以下路径实现PSCIPower State Coordination Interface通过 CPU_OFF 调用让其他 CPU 下线由固件层EL3执行IPI via GICGeneric Interrupt Controller向其他 CPU 发送处理器间中断功能类似 x86_64 的 APIC IPI若 PSCI 不可用如裸板环境则使用smp_send_stop()发 IPI 后等待 CPU 进入 WFIWait For Interrupt状态5.2 设备树 vs ACPIARM64 平台存在两类固件描述方式影响 kdump 的配置方式设备树Device Tree平台嵌入式、服务器早期crashkernel参数行为与 x86_64 基本一致捕获内核通过 DTB设备树二进制获取硬件信息需确保捕获内核使用的 DTB 与生产内核一致ACPI 平台现代 ARM64 服务器如鲲鹏、飞腾、Ampere行为更接近 x86_64crashkernelauto通常可用捕获内核通过 ACPI 表发现硬件无需额外 DTB 配置注意区分 ACPI 和 APICACPI → 系统配置和硬件发现“系统长什么样”APIC → 中断控制和 CPU 通信“中断怎么发、CPU 怎么聊”在 vmcore 生成链路上ACPI决定 crashkernel 能不能正常分配ARM64 更敏感APIC决定 panic 时能不能让所有 CPU 停下并保存寄存器x86_64 特有5.3 crashkernel 参数ARM64ARM64 的内存布局限制比 x86_64 更严格保留区域必须位于内核映像可寻址的范围内部分平台要求保留区域对齐到 2MB 边界高端内存分离写法同样适用crashkernel256M,highcrashkernel128M,lowARM64 特有问题部分平台尤其是内存超过 256GB 的大型服务器需要同时指定 high 和 low否则捕获内核的 DMA 操作会失败crashkernel512M,highcrashkernel128M,low推荐值参考ARM64物理内存总量推荐 crashkernel 大小 4 GB128M4 ~ 64 GB256M64 ~ 256 GB512M 256 GB512M,high 128M,low5.4 KASLR on ARM64ARM64 的 KASLR 实现与 x86_64 类似但随机化范围由 VA_BITS 决定通常 48 位或 52 位虚拟地址空间。处理方式相同vmcore 的 PT_NOTE 中记录偏移量crash 工具自动处理。六、makedumpfile 过滤参数makedumpfile 是控制 vmcore 体积与质量的核心工具通过-d参数指定过滤级别参数总共有 32 个过滤级别数值范围从 0 到 31下表为部分示例级别参数过滤内容典型用途0-d 0不过滤完整转储深度调试体积最大1-d 1过滤零页轻度压缩2-d 2过滤零页 缓存页非私有常规推荐3-d 3 缓存页私有进阶定制过滤4-d 4 用户态数据页默认推荐值5-d 5 空闲页buddy system 中的空闲内存体积最小6-d 6 Hugepage特殊巨页场景31-d 31最大过滤几乎只保留内核关键数据网络传输场景生产环境推荐-d 31配合压缩体积可缩小到原始内存的 5%15%同时保留足够的内核分析数据。若需要分析用户态进程如调查某个进程是否触发了内核 bug则使用-d 4或更低级别。压缩选项 -c # zlib 压缩最通用 -l # lzo 压缩速度快CPU 开销低 -p # 并行压缩多核加速推荐配置文件/etc/kdump.conf或/etc/sysconfig/kdump中的典型配置core_collector makedumpfile -l --message-level 1 -d 31七、常见故障与解决方法7.1 kdump 服务启动失败现象systemctl status kdump显示 failed或/sys/kernel/kexec_crash_loaded值为 0# 确认保留内存是否生效cat/proc/cmdline|grepcrashkernelcat/sys/kernel/kexec_crash_size# 应为非零值# 查看 kdump 日志journalctl-ukdump-b常见原因与解法原因现象解法crashkernel 参数未加入启动项kexec_crash_size 为 0修改 GRUB 配置文件重启生效保留内存Reserved不足kdump 日志显示 OOM 报错增大 crashkernel 分配值捕获内核Capture镜像缺失日志提示找不到 vmlinuz确认 kdump 核心包安装完整SELinux 策略阻止内核加载触发 AVC denied 日志setenforce 0 测试或加 policy7.2 panic 后未生成 vmcore现象系统崩溃重启目标路径下无 vmcore 文件# 确认目标路径挂载正常NFS 场景尤其要检查cat/etc/kdump.conf|grep^pathcat/etc/kdump.conf|grep^nfs# 检查磁盘空间df-h/var/crash# 查看上次崩溃的 kdump 日志journalctl-b-1|grep-ikdump常见原因原因解法目标路径磁盘已满清理旧 vmcore或更换存储目标NFS 挂载在捕获内核中失败检查网络设备驱动是否在捕获内核 initrd 中makedumpfile 崩溃OOM减小过滤级别或增大 crashkernel目标路径权限不足确认 root 可写二次 panic捕获内核本身崩溃查看串口/BMC 日志通常是驱动兼容问题7.3 vmcore 生成但无法用 crash 打开现象crash vmlinux vmcore报错退出crash: cannot resolve init_task或crash: compressed kdump: uncompress error常见原因与解法错误信息原因解法cannot resolve “init_task”vmlinux 与 vmcore 内核版本不匹配用crash -s确认版本找到对应 debuginfouncompress errorvmcore 损坏或压缩格式不支持检查 makedumpfile 版本尝试-d 0重新生成ELF header is corrupted写入中断磁盘满、掉电检查生成时的错误日志no debugging data available缺少 debuginfo/vmlinux安装对应内核的 debuginfo 包7.4 x86_64 特有APIC 超时导致 vmcore 不完整现象vmcore 中部分 CPU 的寄存器快照缺失crash 中bt -a某些 CPU 无输出原因panic 发生时部分 CPU 未在超时时间内响应 IPI主 CPU 放弃等待直接执行 kexec。# 内核启动参数增加apicverbose# 开启APIC详细日志定位卡死CPUhpetdisable# 某些平台HPET中断干扰IPI响应# 或在 kdump 配置中允许更长的 CPU 等待时间# /etc/kdump.confextra_bins /usr/sbin/earlykdump7.5 ARM64 特有PSCI 调用失败导致捕获内核卡死现象panic 后系统无响应串口无输出既不重启也不生成 vmcore原因捕获内核尝试通过 PSCI 让其他 CPU 下线时固件未正确响应。多见于早期 ARMv8 平台固件 bug虚拟化层EL2拦截了 PSCI 调用设备树中 PSCI 描述错误# 捕获内核启动参数中禁用其他 CPU单 CPU 模式捕获牺牲完整性换可靠性nr_cpus1# 或指定 PSCI 调用方式psciforce_hvc# 强制使用HVC调用虚拟化场景psciforce_smc# 强制使用SMC调用裸机场景常规的处理方法是通过/etc/kdump.conf将参数传递给捕获内核这种方法以牺牲性能换取绝对的启动成功率。以此绕过 ARM64 复杂的 PSCI 多核和中断固件 Bugkdump_commandline_appendnr_cpus1 irqpoll7.6 vmcore 体积过大写入超时现象捕获内核启动正常但 makedumpfile 运行时间过长最终超时或磁盘写满# 提高过滤级别core_collector makedumpfile-l--message-level1-d31# 启用并行压缩多核机器显著提速core_collector makedumpfile-l--message-level1-d31-p# 或使用 SSH 实时传输到远端避免本地磁盘瓶颈sshrootremote-hostmkdir -p /var/crash对于超大内存机器1TB建议结合-d 31和并行压缩并将crashkernel设置到 1G 以上确保捕获内核本身有足够内存运行 makedumpfile。八、小结初见全牛的地图看完本篇你对 vmcore 应当已经建立这样的认知地图【系统启动时】 GRUB crashkernel 参数 │ └→ 内核保留一块物理内存 └→ kdump 服务将捕获内核加载入保留区kexec -p 【panic 发生时】 生产内核触发 panic │ └→ 保存各 CPU 寄存器x86_64: IPINMI / ARM64: GIC IPIPSCI └→ kexec 热切换到捕获内核 【捕获内核运行时】 /proc/vmcore 暴露生产内核内存 │ └→ makedumpfile 读取、过滤、压缩 └→ 写入目标路径 → vmcore 文件 【之后】 crash 工具 vmlinux → 还原现场vmcore 就是这条链路的终点产物。它的完整性取决于保留内存够不够、过滤级别对不对、目标存储来不来得及写完。下一篇「执刀问器」我们将配置好分析环境拿起工具开始正式面对这牛头。