linux內核oops調試跟蹤

當內核出現類似用戶空間的 Segmentation fault 時,oops會被打印到控制檯和寫入內核log緩衝區。
下面來製造一個oops,程序如下:

#include <linux/init.h>
#include <linux/module.h>

static int __init test_init(void)
{
        char *tmp = NULL;

        *tmp = 0x1;

        return 0;
}

static void __exit test_exit(void)
{
        return;
}

module_init(test_init);
module_exit(test_exit);

MODULE_LICENSE("GPL v2");

如上,在 test_init() 函數中存在空指針錯誤,在加載模塊時,內核的oops打印如下:

[   28.142547] Unable to handle kernel NULL pointer dereference at virtual address 00000000
[   28.151618] pgd = ed8b8000
[   28.154632] [00000000] *pgd=7bd08835
[   28.158643] Internal error: Oops: 817 [#1] PREEMPT SMP ARM
[   28.164753] Modules linked in: test(+) 8189fs
[   28.192879] CPU: 0 PID: 1429 Comm: insmod Not tainted 4.9.118 #2034
[   28.199855] Hardware name: arm
[   28.203736] task: ee2167c0 task.stack: ee1ee000
[   28.208785] PC is at test_init+0x8/0x10 [test]
[   28.213737] LR is at do_one_initcall+0x140/0x174
[   28.218880] pc : [<bf1df008>]    lr : [<c0101afc>]    psr: 60000013
[   28.218880] sp : ee1efdf8  ip : 00000000  fp : c017be2c
[   28.231673] r10: ed8a3aa4  r9 : 00000001  r8 : ed8a3a80
[   28.237489] r7 : 00000000  r6 : ffffe000  r5 : c0a0400c  r4 : bf1df000
[   28.244760] r3 : 00000001  r2 : 00040976  r1 : bf1df000  r0 : 00000000
[   28.252031] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
[   28.259979] Control: 10c5387d  Table: 6d8b806a  DAC: 00000051
[   28.266377] 
[   28.266377] LR: 0xc0101a7c:
[   28.271129] 1a7c  e5983004 e1570003 0a000003 e59f1090 e28d0014 eb072890 e5887004 e10f3000
[   28.280278] 1a9c  e3130080 0a000004 e3a02040 e59f1074 e28d0014 eb072a56 f1080080 e5dd3014
[   28.289432] 1abc  e3530000 0a000006 e28d3014 e59f2058 e58d3000 e3001319 e1a03004 e59f004c
[   28.298582] 1adc  eb005a2b e59d2054 e1a00006 e5953000 e1520003 0a000003 eb005996 e12fff34
[   28.307733] 1afc  e1a06000 eaffffd8 e28dd05c e8bd83f0 c0a0400c ffffe000 c0b06000 c07c22cf
[   28.316885] 1b1c  c07c22e4 c07c2311 c07c2327 c07c233c c07c20f0 e5900184 e3500000 012fff1e
[   28.326034] 1b3c  e1a03001 e92d4010 e5912004 e1a01000 e5930000 eb0729fc e16f0f10 e1a002a0
[   28.335189] 1b5c  e8bd8010 e92d40f0 e24dd04c e59f6350 e3a02009 e59f134c e1a04000 e5963000
[   28.344343] 
[   28.344343] SP: 0xee1efd78:
[   28.349095] fd78  00000005 00190002 024000c0 c01bef54 ef0021c0 efda8880 ed844040 bf1df008
[   28.358249] fd98  60000013 ffffffff ee1efddc c010b938 00000000 bf1df000 00040976 00000001
[   28.367399] fdb8  bf1df000 c0a0400c ffffe000 00000000 ed8a3a80 00000001 ed8a3aa4 c017be2c
[   28.376548] fdd8  00000000 ee1efdf8 c0101afc bf1df008 60000013 ffffffff 00000051 bf000000
[   28.385700] fdf8  00000001 00190018 ed844040 c01c2bd8 c07dda5e c0941470 ef0021c0 60000013
[   28.394852] fe18  024000c0 c0184764 c0184764 00000000 c017be2c c01c1b5c 00000000 ef0021c0
[   28.403996] fe38  024000c0 ee1ee000 ee1efe48 c01c1d80 c0b110ec 00040976 ee1eff44 bf1dd040
[   28.413146] fe58  ee1eff44 ed844040 bf1dd088 ed8a3a80 00000001 c01847a0 bf1dd040 00000001
[   28.422303] 
[   28.422303] FP: 0xc017bdac:
[   28.427058] bdac  e3500000 1a000019 e7d43006 e353003d 1a000016 e2866001 e0844006 e1a00004
[   28.436208] bdcc  e8bd81f0 e3520001 e2455001 e1a03000 9a000010 e5d31000 e1a02005 e2830001
[   28.445361] bdec  e3510000 1afffff6 e1a04003 e2833001 e5d41000 e3510000 1affffe2 e3520001
[   28.454509] be0c  e2455001 9a000003 e1a02005 eafffff5 e1a03004 eaffffee e3a04000 eaffffe6
[   28.463658] be2c  e92d4010 e59d1008 e592000c e59d2010 e0801001 e1a00003 eb051d25 e59d0010
[   28.472811] be4c  e8bd8010 e5913024 e1a00002 e59f1008 e5932178 e2422001 ea054e60 c07d2a33
[   28.481965] be6c  e5913024 e1a00002 e59f1004 e59320f8 ea054e5a c07cb14b e5913024 e1a00002
[   28.491116] be8c  e59f1004 e59320e4 ea054e54 c07cb14b e1a03002 e59f1008 e5902020 e1a00003
[   28.500267] 
[   28.500267] R5: 0xc0a03f8c:
[   28.505020] 3f8c  00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[   28.514176] 3fac  00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[   28.523328] 3fcc  00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[   28.532480] 3fec  00000000 00000000 00000000 00000000 00000000 00000000 00000001 00000001
[   28.541630] 400c  00040976 00000009 001fb0d6 00000000 00000012 ffffffff 00000000 00000000
[   28.550781] 402c  0000000f 0000000f 0000000f 0000000f 00000000 00000000 ef00e640 ef00f840
[   28.559932] 404c  ef00e840 ef007940 ef00f640 ef00ea40 ef00f440 00000001 00000001 00000001
[   28.569081] 406c  00000000 00000028 00989680 00000000 00000000 00004e20 00000000 00000000
[   28.578225] 
[   28.578225] R6: 0xffffdf80:
[   28.582976] df80  ******** ******** ******** ******** ******** ******** ******** ********
[   28.592127] dfa0  ******** ******** ******** ******** ******** ******** ******** ********
[   28.601279] dfc0  ******** ******** ******** ******** ******** ******** ******** ********
[   28.610425] dfe0  ******** ******** ******** ******** ******** ******** ******** ********
[   28.619574] e000  ******** ******** ******** ******** ******** ******** ******** ********
[   28.628715] e020  ******** ******** ******** ******** ******** ******** ******** ********
[   28.637866] e040  ******** ******** ******** ******** ******** ******** ******** ********
[   28.647017] e060  ******** ******** ******** ******** ******** ******** ******** ********
[   28.656165] 
[   28.656165] R8: 0xed8a3a00:
[   28.660917] 3a00  c01d061c c0106ea0 00000000 00000000 00000000 00000000 00000000 00000002
[   28.670068] 3a20  00000551 ffff8ebb 5a5a5a5a 5a5a5a5a 5a5a5a5a 5a5a5a5a 5a5a5a5a 5a5a5a5a
[   28.679226] 3a40  cccccccc cccccccc cccccccc cccccccc cccccccc cccccccc cccccccc cccccccc
[   28.688380] 3a60  cccccccc cccccccc cccccccc cccccccc cccccccc cccccccc cccccccc cccccccc
[   28.697535] 3a80  ed8a2f40 00000001 ee2a2180 00000124 00000024 bf1dd004 c017be2c 00000000
[   28.706686] 3aa0  00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[   28.715834] 3ac0  cccccccc ed8a3bc0 c017e45c c01c1c34 c017e45c c017ebdc c0106ea0 00000000
[   28.724982] 3ae0  00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[   28.734135] 
[   28.734135] R10: 0xed8a3a24:
[   28.738983] 3a24  ffff8ebb 5a5a5a5a 5a5a5a5a 5a5a5a5a 5a5a5a5a 5a5a5a5a 5a5a5a5a cccccccc
[   28.748136] 3a44  cccccccc cccccccc cccccccc cccccccc cccccccc cccccccc cccccccc cccccccc
[   28.757287] 3a64  cccccccc cccccccc cccccccc cccccccc cccccccc cccccccc cccccccc ed8a2f40
[   28.766436] 3a84  00000001 ee2a2180 00000124 00000024 bf1dd004 c017be2c 00000000 00000000
[   28.775585] 3aa4  00000000 00000000 00000000 00000000 00000000 00000000 00000000 cccccccc
[   28.784741] 3ac4  ed8a3bc0 c017e45c c01c1c34 c017e45c c017ebdc c0106ea0 00000000 00000000
[   28.793892] 3ae4  00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[   28.803046] 3b04  00000000 00000000 00000000 00000595 ffff95ce c027f4ec c027f4ec c027f558
[   28.812201] Process insmod (pid: 1429, stack limit = 0xee1ee210)
[   28.818890] Stack: (0xee1efdf8 to 0xee1f0000)
[   28.823739] fde0:                                                       00000001 00190018
[   28.832852] fe00: ed844040 c01c2bd8 c07dda5e c0941470 ef0021c0 60000013 024000c0 c0184764
[   28.841967] fe20: c0184764 00000000 c017be2c c01c1b5c 00000000 ef0021c0 024000c0 ee1ee000
[   28.851077] fe40: ee1efe48 c01c1d80 c0b110ec 00040976 ee1eff44 bf1dd040 ee1eff44 ed844040
[   28.860190] fe60: bf1dd088 ed8a3a80 00000001 c01847a0 bf1dd040 00000001 bf1dd040 ee1eff44
[   28.869302] fe80: 00000001 c017e4fc bf1dd04c 00007fff bf1dd040 c017bf74 00000000 f1928000
[   28.878414] fea0: c017be9c c0701c6c f1928a44 bf1dd1ac b6ef00e0 00000003 ed836f40 ffffffff
[   28.887527] fec0: 00000000 00000000 00000000 00000000 00000000 00000000 6e72656b 00006c65
[   28.896640] fee0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[   28.905751] ff00: 00000000 00000000 00000000 00000000 00000000 00040976 00000000 00000a94
[   28.914861] ff20: 00023c14 00000000 f1928a94 ee1ee000 b6ef00e0 00000051 00000000 c017ebdc
[   28.923975] ff40: 00000000 f1928000 00000a94 f1928724 f192863c f192854c 000001c0 00000200
[   28.933088] ff60: 00000000 00000000 00000000 00000300 00000014 00000015 0000000d 00000000
[   28.942202] ff80: 0000000b 00000000 00000000 00000000 00000004 00000080 c0107088 ee1ee000
[   28.951312] ffa0: 00000000 c0106ea0 00000000 00000000 00023180 00000a94 b6ef00e0 00005d01
[   28.960426] ffc0: 00000000 00000000 00000004 00000080 00000a94 00000000 00000020 00000000
[   28.969535] ffe0: be9ccc3c be9ccc20 00011adc b6f3a110 60000010 00023180 5a5a5a5a 5a5a5a5a
[   28.978668] [<bf1df008>] (test_init [test]) from [<c0101afc>] (do_one_initcall+0x140/0x174)
[   28.987978] [<c0101afc>] (do_one_initcall) from [<c01847a0>] (do_init_module+0x54/0x37c)
[   28.996998] [<c01847a0>] (do_init_module) from [<c017e4fc>] (load_module+0x15ec/0x1bb0)
[   29.005920] [<c017e4fc>] (load_module) from [<c017ebdc>] (SyS_init_module+0x11c/0x128)
[   29.014747] [<c017ebdc>] (SyS_init_module) from [<c0106ea0>] (ret_fast_syscall+0x0/0x48)
[   29.023762] Code: bad PC value
[   29.027207] ---[ end trace b80675877b6d72fb ]---

oops信息解讀

  1. 一段文本描述信息
    比如類似“Unable to handle kernel NULL pointer dereference at virtual address 00000000”的信息,它說明了發生的是哪類錯誤。
  2. Oops 信息的序號
    比如是第 1 次、第 2 次等。這些信息與下面類似,中括號內的數據表示序號。Internal error: Oops: 805 [#1]
  3. 內核中加載的模塊名稱,也可能沒有,以下面字樣開頭。
    Modules linked in:
  4. 發生錯誤的 CPU 的序號,對於單處理器的系統,序號爲 0,比如:
    CPU: 0
    Not tainted (2.6.22.6 #36)
  5. 發生錯誤時 CPU 的各個寄存器值。
  6. 當前進程的名字及進程 ID,比如:
    Process swapper (pid: 1, stack limit = 0xc0480258)
    這並不是說發生錯誤的是這個進程,而是表示發生錯誤時,當前進程是它。錯誤可能發生在內核、驅動程序,也可能就是這個進程的錯誤。
  7. 棧信息。
  8. 棧回溯信息,可以從中看出函數調用關係,形式如下:
    Backtrace:
    [] (s3c2410fb_probe+0x0/0x560) from [] (platform_drv_probe+0x20/0x24)
  9. 出錯指令附近的指令的機器碼,比如(出錯指令在小括號裏)
    Code: e24cb004 e24dd010 e59f34e0 e3a07000 (e5873000)

oops的log分析如下:

  1. 明確出錯原因:“Unable to handle kernel NULL pointer dereference at virtual address 00000000”。可知是由於非法地址訪問出錯導致的,使用了空指針。
  2. “Internal error: Oops: 817 [#1] PREEMPT SMP ARM”,oops信息的序號,比如是第 1 次、第 2 次等。這些信息與下面類似,中括號內的數據表示序號。
  3. 此時內核加載的模塊名稱,“Modules linked in:”,也是有可能沒有的。
  4. 發生錯誤的CPU序號等信息:“CPU: 0 PID: 1429 Comm: insmod Not tainted 4.9.118 #2034”。
  5. 發生錯誤時各寄存器的值。
  6. 棧信息等。

oops信息分析

明確出錯原因

由出錯信息“Unable to handle kernel NULL pointer dereference at virtual address 00000000”可知內核是因爲非法地址訪問出錯,使用了空指針

根據棧回溯信息找出函數調用關係

從內核崩潰時打印的pc寄存器可以知道發生崩潰時正在運行的函數。

[   28.208785] PC is at test_init+0x8/0x10 [test]
[   28.213737] LR is at do_one_initcall+0x140/0x174
[   28.218880] pc : [<bf1df008>]    lr : [<c0101afc>]    psr: 60000013
[   28.218880] sp : ee1efdf8  ip : 00000000  fp : c017be2c
[   28.231673] r10: ed8a3aa4  r9 : 00000001  r8 : ed8a3a80
[   28.237489] r7 : 00000000  r6 : ffffe000  r5 : c0a0400c  r4 : bf1df000
[   28.244760] r3 : 00000001  r2 : 00040976  r1 : bf1df000  r0 : 00000000
...
[   28.978668] [<bf1df008>] (test_init [test]) from [<c0101afc>] (do_one_initcall+0x140/0x174)

上面表示,do_one_initcall() 調用了 test_init() 函數,而前面的“bf1df008”是 test_init() 函數首地址偏移爲0的地址,這個函數的大小爲 0x10;而後面的“c0101afc”是 do_one_initcall() 函數首地址偏移爲0的地址,這個函數的大小爲 0x174。

結合內核源代碼和反彙編代碼定位問題

生成內核的反彙編代碼 test.dis
arm-linux-objdump -dS test.ko > test.dis

附上部分調試工具命令:

arm-linux-readelf
  • 查看是否包含debug信息: arm-linux-readelf –S hello | grep debug
  • 查看依賴庫: arm-linux-readelf –d hello
arm-linux-nm
  • 查看依賴函數: arm-linux-nm –D hello
  • 查看函數大小: arm-linux-nm –s –r hello | head -10
  • 查看函數名和行號: arm-linux-nm –l vmlinux
arm-linux-addr2line
  • 查看地址對應源碼: arm-linux-addr2line –f –e vmlinux {address}
arm-linux-objdump
  • 反彙編(包含源碼): arm-linux-objdump –dS hello
  • 查看header信息: arm-linux-objdump –x hello
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章