成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

你了解Linux內核Oops的妙用嗎

系統 Linux
在Linux內核開發中的Oops是什么呢?其實,它和上面的解釋也沒什么本質的差別,只不過說話的主角變成了Linux。當某些比較致命的問題出現時,我們的Linux內核也會抱歉的對我們說:“哎呦(Oops),對不起,我把事情搞砸了”。Linux內核在發生kernel panic時會打印出Oops信息,把目前的寄存器狀態、堆棧內容、以及完整的Call trace都show給我們看,這樣就可以幫助我們定位錯誤。

[[181773]]

什么是Oops?從語言學的角度說,Oops應該是一個擬聲詞。當出了點小事故,或者做了比較尷尬的事之后,你可以說"Oops",翻譯成中國話就叫做“哎呦”。“哎呦,對不起,對不起,我真不是故意打碎您的杯子的”。看,Oops就是這個意思。

在Linux內核開發中的Oops是什么呢?其實,它和上面的解釋也沒什么本質的差別,只不過說話的主角變成了Linux。當某些比較致命的問題出現時,我們的Linux內核也會抱歉的對我們說:“哎呦(Oops),對不起,我把事情搞砸了”。Linux內核在發生kernel panic時會打印出Oops信息,把目前的寄存器狀態、堆棧內容、以及完整的Call trace都show給我們看,這樣就可以幫助我們定位錯誤。

下面,我們來看一個實例。為了突出本文的主角--Oops,這個例子唯一的作用就是造一個空指針引用錯誤。

  1. #include <linux/kernel.h>#include <linux/module.h>static int __init hello_init(void){ 
  2.     int *p = 0; 
  3.      
  4.     *p = 1;  
  5.     return 0;}static void __exit hello_exit(void){ 
  6.     return;}module_init(hello_init);module_exit(hello_exit);MODULE_LICENSE("GPL");  

很明顯,錯誤的地方就是第8行。

