2012-04-16 67 views
18

如果你很幸運當你的內核模塊崩潰時,你會得到一個帶有很多信息的日誌,比如寄存器中的值等。一個這樣的信息是堆棧跟蹤(對於核心轉儲也是如此,但我最初問這個內核模塊)。就拿這個例子:如何充分利用堆棧跟蹤(從內核或核心轉儲)?

[<f97ade02>] ? skink_free_devices+0x32/0xb0 [skin_kernel] 
[<f97aba45>] ? cleanup_module+0x1e5/0x550 [skin_kernel] 
[<c017d0e7>] ? __stop_machine+0x57/0x70 
[<c016dec0>] ? __try_stop_module+0x0/0x30 
[<c016f069>] ? sys_delete_module+0x149/0x210 
[<c0102f24>] ? sysenter_do_call+0x12/0x16 

我的猜測是,+<number1>/<number2>有事情做與已經發生了誤差函數的偏移量。也就是說,通過檢查這個數字,或許看看程序集輸出,我應該能夠找出發生該錯誤的那一行(更好的是,指令)。那是對的嗎?

我的問題是,這兩個數字究竟是什麼?你如何利用它們?

回答

19
skink_free_devices+0x32/0xb0 

這意味着違例指令是從功能skink_free_devices()0xB0字節長在總的開始0x32字節。

如果用-g編譯內核啓用,那麼你可以在函數內部的行號使用工具addr2line或我們的好老gdb

像這樣的事情

$ addr2line -e ./vmlinux 0xc01cf0d1 
/mnt/linux-2.5.26/include/asm/bitops.h:244 
or 
$ gdb ./vmlinux 
... 
(gdb) l *0xc01cf0d1 
0xc01cf0d1 is in read_chan (include/asm/bitops.h:244). 
(...) 
244  return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0; 
(...) 

所以控制跳下哪裏只需將您要檢查的地址提供給addr2linegdb,他們會告訴您源文件中存在違規功能的行號 請參閱this article for全部細節

編輯:vmlinux是用於調試內核的無壓縮版本,通常發現@/lib/modules/$(uname -r)/build/vmlinux提供你已經建立從來源內核。 vmlinuz你找到/boot是壓縮的內核,也有可能在調試

+0

我不知道你可以gdb linux本身!這太棒了! – Shahbaz 2012-04-16 12:13:10

+0

雖然'vmlinux'在哪裏?我認爲這將是Linux內核本身(在/ boot中),但是'vmlinuz ...'和addr2line說「文件格式不被識別」雖然沒有什麼大不了,因爲我對自己的模塊更感興趣。 – Shahbaz 2012-04-16 12:15:14

+0

@Shahbaz vmlinuz只是'vmlinux'的壓縮和/或剝離版本。 BOth通常會放在'/ boot'文件夾中。我現在沒有和我一起檢查我的linux系統。谷歌周圍的兩個:)這裏有一些首發。 [One](http://superuser.com/questions/62575/where-is-vmlinux-on-my-ubuntu-installation)和[Two](http://superuser.com/questions/298826/how-do -i-uncompress-vmlinuz-to-vmlinux) – 2012-04-16 12:23:37

1

對於Emacs用戶有用,here的是一個主要的模式,輕鬆堆棧跟蹤中跳來跳去(使用addr2line內部)。

免責聲明:我寫了:)

+0

現在只需爲ViM創建一個... – Shahbaz 2012-11-01 14:55:49

+0

有一些vim(對於necro抱歉):https://github.com/rzwisler/oops_trace.vim/blob/master/plugin/oops_trace.vim – stellarhopper 2015-02-10 01:13:08