深入 kernel panic 流程

本文详细探讨了Kernel Panic的现象、原因和处理流程。从内核异常、调用栈、关键信息输出到 Panic 流程,分析了如何利用这些信息定位和解决问题。通过对 Panic 输出的解读和调试工具的使用,开发者可以更好地理解和处理内核级别的系统死机问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、前言

我们在项目开发过程中,很多时候会出现由于某种原因经常会导致手机系统死机重启的情况(重启分Android重启跟kernel重启,而我们这里只讨论kernel重启也就是 kernel panic 的情况),死机重启基本算是影响最严重的系统问题了,有稳定复现的,也有概率出现的,解题难度也千差万别,出现问题后,通常我们会拿到类似这样的kernel log信息(下面log仅以调用BUG()为例,其它异常所致的死机log信息会有一些不同之处):

[    2.052157] <2>-(2)[1:swapper/0]------------[ cut here ]------------
[    2.052163] <2>-(2)[1:swapper/0]Kernel BUG at c04289dc [verbose debug info unavailable]
[    2.052169] <2>-(2)[1:swapper/0]Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ARM
[    2.052178] <2>-(2)[1:swapper/0]disable aee kernel api[    3.052192] <2>-(2)[1:swapper/0]Non-crashing CPUs did not react to IPI
[    3.052204] <2>-(2)[1:swapper/0]CPU: 2 PID: 1 Comm: swapper/0 Tainted: G        W      3.18.35+ #3
[    3.052211] <2>-(2)[1:swapper/0]task: df060000 ti: df04a000 task.ti: df04a000
[    3.052227] <2>-(2)[1:swapper/0]PC is at ltr553_i2c_probe+0x94/0x9c
[    3.052233] <2>-(2)[1:swapper/0]LR is at 0x0
[    3.052242] <2>-(2)[1:swapper/0]pc : [<c04289dc>]    lr : [<00000000>]    psr: a0000113
[    3.052242] <2>sp : df04bd30  ip : 00000000  fp : df04bd4c
[    3.052249] <2>-(2)[1:swapper/0]r10: 00000003  r9 : de348fc0  r8 : c0428948
[    3.052255] <2>-(2)[1:swapper/0]r7 : dea1bc00  r6 : dea1bc04  r5 : dea1bc20  r4 : c0b53358
[    3.052262] <2>-(2)[1:swapper/0]r3 : c115ef4c  r2 : 00000000  r1 : 00000000  r0 : de366a00
[    4.354655] <2>-(2)[1:swapper/0] oops_end, 1, 11
[    4.354740] <2>-(2)[1:swapper/0]Kernel panic - not syncing: Fatal exception

这是linux 内核在死机之前输出的相关重要信息,包括PC指针、调用栈等在内的非常重要的便于Debug的线索,比如我们可以借助GUN toolsadd2Line)工具结合内核符号映射表vmlinux来定位当前PC指针所在的代码具体行数(定位到出错代码行并不意味着就找到了问题的根本原因跟修复异常,这个需要根据异常的复杂程度而论)。深入理解这些关键打印log信息的含义和机制非常有助于我们对于此类死机问题的定位和分析(对于内存被踩、硬件不稳定导致的一类问题分析有局限性),这也是我们需要深入学习内核异常流程的初衷。

这里我们必须弄清楚几个问题:

  • 这些死机前留下的关键register信息是怎么来的,有什么用,具体含义是什么?
  • 如何利用这些遗留的线索找到出问题代码具体在哪支文件,在哪一行?
  • 内核发生致命异常到死机的总流程是怎样的,类似死机问题应该如何着手分析?

为此,本文就从最常见的主动触发BUG()为例解析上面的疑问及分析整个kernel panic流程。

二、什么是BUG() ?

有过驱动调试经验的人肯定都知道这个东西,这里的BUG跟我们一般认为的“软件缺陷”可不是一回事,这里说的BUG()其实是linux kernel中用于拦截内核程序超出预期的行为,属于软件主动汇报异常的一种机制。这里有个疑问,就是什么时候会用到呢?一般来说有两种用到的情况,一是软件开发过程中,若发现代码逻辑出现致命fault后就可以调用BUG()kernel死掉(类似于assert),这样方便于定位问题,从而修正代码执行逻辑;另外一种情况就是,由于某种特殊原因(通常是为了debug而需抓ramdump),我们需要系统进入kernel panic的情况下使用.

  • 原形是什么?

