Linux核心調試之Oops資訊

來源:互聯網
上載者:User

Linux核心調試之Oops資訊

Oops這個英文單詞的意思是“哎呀”,當核心出錯時(比如訪問非法地址),輸出的資訊就成為Oops資訊,下面用一個例子來介紹一下Oops資訊:

例子:為了測試Oops資訊,這裡我們可以任意選擇一個核心檔案做測試,我以i2c為例:

1.
修改linux原始碼/drivers/i2c/i2c-core.c
在函數static int __init i2c_init(void)的開頭添加如下語句:

int * ptest = NULL;*ptest = 0xabcd;

如下:


Linux核心執行到這裡就會出錯,產生Oops資訊

2.
然後在menuconfig中將i2c編譯進核心:
make menuconfig
在Device Drivers中選擇I2C support,把I2C編譯進核心

3.
重新編譯核心,然後用該核心啟動

4.
果然出現了Oops資訊啦~~如:

中的從第7行Bug開始到最後就是Oops資訊

5.

為了將Oops資訊中的機器碼地址和源檔案相對應,我們還要將編譯好的核心鏡像反組譯碼以便對照,但由於我們之前用make bzImage命令來產生bzImage核心壓縮鏡像,無法反組譯碼,所以我們運行如下命令:

make vmlinux                    表示對產生的核心鏡像不壓縮


這樣產生的核心鏡像大約150M!



6.

將第5步產生的無壓縮的核心鏡像反組譯碼:

objdump -D vmlinux > vmlinux.dis


產生的vmlinux.dis大約500M!呵呵,如下:

vmlinux:     file format elf32-i386Disassembly of section .text:c1000000 <_text>:c1000000:       f6 86 11 02 00 00 40    testb  $0x40,0x211(%esi)c1000007:       75 14                   jne    c100001d <_text+0x1d>c1000009:       0f 01 15 16 4e 6a 01    lgdtl  0x16a4e16c1000010:       b8 18 00 00 00          mov    $0x18,%eaxc1000015:       8e d8                   mov    %eax,%dsc1000017:       8e c0                   mov    %eax,%esc1000019:       8e e0                   mov    %eax,%fsc100001b:       8e e8                   mov    %eax,%gsc100001d:       fc                      cldc100001e:       31 c0                   xor    %eax,%eaxc1000020:       bf 00 90 7a 01          mov    $0x17a9000,%edic1000025:       b9 5c b8 83 01          mov    $0x183b85c,%ecxc100002a:       29 f9                   sub    %edi,%ecxc100002c:       c1 e9 02                shr    $0x2,%ecxc100002f:       f3 ab                   rep stos %eax,%es:(%edi)c1000031:       bf e0 99 73 01          mov    $0x17399e0,%edic1000036:       b9 00 04 00 00          mov    $0x400,%ecxc100003b:       fc                      cldc100003c:       f3 a5                   rep movsl %ds:(%esi),%es:(%edi)c100003e:       8b 35 08 9c 73 01       mov    0x1739c08,%esic1000044:       21 f6                   and    %esi,%esic1000046:       74 0c                   je     c1000054 <_text+0x54>c1000048:       bf 00 73 73 01          mov    $0x1737300,%edic100004d:       b9 00 02 00 00          mov    $0x200,%ecxc1000052:       f3 a5                   rep movsl %ds:(%esi),%es:(%edi)c1000054:       66 81 3d e6 9b 73 01    cmpw   $0x207,0x1739be6c100005b:       07 02c100005d:       72 1c                   jb     c100007b <default_entry>c100005f:       a1 1c 9c 73 01          mov    0x1739c1c,%eaxc1000064:       3d 04 00 00 00          cmp    $0x4,%eaxc1000069:       73 0e                   jae    c1000079 <lguest_entry>c100006b:       8b 04 85 c0 72 73 01    mov    0x17372c0(,%eax,4),%eaxc1000072:       2d 00 00 00 c0          sub    $0xc0000000,%eaxc1000077:       ff e0                   jmp    *%eax               ..................................................





下面開始詳細介紹Oops資訊:


BUG: unable to handle kernel NULL pointer dereference at (null)

這是Oops資訊的字串說明,說明我們訪問了NULL指標



IP: [<c172f60b>] i2c_init+0x9/0x63

<c172f60b>表示核心錯誤處的ip指標,在vmlinux.dis中搜尋“c172f60b”,找到如下:

c172f5fe:       5e                      pop    %esic172f5ff:       5f                      pop    %edic172f600:       5d                      pop    %ebpc172f601:       c3                      retc172f602 <i2c_init>:c172f602:       55                      push   %ebpc172f603:       b8 20 c0 6d c1          mov    $0xc16dc020,%eaxc172f608:       89 e5                   mov    %esp,%ebpc172f60a:       53                      push   %ebxc172f60b:       c7 05 00 00 00 00 cd    movl   $0xabcd,0x0c172f612:       ab 00 00c172f615:       e8 c6 92 bd ff          call   c13088e0 <bus_register>c172f61a:       85 c0                   test   %eax,%eaxc172f61c:       89 c3                   mov    %eax,%ebxc172f61e:       75 40                   jne    c172f660 <i2c_init+0x5e>c172f620:       b8 67 ee 63 c1          mov    $0xc163ee67,%eaxc172f625:       e8 36 ab bd ff          call   c130a160 <class_compat_register>c172f62a:       85 c0                   test   %eax,%eaxc172f62c:       a3 d4 76 83 c1          mov    %eax,0xc18376d4c172f631:       74 1e                   je     c172f651 <i2c_init+0x4f>

這正好是在i2c_init函數中。



i2c_init+0x9/0x63

表示出錯的是在i2c_init函數的起始地址(0xc172f602)位移0x9的位置,而i2c_init函數的大小為0x63個位元組,出錯處的ip=c172f60b,正好等於0xc172f602+0x9



Pid: 1

發生錯誤的進程ID



[    0.992003] EIP: 0060:[<c172f60b>] EFLAGS: 00010246 CPU: 0                   [    0.992003] EIP is at i2c_init+0x9/0x63                                      [    0.992003] EAX: c16dc020 EBX: c1785e34 ECX: 00000000 EDX: 00000000          [    0.992003] ESI: c16fe164 EDI: 00000000 EBP: df071f98 ESP: df071f94          [    0.992003]  DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068                    [    0.992003] Process swapper (pid: 1, ti=df070000 task=df068000 task.ti=df070)

發生錯誤時的各個寄存器的值,其中的CPU: 0表示發生錯誤的CPU編號,對於單一處理器系統來說,編號為0



[    1.240004] Call Trace:[    1.240004]  [<c1001272>] ? do_one_initcall+0x32/0x1a0[    1.240004]  [<c172f602>] ? i2c_init+0x0/0x63[    1.240004]  [<c17018d9>] ? kernel_init+0x12d/0x183[    1.240004]  [<c17017ac>] ? kernel_init+0x0/0x183[    1.240004]  [<c1003e67>] ? kernel_thread_helper+0x7/0x10

發生錯誤時的堆棧調用,最下面的是最上層的調用




Code: 89 18 83 7d ec 00 0f 85 64 ff ff ff 31 db b8 00 c0 6d c1 e8

出錯指令附近的指令的機器碼


利用上面這些資訊,我們就可以很快的找到錯誤的位置啦~~


完成!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.