1. 程式人生 > 其它 >LINUX KERNEL OOPS除錯及例項分析(GDB OBJDUMP指令)

LINUX KERNEL OOPS除錯及例項分析(GDB OBJDUMP指令)

LINUX KERNEL OOPS除錯及例項分析(GDB OBJDUMP指令)

異常核心模組

核心模組檔案OOPS.C

  1. #include <linux/kernel.h>
  2.   #include <linux/module.h>
  3.   #include <linux/init.h>
  4.    
  5.   static void create_oops(void)
  6.   {
  7.   *(int *)0 = 0;
  8.   }
  9.   static int __init my_oops_init(void)
  10.   {
  11.   printk("oops from the module\n");
  12.   create_oops();
  13.   return (0);
  14.   }
  15.   static void __exit my_oops_exit(void)
  16.   {
  17.   printk("Goodbye world\n");
  18.   }
  19.   module_init(my_oops_init);
  20.   module_exit(my_oops_exit);
  21.   MODULE_LICENSE("GPL");

編譯核心模組MAKEFILE

  1.   EXTRA_CFLAGS += -g
  2.   obj-m += oops.o
  3.    
  4.   all:
  5.   $(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD)
  6.   clean:
  7.   make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
  8.   rm -f modules.order Module.symvers Module.markers

備註:

        Makefile中EXTRA_CFLAGS += -g需要增加

編譯核心模擬OOPS

安裝模組INSMOD OOPS.KO,出現KILLED,由於故障不嚴重,未導致系統宕機重啟

