2010-04-15 73 views
1

我試圖調試這似乎是一個完成隊列問題行號:獲取從內核調用跟蹤

Apr 14 18:39:15 ST2035 kernel: Call Trace: 
Apr 14 18:39:15 ST2035 kernel: [<ffffffff8049b295>] schedule_timeout+0x1e/0xad 
Apr 14 18:39:15 ST2035 kernel: [<ffffffff8049a81c>] wait_for_common+0xd5/0x13c 
Apr 14 18:39:15 ST2035 kernel: [<ffffffffa01ca32b>] 
ib_unregister_mad_agent+0x376/0x4c9 [ib_mad] 
Apr 14 18:39:16 ST2035 kernel: [<ffffffffa03058f4>] ib_umad_close+0xbd/0xfd 

是否有可能將這些十六進制數到了接近行號?

+0

你是否嘗試過使用kalllsyms_all構建和詳細bug()? – user2284570 2015-04-12 14:32:04

回答

4

不完全是,但如果你有一個vmlinux的圖像內置與調試信息,(例如,在RHEL,你應該能夠安裝內核調試或內核DBG或類似的東西),你可以親近。所以假設你有可用的vmlinux文件。執行以下操作:

objdump的-S​​ vmlinux的

這將嘗試它是最難匹配的對象代碼的源代碼的各行。

例如以下C代碼:

#include <stdio.h> 
main() { 
    int a = 1; 
    int b = 2; 

    // This is a comment 

    printf("This is the print line %d\n", b); 
} 

編譯:CC -g test.c的

,然後運行objdump的-S​​上生成的可執行文件,得到了一個大的輸出描述可執行文件的各個部分inclding以下部分:

00000000004004cc <main>: 
#include <stdio.h> 
main() { 
    4004cc: 55      push %rbp 
    4004cd: 48 89 e5    mov %rsp,%rbp 
    4004d0: 48 83 ec 20    sub $0x20,%rsp 
    int a = 1; 
    4004d4: c7 45 f8 01 00 00 00 movl $0x1,-0x8(%rbp) 
    int b = 2; 
    4004db: c7 45 fc 02 00 00 00 movl $0x2,-0x4(%rbp) 

    // This is a comment 

    printf("This is the print line %d\n", b); 
    4004e2: 8b 75 fc    mov -0x4(%rbp),%esi 
    4004e5: bf ec 05 40 00   mov $0x4005ec,%edi 
    4004ea: b8 00 00 00 00   mov $0x0,%eax 
    4004ef: e8 cc fe ff ff   callq 4003c0 <[email protected]> 
} 

您可以將第一列中目標代碼的地址與堆棧跟蹤中的地址進行匹配。將它與在組件輸出中交錯的行號信息結合起來......並且您在那裏。

現在請記住,這不會總是100%成功,因爲kenrel通常編譯在-O2優化級別,編譯器會做很多代碼重新排序等。但如果您熟悉代碼你正在嘗試調試並且解密你正在工作的平臺的程序集時有一些安慰......你應該能夠確定你的大部分崩潰等。

+0

objdump!這是命令。這已經過去了幾年,我無法記住它的一生。 我做了一個objdump模塊的問題,得到了一些有用的數據。謝謝。 – 2010-04-15 21:08:23