BUG()BUG_ON(1)其实本质是一回事,后者只是在前者的基础上做了简单的封装而已,BUG()的实现 本质是埋入一条未定义指令:0xe7f001f2,触发ARM发起Undefined Instruction异常(PS:ARM有分10种异常类型,详细可以复习ARM异常模型章节).

<kernel-3.18/arch/arm/include/asm/bug.h>
#define BUG_INSTR_VALUE 0xe7f001f2
#define BUG_INSTR(__value) __inst_arm(__value)
#define BUG() _BUG(__FILE__, __LINE__, BUG_INSTR_VALUE)
#define _BUG(file, line, value) __BUG(file, line, value)
#define __BUG(__file, __line, __value)              \
do {                                \
    asm volatile(BUG_INSTR(__value) "\n");          \
    unreachable();     
<think>好的,我现在需要解决用户提到的在OpenStack中创建虚拟机时遇到的Kernel panic - not syncing: fatal exception错误。首先,我得回忆一下Kernel panic的一般原因,可能涉及内核配置、镜像问题、硬件兼容性或资源分配等。 首先,用户是在创建虚拟机时出现这个问题,所以可能是虚拟机启动过程中的内核问题。我需要分步骤考虑可能的原因: 1. **镜像问题**:用户使用的镜像可能有损坏,或者内核与虚拟化环境不兼容。比如,镜像可能缺少必要的驱动,如virtio驱动,导致无法正确访问磁盘或网络。这时候需要检查镜像是否适合在KVM环境下运行,是否支持半虚拟化驱动。 2. **虚拟机配置**:虚拟机的计算配置(如Flavor)是否合理。比如,分配的内存过小可能导致内核无法启动。检查用户是否给虚拟机分配了足够的内存和CPU资源。特别是某些操作系统对最低资源有要求,如果低于这个阈值,启动时会出问题。 3. **Hypervisor兼容性**:OpenStack使用的Hypervisor(通常是KVM)是否与镜像的内核兼容。例如,某些内核参数可能需要调整,或者需要启用特定的CPU特性。可能需要检查虚拟机的XML定义,看是否有不兼容的配置项。 4. **内核参数错误**:在引导参数中可能存在错误,比如错误的根设备指定、缺失的initrd配置,或者错误的console设置。需要检查虚拟机的引导参数是否正确,特别是root=、console=ttyS0等参数是否正确设置。 5. **日志收集**:用户是否查看了虚拟机的控制台日志或OpenStack的日志(如Nova日志)?控制台输出可能会有更详细的错误信息,帮助定位问题。例如,是否在挂载根文件系统时失败,或者驱动加载问题。 接下来,我需要考虑如何逐步指导用户排查问题。可能需要建议用户先检查镜像,尝试使用其他已知良好的镜像测试,确认是否是镜像问题。然后检查Flavor配置,确保资源足够。如果镜像没问题,可能需要检查Hypervisor的日志,比如查看libvirt的日志,或者Nova-compute的日志,寻找更详细的错误信息。 另外,用户可能需要确保镜像支持虚拟化环境。例如,某些镜像可能需要安装virtio驱动,否则无法在KVM下正常工作。如果是自己制作的镜像,可能需要检查是否包含virtio_blk、virtio_net等驱动。 还有可能是在创建虚拟机时指定的元数据或配置驱动不正确,导致内核无法正确初始化。比如,配置驱动为configdrive时是否存在问题,或者metadata服务是否可达,但这种情况可能不会直接导致Kernel panic,更多是网络配置问题。 此外,内核本身可能存在bug,尤其是在使用非主流或自定义编译的内核时。建议用户尝试使用官方提供的镜像,或者确认内核版本是否与OpenStack环境兼容。 总结下来,处理步骤可能包括: 1. 验证镜像的完整性及兼容性。 2. 检查虚拟机的资源分配(内存、CPU)。 3. 查看虚拟机控制台日志,确认panic的具体原因。 4. 确保virtio驱动正确包含在镜像中。 5. 检查内核引导参数是否正确。 6. 更新或更换内核版本,测试是否存在已知问题。 在指导用户时,需要一步步排除可能性,从最可能的镜像和配置问题开始,逐步深入。同时,提醒用户查看详细的日志信息,这对于诊断问题至关重要。</think>在OpenStack中创建虚拟机时遇到`kernel panic - not syncing: fatal exception`错误,通常与虚拟机内核配置、镜像问题或资源分配有关。以下是逐步排查与解决方案: --- ### 1. **检查镜像兼容性** - **问题原因**:使用的镜像可能缺少必要的驱动(如virtio驱动)或内核不兼容OpenStack的虚拟化环境(如KVM)。 - **解决方法**: 1. 使用官方或已验证兼容的镜像(如CirrOS、Cloud-Init镜像)。 2. 如果是自定义镜像,确保包含以下驱动: - 块设备驱动:`virtio_blk` - 网络驱动:`virtio_net` - 文件系统驱动:`ext4`/`xfs`(根据镜像配置) 3. 通过命令检查镜像格式和元数据: ```bash qemu-img info <镜像文件> ``` --- ### 2. **验证虚拟机资源配置** - **问题原因**:内存或CPU分配不足,导致内核无法正常启动。 - **解决方法**: 1. 检查虚拟机的Flavor配置: - 确保内存≥镜像要求的最小值(如Ubuntu通常需要≥1GB)。 - 确保vCPU数量合理(可从1核开始测试)。 2. 临时调整Flavor测试: ```bash openstack flavor create --ram 2048 --vcpus 2 test-flavor openstack server create --flavor test-flavor --image <镜像ID> test-vm ``` --- ### 3. **查看虚拟机控制台日志** - **步骤**: 1. 通过OpenStack Dashboard或命令行获取控制台日志: ```bash openstack console log show <虚拟机ID> ``` 2. 分析日志中的关键错误: - 如果提示`VFS: Unable to mount root fs`,可能是根文件系统驱动缺失。 - 如果提示`No init found`,可能是镜像未正确配置Initramfs。 --- ### 4. **检查内核引导参数** - **问题原因**:内核启动参数(如根设备、控制台设置)错误。 - **解决方法**: 1. 编辑镜像的Grub配置(需挂载镜像): - 确认`root=`参数指向正确的设备(如`/dev/vda`)。 - 添加`console=ttyS0`以启用串口控制台。 2. 重建Initramfs以包含virtio驱动: ```bash sudo update-initramfs -u ``` --- ### 5. **验证Hypervisor兼容性** - **问题原因**:KVM Hypervisor与虚拟机内核存在兼容性问题。 - **解决方法**: 1. 尝试调整虚拟机的CPU模式: ```bash openstack flavor set <Flavor名称> --property hw:cpu_mode=host-passthrough ``` 2. 检查Nova和Libvirt日志: ```bash # Nova日志 tail -f /var/log/nova/nova-compute.log # Libvirt日志 tail -f /var/log/libvirt/qemu/<虚拟机名称>.log ``` --- ### 6. **测试其他虚拟化类型** - **步骤**: 1. 尝试使用不同的虚拟化类型(如从KVM切换到QEMU): ```bash openstack flavor set <Flavor名称> --property hw:vm_type=qemu ``` --- ### 7. **更新内核或OpenStack版本** - **问题原因**:内核或OpenStack组件存在已知Bug。 - **解决方法**: 1. 升级虚拟机内核至最新稳定版。 2. 升级OpenStack到最新版本(如Zed、Antelope)。 --- ### 总结流程 1. **优先检查镜像** → 使用官方镜像测试。 2. **调整资源配置** → 增加内存/CPU。 3. **查看日志定位原因** → 根据错误提示修复驱动或配置。 4. **逐步验证** → 通过最小化配置排除干扰因素。 若问题仍未解决,请提供虚拟机控制台日志和Nova日志,以便进一步分析。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值