LINUX KERNEL OOPS除錯及例項分析(GDB OBJDUMP指令)
LINUX KERNEL OOPS除錯及例項分析(GDB OBJDUMP指令)
異常核心模組核心模組檔案OOPS.C
- static void create_oops(void)
- {
- *(int *)0 = 0;
- }
- static int __init my_oops_init(void)
- {
-
printk("oops from the module\n");
- create_oops();
- return (0);
- }
- static void __exit my_oops_exit(void)
- {
- printk("Goodbye world\n");
- }
- module_init(my_oops_init);
- module_exit(my_oops_exit);
- MODULE_LICENSE("GPL");
編譯核心模組MAKEFILE
- EXTRA_CFLAGS += -g
- obj-m += oops.o
- all:
- $(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD)
- clean:
- make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
- rm -f modules.order Module.symvers Module.markers
備註:
Makefile中EXTRA_CFLAGS += -g需要增加
編譯核心模擬OOPS
安裝模組INSMOD OOPS.KO,出現KILLED,由於故障不嚴重,未導致系統宕機重啟
DMESG檢視資訊可以看到OOPS資訊如下
- [
- [
- [
- [
- [
- [
- [
- [
- [
- [
- [
- [
- [
- [
- [
- [
- [
- [
- [
- [
- [
- [
- [
- [
- [
- [
- [
- [
- [
- [
- [
- [
- [
- [
- [
- [
- [
- [
- [
- [
- [
- [
- [
問題分析
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]
問題定位
從以上分析可以看出,最關鍵資訊如下:
- [
- [
由此可以看出核心執行到my_oops_init+0x15/0x1000這個地址的時候出現異常,我們只需要找到這個地址對應的程式碼即可
格式為 +偏移/長度
my_oops_init指示了實在my_oops_init中出現的異常
0x15表示出錯的偏移位置
0x1000表示my_oops_init函式的大小
方法一:GDB直接檢視異常程式碼
由於是驅動出現的問題, 那麼gdb直接除錯驅動的 ko
檔案, 如果是源核心出現的 OOPS
, 那麼只能用 gdb
對 vmlinux(核心根目錄下)
檔案進行除錯
- gdb oops.ko或者gdb oops.o
- l*(my_oops_init+0x15)
- 格式:
- l*(函式名+偏移地址)或者(函式入口地址+偏移地址)
備註:
ko檔案一定要是和報錯的是ko是同一個,如果編譯到核心可以使用.o檔案,如下所示
可以看到gdb提示是第7行程式碼異常,此方法也適合核心Oops,只需要將ko檔案替換為vmlinux檔案即可
方法二:GDB反彙編程式碼獲取地址直接轉化對應原始碼
對於驅動來說, 可以從/sys/module/對應驅動名稱/sections/.init.text
查詢到對應的地址資訊
- cat /sys/module/oops/sections/.init.text
- 0xffffffffc0648000
- gdb oops.ko
- #加符號檔案新增到偵錯程式
- add-symbol-file oops.o 0xffffffffc0648000
- #將my_oops_init函式反彙編得到虛擬地址資訊
- disassemble my_oops_init
- #列出對應程式碼資訊
- 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]
公眾號:開發之美