DMESG檢視資訊可以看到OOPS資訊如下

  1.   [ 933.023020] oops: loading out-of-tree module taints kernel.
  2.   [ 933.023046] oops: module verification failed: signature and/or required key missing - tainting kernel
  3.   [ 933.023611] oops from the module
  4.   [ 933.023615] BUG: unable to handle kernel NULL pointer dereference at 0000000000000000
  5.   [ 933.023621] IP: my_oops_init+0x15/0x1000 [oops]
  6.   [ 933.023622] PGD 0 P4D 0
  7.   [ 933.023624] Oops: 0002 [#1] SMP PTI
  8.   [ 933.023626] Modules linked in: oops(OE+) vmw_vsock_vmci_transport vsock crct10dif_pclmul crc32_pclmul ghash_clmulni_intel pcbc snd_ens1371 snd_ac97_codec gameport aesni_intel ac97_bus snd_pcm aes_x86_64 crypto_simd snd_seq_midi glue_helper snd_seq_midi_event joydev cryptd snd_rawmidi vmw_balloon input_leds serio_raw snd_seq snd_seq_device intel_rapl_perf shpchp snd_timer mac_hid snd i2c_piix4 soundcore vmw_vmci parport_pc ppdev lp parport autofs4 hid_generic usbhid hid psmouse vmwgfx ttm drm_kms_helper ahci libahci syscopyarea sysfillrect mptspi sysimgblt fb_sys_fops pcnet32 mii drm mptscsih mptbase scsi_transport_spi pata_acpi
  9.   [ 933.023642] CPU: 1 PID: 4198 Comm: insmod Tainted: G OE 4.15.0-123-generic #126~16.04.1-Ubuntu
  10.   [ 933.023643] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 07/29/2019
  11.   [ 933.023645] RIP: 0010:my_oops_init+0x15/0x1000 [oops]
  12.   [ 933.023646] RSP: 0018:ffffa90044b67c68 EFLAGS: 00010286
  13.   [ 933.023647] RAX: 0000000000000014 RBX: ffffffffc0645000 RCX: 0000000000000006
  14.   [ 933.023648] RDX: 0000000000000000 RSI: 0000000000000096 RDI: ffff8ed839656490
  15.   [ 933.023649] RBP: ffffa90044b67c68 R08: 0000000000021d54 R09: ffff8ed83fec8000
  16.   [ 933.023650] R10: ffffe45282d98e40 R11: 000000000000062d R12: ffffffffc0648000
  17.   [ 933.023651] R13: 0000000000000000 R14: 0000000000000001 R15: ffff8ed7a4ce3b40
  18.   [ 933.023652] FS: 00007fc14dfbe700(0000) GS:ffff8ed839640000(0000) knlGS:0000000000000000
  19.   [ 933.023653] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
  20.   [ 933.023654] CR2: 0000000000000000 CR3: 00000000a4d48001 CR4: 00000000003606e0
  21.   [ 933.023674] Call Trace:
  22.   [ 933.023680] do_one_initcall+0x55/0x1ac
  23.   [ 933.023683] ? _cond_resched+0x1a/0x50
  24.   [ 933.023686] ? kmem_cache_alloc_trace+0x165/0x1c0
  25.   [ 933.023690] do_init_module+0x5f/0x223
  26.   [ 933.023692] load_module+0x188c/0x1ea0
  27.   [ 933.023696] ? ima_post_read_file+0x83/0xa0
  28.   [ 933.023698] SYSC_finit_module+0xe5/0x120
  29.   [ 933.023700] ? SYSC_finit_module+0xe5/0x120
  30.   [ 933.023702] SyS_finit_module+0xe/0x10
  31.   [ 933.023703] do_syscall_64+0x73/0x130
  32.   [ 933.023706] entry_SYSCALL_64_after_hwframe+0x41/0xa6
  33.   [ 933.023707] RIP: 0033:0x7fc14daec599
  34.   [ 933.023708] RSP: 002b:00007ffc96df4ce8 EFLAGS: 00000206 ORIG_RAX: 0000000000000139
  35.   [ 933.023709] RAX: ffffffffffffffda RBX: 0000563624a281f0 RCX: 00007fc14daec599
  36.   [ 933.023710] RDX: 0000000000000000 RSI: 0000563622b0426b RDI: 0000000000000003
  37.   [ 933.023711] RBP: 0000563622b0426b R08: 0000000000000000 R09: 00007fc14ddb1ea0
  38.   [ 933.023712] R10: 0000000000000003 R11: 0000000000000206 R12: 0000000000000000
  39.   [ 933.023712] R13: 0000563624a27130 R14: 0000000000000000 R15: 0000000000000000
  40.   [ 933.023714] Code: <c7> 04 25 00 00 00 00 00 00 00 00 31 c0 5d c3 00 00 00 00 00 00 00
  41.   [ 933.023722] RIP: my_oops_init+0x15/0x1000 [oops] RSP: ffffa90044b67c68
  42.   [ 933.023723] CR2: 0000000000000000
  43.   [ 933.023725] ---[ end trace b763de4574e1f5e6 ]---

問題分析

OOPS資訊分析

[  933.023624] Oops: 0002 [#1] SMP PTI

0002 :是錯誤碼

#1 :Oops發生的次數 

This is the error code value in hex. Each bit has a significance of its own:

  • bit 0 == 0 means no page found, 1 means a protection fault
  • bit 1 == 0 means read, 1 means write
  • bit 2 == 0 means kernel, 1 means user-mode
  • [#1] — this value is the number of times the Oops occurred. Multiple Oops can be triggered as a cascading effect of the first one.
[  933.023642] CPU: 1 PID: 4198 Comm: insmod Tainted: G           OE    4.15.0-123-generic #126~16.04.1-Ubuntu

 這個表示Oops是發生在CPU1上,當執行程序4198 insmod的時候出現的問題 

關鍵資訊如下,這裡提示在操作函式my_oops_init的時候出現異常,偏移地址0x15

[  933.023621] IP: my_oops_init+0x15/0x1000 [oops]

 問題定位

從以上分析可以看出,最關鍵資訊如下:

  1.   [ 933.023621] IP: my_oops_init+0x15/0x1000 [oops]
  2.   [ 933.023722] RIP: my_oops_init+0x15/0x1000 [oops] RSP: ffffa90044b67c68

由此可以看出核心執行到my_oops_init+0x15/0x1000這個地址的時候出現異常,我們只需要找到這個地址對應的程式碼即可

格式為 +偏移/長度
my_oops_init指示了實在my_oops_init中出現的異常
0x15表示出錯的偏移位置
0x1000表示my_oops_init函式的大小 

方法一:GDB直接檢視異常程式碼

由於是驅動出現的問題, 那麼gdb直接除錯驅動的 ko 檔案, 如果是源核心出現的 OOPS, 那麼只能用 gdb 對 vmlinux(核心根目錄下) 檔案進行除錯 

  1.   gdb oops.ko或者gdb oops.o
  2.   l*(my_oops_init+0x15)
  3.    
  4.   格式:
  5.   l*(函式名+偏移地址)或者(函式入口地址+偏移地址)

備註:

       ko檔案一定要是和報錯的是ko是同一個,如果編譯到核心可以使用.o檔案,如下所示

可以看到gdb提示是第7行程式碼異常,此方法也適合核心Oops,只需要將ko檔案替換為vmlinux檔案即可

方法二:GDB反彙編程式碼獲取地址直接轉化對應原始碼

對於驅動來說, 可以從/sys/module/對應驅動名稱/sections/.init.text 查詢到對應的地址資訊

  1.   cat /sys/module/oops/sections/.init.text
  2.   0xffffffffc0648000
  3.   gdb oops.ko
  4.   #加符號檔案新增到偵錯程式
  5.   add-symbol-file oops.o 0xffffffffc0648000
  6.   #將my_oops_init函式反彙編得到虛擬地址資訊
  7.   disassemble my_oops_init
  8.   #列出對應程式碼資訊
  9.   l*(函式名+偏移地址)

方法三:OBJDUMP反彙編

objdump -S oops.o

從報錯log可以找到出錯的機器碼如下:

[  933.023714] Code: <c7> 04 25 00 00 00 00 00 00 00 00 31 c0 5d c3 00 00 00 00 00 00 00 

參考資料

https://cloud.tencent.com/developer/article/1463579

 https://kernel.blog.csdn.net/article/details/73715860

版權宣告:本文為wgl307293845原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連結和本宣告。 本文連結:https://blog.csdn.net/wgl307293845/article/details/109767808  

本公司成本價甩賣工控主機板,歡迎大家選購:
PCIE匯流排轉八串列埠卡,PCIE匯流排轉IO卡,瑞芯微3568板卡,寒武紀CE3226攝像頭板卡,龍芯3A4000工控板卡,龍芯3A5000工控板卡,海光3250工控板卡,飛騰FT-2000/4板卡

聯絡方式:
電話、微信:15918785568 羅生
Email:[email protected]
公眾號:開發之美