Oops的诞生

2024-04-14 14:08
文章标签 诞生 oops

本文主要是介绍Oops的诞生,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原文地址 http://pczou.bokee.com/3915699.html

常在河边走,哪能不湿鞋。用Linux,总有死机的时候,如果运气好,会看到一些所谓"Oops"信息(在屏幕上或系统日志中),比如:

Unable to handle kernel paging request at virtual address f899b670
printing eip:
c01de48c
*pde = 00737067
Oops: 0002 [#1]
Modules linked in: bluesmoke_e752x bluesmoke_mc md5 ipv6 parport_pc lp parport nls_cp936 vfat fat dm_mod button battery asus_acpi ac joydev yenta_socket pcmcia_core uhci_hcd ehci_hcd snd_intel8x0 snd_ac97_codec snd_pcm_oss snd_mixer_oss snd_pcm snd_timer snd_page_alloc snd_mpu401_uart snd_rawmidi snd_seq_device snd soundcore ipw2200 ieee80211 ieee80211_crypt sk98lin ext3 jbd
CPU: 0
EIP: 0060:[ ] Not tainted VLI
EFLAGS: 00210286 (2.6.9-11.21AXKProbes)
EIP is at kobject_add+0x83/0xd7
eax: c038db78 ebx: c038db04 ecx: f899b670 edx: f8a4a630
esi: c038db4c edi: f8a4a614 ebp: c038db80 esp: d7568f2c
ds: 007b es: 007b ss: 0068
Process modprobe (pid: 8227, threadinfo=d7568000 task=f4ea99b0)
Stack: f8a4a614 ffffffea f8a4a5e4 00000000 c01de4f9 f8a4a614 c038db00 c024a1d4
f8a4a5c0 f8a4a5e4 f8a4a5f4 d7568000 c024a661 1d244b3c 00000000 0000000a
c032421b 00000000 00000000 00000015 00000014 00000016 f89ddb34 f8a4a5c0
Call Trace:
[ ] kobject_register+0x19/0x39
[ ] bus_add_driver+0x36/0x97
[ ] driver_register+0x82/0x89
[ ] pci_register_driver+0x85/0xa1
[ ] init_module+0xa/0x14 [bluesmoke_e752x]
[ ] sys_init_module+0x1ec/0x323
[ ] syscall_call+0x7/0xb
Code: 85 d2 0f 85 06 04 00 00 85 ed 75 0d 8b 47 28 83 c0 10 e8 82 01 00 00 89 c5 8b 47 28 8d 57 1c 83 c0 08 89 47 1c 8b 48 04 89 50 04 <89> 11 89 4a 04 8b 47 28 8b 18 8d 4b 48 89 c8 ba ff ff 00 00 0f


Oops 可以看成是内核级的Segmentation Fault。应用程序如果进行了非法内存访问或执行了非法指令,会得到Segfault信号,一般的行为是coredump,应用程序也可以自己截获 Segfault信号,自行处理。如果内核自己犯了这样的错误,则会打出Oops信息。

有不少文章说明如何理解这些Oops (http://pczou.blogchina.com/545558.html),这里只想解释一下它所产生的过程(以2.6系列内核为例):

首先是处理硬件发出的内存访问异常(fault),有些异常是无辜的(比如demand-paging),而有些则是内核的错误所致。

1. do_page_fault() arch/i386/mm/fault.c

如果是内核进行了非法访问,do_page_fault()会先打出EIP, PDE等信息,例如:

Unable to handle kernel paging request at virtual address f899b670
printing eip:
c01de48c
*pde = 00737067

然后调用 die("Oops", regs, error_code);

这之后,如果系统还活着(至少要满足两个条件:1. 在进程上下文 2. 没有设置panic_on_oops),会杀死当前进程。然后继续运行,好像什么事情都没有发生一样。不过,这样的好事不经常发生,发生了也不会太持久。

2. do_page_fault() -> die() arch/i386/kernel/traps.c

die() 首先打出一行:

Oops: 0002 [#1]

其中0002代表错误码 (读错误、发生在内核空间),#1代表Oops发生次数。

 * error_code:
 *      bit 0 == 0 means no page found, 1 means protection fault
 *      bit 1 == 0 means read, 1 means write
 *      bit 2 == 0 means kernel, 1 means user-mode


然后,调用 show_registers(regs) 输出寄存器、当前进程、堆栈、指令代码等信息:

Modules linked in: bluesmoke_e752x bluesmoke_mc md5 ipv6 parport_pc lp parport nls_cp936 vfat fat dm_mod button battery asus_acpi ac joydev yenta_socket pcmcia_core uhci_hcd ehci_hcd snd_intel8x0 snd_ac97_codec snd_pcm_oss snd_mixer_oss snd_pcm snd_timer snd_page_alloc snd_mpu401_uart snd_rawmidi snd_seq_device snd soundcore ipw2200 ieee80211 ieee80211_crypt sk98lin ext3 jbd
CPU: 0
EIP: 0060:[ ] Not tainted VLI
EFLAGS: 00210286 (2.6.9-11.21AXKProbes)
EIP is at kobject_add+0x83/0xd7
eax: c038db78 ebx: c038db04 ecx: f899b670 edx: f8a4a630
esi: c038db4c edi: f8a4a614 ebp: c038db80 esp: d7568f2c
ds: 007b es: 007b ss: 0068
Process modprobe (pid: 8227, threadinfo=d7568000 task=f4ea99b0)
Stack: f8a4a614 ffffffea f8a4a5e4 00000000 c01de4f9 f8a4a614 c038db00 c024a1d4
f8a4a5c0 f8a4a5e4 f8a4a5f4 d7568000 c024a661 1d244b3c 00000000 0000000a
c032421b 00000000 00000000 00000015 00000014 00000016 f89ddb34 f8a4a5c0
Call Trace:
[ ] kobject_register+0x19/0x39
[ ] bus_add_driver+0x36/0x97
[ ] driver_register+0x82/0x89
[ ] pci_register_driver+0x85/0xa1
[ ] init_module+0xa/0x14 [bluesmoke_e752x]
[ ] sys_init_module+0x1ec/0x323
[ ] syscall_call+0x7/0xb
Code: 85 d2 0f 85 06 04 00 00 85 ed 75 0d 8b 47 28 83 c0 10 e8 82 01 00 00 89 c5 8b 47 28 8d 57 1c 83 c0 08 89 47 1c 8b 48 04 89 50 04 <89> 11 89 4a 04 8b 47 28 8b 18 8d 4b 48 89 c8 ba ff ff 00 00 0f


如果是在中断上下文,则直接调用panic()。如果是在进程上下文,则根据panic_on_oops的设置选择是否panic()。panic_on_oops的缺省设置是"0",即在Oops发生时不会进行panic()操作。可以通过sysctl进行设置:
sysctl -w kernel.panic_on_oops=1

有panic_on_oops 这样的设置,说明Oops不一定导致系统死亡,也不一定需要重新启动系统。正如用户程序segfault时可能还能坚持运行一样。不过Oops一旦发生,系统已经有些不正常了,即使表面上可能还正常,不过可能有些锁已经被占用而无法释放,很快会导致系统死锁。

那么,panic()是什么呢?panic()和用户空间的abort()类似,简单清理一下,就可以放心去死(reboot)了。

3. do_page_fault() -> die() -> panic()

panic会根据 kernel.panic 的设置决定 reboot 前的延时,如果 kernel.panic=0,则打开中断,陷入死循环。反之,则在几秒之后,reboot系统。


可以看出虽然都是死,但死因不同,死亡时的表现更是五花八门。常见的死因有:

  • 非法内存访问 (比如访问地址0)
  • 非法指令
有时候核心成心发出非法指令,比如BUG() (include/asm/bug.h) 中所做的,以引起Oops。类似用户程序中调用assert()。

死亡发生的地点也很关键,直接导致了死亡的不同表现,比如:
  • 进程上下文
  • 中断上下文
在中断上下文中,由于中断是关闭的,而且往往会占用一些锁,这种情况下一般除了死,没有什么别的办法。

在进程上下文中要自由一些,如果运气好的话,可以苟延残喘一段时间。

这篇关于Oops的诞生的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/903186

相关文章

黑神话:游戏的诞生

🛰 前言 近期,国产 3A 大作《黑神话:悟空》给我们带来了一波惊喜。相信各位或多或少都有所了解。看见如此激动人心的产品我们除了欣喜,也不禁让我们思考起来游戏是如何实现的?我们能否开发一款属于自己的游戏? 今天我们借此来讨论一下游戏的基本原理以及优质的游戏是如何诞生的。 🛰 神奇的动画 在开始聊游戏之前,不得不跟大家先聊一个核心知识——动画。什么是动画?动画是如何实现的? 动画是

Go语言诞生5周年!10大Go语言开源项目推荐

2014年11月,Golang官方博客发布文章 ,以纪念Go语言发布5周年。文章称,Go语言在云计算时代找到了位置,预言“2015年将是Go语言急剧发展之年”。 2014年11月,Golang官方博客发布Go语言核心开发组成员Andrew Gerrand文章 《Half a decade with Go》,以纪念Go语言发布5周年。Andrew Gerrand在文章中称,Go语言在工业界向

Scratch的诞生:开启编程世界的大门

标题:Scratch的诞生:开启编程世界的大门 Scratch,这款全球数百万儿童和青少年的编程启蒙工具,自诞生之日起就以其独特的图形化编程界面和强大的社区支持,引领着编程教育的潮流。本文将详细探讨Scratch的起源,它如何从一个教育项目成长为全球性的编程学习平台,并提供一些基础的Scratch代码示例,以助读者理解其编程逻辑。 一、Scratch的起源背景 Scratch是由麻省理工学院

解构微信(一):邮件中诞生与开发的逆境

搜狐IT 2013-11-18 11:48 15 微信 【声明】本案例是由郑小平和许家馨在杨斌教授的指导下编写的,仅用于课堂讨论。本案例中的情况描述不反映编者的观点,也不作为正式文件、基本数据来源以及管理活动是否有效的证明。案例版权归腾讯公司所有。转载请注明以上声明。 虎嗅注:《解构微信》系列文章共计六篇。作者深入微信团队,围绕微信产品诞生与继续完善,从产品开发、

智慧停车(十三) 门把手锁的诞生

决定做门把手锁之前,老板半年前和我提到过玻璃锁,并讲解了整个产品的结构和使用流程,叫我准备着手这个系统的开发工作。三个月前又找到我说不做玻璃锁了,想做轮胎锁,同样细心点的讲解了轮胎锁的结构和使用流程,一样叫我准备这个系统的开发工作。三天前,终于确定要开发了,就做门把手锁,硬件这边已经在做结构了,看来这次下了决心要做,然后把整个流程体系和我大概描述了下,叫我出个流程图准备安排开发。 一 玻璃锁 玻

【vue3|第13期】深入了解Vue3生命周期:管理组件的诞生、成长与消亡

日期:2024年6月22日 作者:Commas 签名:(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释:如果您觉得有所帮助,帮忙点个赞,也可以关注我,我们一起成长;如果有不对的地方,还望各位大佬不吝赐教,谢谢^ - ^ 1.01365 = 37.7834;0.99365 = 0.0255 1.02365 = 1377.4083;0.98365 = 0.0006 说在最前面:本文

super4412下调试cmos驱动是的nternal error: Oops - BUG: 0 [#1] PREEMPT SMP ARM问题解决

一直都觉得友善之臂的4412开发板的cmos硬件接口部分有问题,所以友善官方一直没有更新cmos摄像头驱动,但是还是得试着调, 我用的摄像头模块为ov5642,在把摄像头相关的板级配置都添加好后,编译内核,运行出现了 [ 2.970000] v4l2_i2c_subdev_init finished [ 2.975000] start read ov5642 id [

Go语言的诞生背景

人不走空                                                                              🌈个人主页:人不走空       💖系列专栏:算法专题 ⏰诗词歌赋:斯是陋室,惟吾德馨   目录       🌈个人主页:人不走空       💖系列专栏:算法专题 ⏰诗词歌赋:

产品求职必备:“一份优秀产品简历的诞生”

​好不容易学成要开始求职,简历这一关却成了不少同学的“拦路虎”。 “我的简历投出去没反应~”“我的简历项目经验应该怎么写?” “我的简历完全不知道怎么改” 01明确职业目标 一份泛泛而谈的简历不会让你脱颖而出,如果你对自己还没有清晰定位,又怎么能期望企业对你清晰定位,提供合适的岗位呢? 针对职位定制简历,甚至针对具体的公司定制简历,这并不夸张,尤其对于跨行业的求职者尤为重要。