什么是Oops?从语言学的角度说,Oops应该是一个拟声词。当出了点小事故,或者做了比较尴尬的事之后,你可以说"Oops",翻译成中国话就叫做“哎呦”。“哎呦,对不起,对不起,我真不是故意打碎您的杯子的”。看,Oops就是这个意思。
在Linux内核开发中的Oops是什么呢?其实,它和上面的解释也没什么本质的差别,只不过说话的主角变成了Linux。当某些比较致命的问题出现时,我们的Linux内核也会抱歉的对我们说:“哎呦(Oops),对不起,我把事情搞砸了”。Linux内核在发生kernel panic时会打印出Oops信息,把目前的寄存器状态、堆栈内容、以及完整的Call trace都show给我们看,这样就可以帮助我们定位错误。
下面,我们来看一个实例。为了突出本文的主角--Oops,这个例子唯一的作用就是造一个空指针引用错误。
#include <linux/kernel.h> static int __init hello_init(void) static void __exit hello_exit(void) module_init(hello_init); MODULE_LICENSE("GPL"); |
很明显,错误的地方就是第8行。
接下来,我们把这个模块编译出来,再用insmod来插入到内核空间,正如我们预期的那样,Oops出现了。
[ 100.243737] BUG: unable to handle kernel NULL pointer dereference at (null) [ 100.244985] IP: [<f82d2005>] hello_init+0x5/0x11 [hello] [ 100.262266] *pde = 00000000 [ 100.288395] Oops: 0002 [#1] SMP [ 100.305468] last sysfs file: /sys/devices/virtual/sound/timer/uevent [ 100.325955] Modules linked in: hello(+) vmblock vsock vmmemctl vmhgfs acpiphp snd_ens1371 gameport snd_ac97_codec ac97_bus snd_pcm_oss snd_mixer_oss snd_pcm snd_seq_dummy snd_seq_oss snd_seq_midi snd_rawmidi snd_seq_midi_event snd_seq snd_timer snd_seq_device ppdev psmouse serio_raw fbcon tileblit font bitblit softcursor snd parport_pc soundcore snd_page_alloc vmci i2c_piix4 vga16fb vgastate intel_agp agpgart shpchp lp parport floppy pcnet32 mii mptspi mptscsih mptbase scsi_transport_spi vmxnet [ 100.472178] [ 100.494931] Pid: 1586, comm: insmod Not tainted (2.6.32-21-generic #32-Ubuntu) VMware Virtual Platform [ 100.540018] EIP: 0060:[<f82d2005>] EFLAGS: 00010246 CPU: 0 [ 100.562844] EIP is at hello_init+0x5/0x11 [hello] [ 100.584351] EAX: 00000000 EBX: fffffffc ECX: f82cf040 EDX: 00000001 [ 100.609358] ESI: f82cf040 EDI: 00000000 EBP: f1b9ff5c ESP: f1b9ff5c [ 100.631467] DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 [ 100.657664] Process insmod (pid: 1586, ti=f1b9e000 task=f137b340 task.ti=f1b9e000) [ 100.706083] Stack: [ 100.731783] f1b9ff88 c0101131 f82cf040 c076d240 fffffffc f82cf040 0072cff4 f82d2000 [ 100.759324] <0> fffffffc f82cf040 0072cff4 f1b9ffac c0182340 f19638f8 f137b340 f19638c0 [ 100.811396] <0> 00000004 09cc9018 09cc9018 00020000 f1b9e000 c01033ec 09cc9018 00015324 [ 100.891922] Call Trace: [ 100.916257] [<c0101131>] ? do_one_initcall+0x31/0x190 [ 100.943670] [<f82d2000>] ? hello_init+0x0/0x11 [hello] [ 100.970905] [<c0182340>] ? sys_init_module+0xb0/0x210 [ 100.995542] [<c01033ec>] ? syscall_call+0x7/0xb [ 101.024087] Code: <c7> 05 00 00 00 00 01 00 00 00 5d c3 00 00 00 00 00 00 00 00 00 00 [ 101.079592] EIP: [<f82d2005>] hello_init+0x5/0x11 [hello] SS:ESP 0068:f1b9ff5c [ 101.134682] CR2: 0000000000000000 [ 101.158929] ---[ end trace e294b69a66d752cb ]--- |