接下來,我們把這個模塊編譯出來,再用insmod來插入到內核空間,正如我們預期的那樣,Oops出現了。

  1. [  100.243737] BUG: unable to handle kernel NULL pointer dereference at (null
  2.  
  3. [  100.244985] IP: [<f82d2005>] hello_init+0x5/0x11 [hello] 
  4.  
  5. [  100.262266] *pde = 00000000  
  6.  
  7. [  100.288395] Oops: 0002 [#1] SMP  
  8.  
  9. [  100.305468] last sysfs file: /sys/devices/virtual/sound/timer/uevent 
  10.  
  11. [  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 
  12.  
  13. [  100.472178] [  100.494931] Pid: 1586, comm: insmod Not tainted (2.6.32-21-generic #32-Ubuntu) VMware Virtual Platform 
  14.  
  15. [  100.540018] EIP: 0060:[<f82d2005>] EFLAGS: 00010246 CPU: 0 
  16.  
  17. [  100.562844] EIP is at hello_init+0x5/0x11 [hello] 
  18.  
  19. [  100.584351] EAX: 00000000 EBX: fffffffc ECX: f82cf040 EDX: 00000001 
  20.  
  21. [  100.609358] ESI: f82cf040 EDI: 00000000 EBP: f1b9ff5c ESP: f1b9ff5c 
  22.  
  23. [  100.631467]  DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 
  24.  
  25. [  100.657664] Process insmod (pid: 1586, ti=f1b9e000 task=f137b340 task.ti=f1b9e000) 
  26.  
  27. [  100.706083] Stack: 
  28.  
  29. [  100.731783]  f1b9ff88 c0101131 f82cf040 c076d240 fffffffc f82cf040 0072cff4 f82d2000 
  30.  
  31. [  100.759324] <0> fffffffc f82cf040 0072cff4 f1b9ffac c0182340 f19638f8 f137b340 f19638c0 
  32.  
  33. [  100.811396] <0> 00000004 09cc9018 09cc9018 00020000 f1b9e000 c01033ec 09cc9018 00015324 
  34.  
  35. [  100.891922] Call Trace: 
  36.  
  37. [  100.916257]  [<c0101131>] ? do_one_initcall+0x31/0x190 
  38.  
  39. [  100.943670]  [<f82d2000>] ? hello_init+0x0/0x11 [hello] 
  40.  
  41. [  100.970905]  [<c0182340>] ? sys_init_module+0xb0/0x210 
  42.  
  43. [  100.995542]  [<c01033ec>] ? syscall_call+0x7/0xb 
  44.  
  45. [  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  
  46.  
  47. [  101.079592] EIP: [<f82d2005>] hello_init+0x5/0x11 [hello] SS:ESP 0068:f1b9ff5c 
  48.  
  49. [  101.134682] CR2: 0000000000000000 
  50.  
  51. [  101.158929] ---[ end trace e294b69a66d752cb ]--- 

 Oops首先描述了這是一個什么樣的bug,然后指出了發生bug的位置,即“IP: [<f82d2005>] hello_init+0x5/0x11 [hello]”。

在這里,我們需要用到一個輔助工具objdump來幫助分析問題。objdump可以用來反匯編,命令格式如下:

  1. objdump -S hello.o 

下面是hello.o反匯編的結果,而且是和C代碼混排的,非常的直觀。

  1. hello.o:     file format elf32-i386Disassembly of section .init.text:00000000 <init_module>:#include <linux/kernel.h>#include <linux/module.h>static int __init hello_init(void){ 
  2.    0:   55                      push   %ebp int *p = 0; 
  3.      
  4.     *p = 1; 
  5.      
  6.     return 0;} 
  7.    1:   31 c0                   xor    %eax,%eax#include <linux/kernel.h>#include <linux/module.h>static int __init hello_init(void){ 
  8.    3:   89 e5                   mov    %esp,%ebp    int *p = 0; 
  9.      
  10.     *p = 1; 
  11.    5:   c7 05 00 00 00 00 01    movl   $0x1,0x0 
  12.    c:   00 00 00  
  13.      
  14.     return 0;} 
  15.    f:   5d                      pop    %ebp  10:    c3                      ret    Disassembly of section .exit.text:00000000 <cleanup_module>:static void __exit hello_exit(void){ 
  16.    0:   55                      push   %ebp   1:    89 e5                   mov    %esp,%ebp   3:   e8 fc ff ff ff          call   4 <cleanup_module+0x4> 
  17.     return;} 
  18.    8:   5d                      pop    %ebp   9:    c3                      ret     

 對照Oops的提示,我們可以很清楚的看到,出錯的位置hello_init+0x5的匯編代碼是:

  1. 5:c7 05 00 00 00 00 01 movl $0x1,0x0 

這句代碼的作用是把數值1存入0這個地址,這個操作當然是非法的。

我們還能看到它對應的c代碼是:

  1. *p = 1; 

Bingo!在Oops的幫助下我們很快就解決了問題。

我們再回過頭來檢查一下上面的Oops,看看Linux內核還有沒有給我們留下其他的有用信息。

Oops: 0002 [#1]

這里面,0002表示Oops的錯誤代碼(寫錯誤,發生在內核空間),#1表示這個錯誤發生一次。

Oops的錯誤代碼根據錯誤的原因會有不同的定義,本文中的例子可以參考下面的定義(如果發現自己遇到的Oops和下面無法對應的話,***去內核代碼里查找):

  1. * error_code: 
  2. *      bit 0 == 0 means no page found, 1 means protection fault 
  3. *      bit 1 == 0 means read, 1 means write 
  4. *      bit 2 == 0 means kernel, 1 means user-mode 
  5. *      bit 3 == 0 means data, 1 means instruction 

 有時候,Oops還會打印出Tainted信息。這個信息用來指出內核是因何種原因被tainted(直譯為“玷污”)。具體的定義如下:

  1: 'G' if all modules loaded have a GPL or compatible license, 'P' if any proprietary module has been loaded.  Modules without a MODULE_LICENSE or with a MODULE_LICENSE that is not recognised by insmod as GPL compatible are assumed to be proprietary.
  2: 'F' if any module was force loaded by "insmod -f", ' ' if all modules were loaded normally.
  3: 'S' if the oops occurred on an SMP kernel running on hardware that hasn't been certified as safe to run multiprocessor. Currently this occurs only on various Athlons that are not SMP capable.
  4: 'R' if a module was force unloaded by "rmmod -f", ' ' if all modules were unloaded normally.
  5: 'M' if any processor has reported a Machine Check Exception, ' ' if no Machine Check Exceptions have occurred.
  6: 'B' if a page-release function has found a bad page reference or some unexpected page flags.
  7: 'U' if a user or user application specifically requested that the Tainted flag be set, ' ' otherwise.
  8: 'D' if the kernel has died recently, i.e. there was an OOPS or BUG.
  9: 'A' if the ACPI table has been overridden.
 10: 'W' if a warning has previously been issued by the kernel. (Though some warnings may set more specific taint flags.)
 11: 'C' if a staging driver has been loaded.
 12: 'I' if the kernel is working around a severe bug in the platform firmware (BIOS or similar).

 基本上,這個Tainted信息是留給內核開發者看的。用戶在使用Linux的過程中如果遇到Oops,可以把Oops的內容發送給內核開發者去debug,內核開發者根據這個Tainted信息大概可以判斷出kernel panic時內核運行的環境。如果我們只是debug自己的驅動,這個信息就沒什么意義了。

本文的這個例子非常簡單,Oops發生以后沒有造成宕機,這樣我們就可以從dmesg中查看到完整的信息。但更多的情況是Oops發生的同時系統也會宕機,此時這些出錯信息是來不及存入文件中的,關掉電源后就無法再看到了。我們只能通過其他的方式來記錄:手抄或者拍照。

還有更壞的情況,如果Oops信息過多的話,一頁屏幕顯示不全,我們怎么來查看完整的內容呢?***種方法,在grub里用vga參數指定更高的分辨率以使屏幕可以顯示更多的內容。很明顯,這個方法其實解決不了太多的問題;第二種方法,使用兩臺機器,把調試機的Oops信息通過串口打印到宿主機的屏幕上。但現在大部分的筆記本電腦是沒有串口的,這個解決方法也有很大的局限性;第三種方法,使用內核轉儲工具kdump把發生Oops時的內存和CPU寄存器的內容dump到一個文件里,之后我們再用gdb來分析問題。

開發內核驅動的過程中可能遇到的問題是千奇百怪的,調試的方法也是多種多樣,Oops是Linux內核給我們的提示,我們要用好它。 

責任編輯:龐桂玉 來源: 嵌入式Linux中文站
相關推薦

2018-11-13 12:52:50

Linux內核棧回溯

2021-01-12 12:07:34

Linux磁盤系統

2015-09-11 15:56:52

內核構建Linux

2009-12-03 19:02:05

Linux

2019-10-31 08:36:59

線程內存操作系統

2009-12-09 14:03:18

2009-12-23 11:05:28

Linux內核

2012-09-27 10:24:22

監控機房

2022-07-26 00:00:22

HTAP系統數據庫

2012-09-06 17:54:28

2014-04-17 16:42:03

DevOps

2025-06-11 01:00:00

2025-01-03 08:09:15

2010-09-07 14:54:01

PPP幀中繼

2023-11-09 08:22:38

2018-11-21 09:32:10

IT云計算

2012-02-06 13:52:33

JavaScript

2022-05-12 08:22:54

內核oopsPC

2022-08-01 11:32:57

Linux內核版本

2022-11-03 15:14:43

Linux文件權限
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 天天天操操操 | 久久久久亚洲 | 日韩在线免费播放 | 日韩欧美在线播放 | 日韩欧美国产不卡 | 在线91| 国产原创在线观看 | 精品欧美一区二区精品久久久 | 一级黄色淫片 | 国产一区二区三区四区在线观看 | а_天堂中文最新版地址 | 国产欧美精品在线观看 | 国产精品毛片无码 | 日日摸夜夜添夜夜添精品视频 | 国产一区二区在线播放 | 在线成人免费视频 | 亚洲不卡视频 | 欧美一区二区三区视频在线观看 | 欧美日本高清 | 综合成人在线 | 日本福利视频免费观看 | 69性欧美高清影院 | 国产精品久久久久一区二区三区 | 欧美 日韩 国产 成人 在线 | 国产超碰人人爽人人做人人爱 | 亚洲欧美日韩中文字幕一区二区三区 | 国产精品国产a级 | 久久久久久久久久久蜜桃 | 久久久久久中文字幕 | 国产色片 | 久草新在线 | 中文字幕av亚洲精品一部二部 | 国产精品国产精品国产专区不片 | 九九视频网 | 成人精品一区二区 | 午夜av成人 | 午夜www| 精品久久国产 | 一区二区福利视频 | 亚洲精品中文字幕在线观看 | 亚洲电影中文字幕 |