2013-06-03 37 views
0

我目前正在調試一個內核模塊,爲此,我使用調試信息(產生kallsyms等)構建了整個內核。爲什麼缺少一些調試符號以及如何跟蹤它們?

當我嘗試nm my_module.ko時,我得到了我的模塊包含的符號列表。除了某些符號由於它們不出現在符號列表中而有些遺漏之外,一切都是好的。我對此的感覺是相關功能被自動內聯。

無論如何,當用qemu-kgdb/gdb運行內核時,我能夠看到「missing」函數被調用。這意味着編譯器沒有把它擦掉,因爲它從來沒有用在任何代碼路徑中(因此我的「感覺」)。

因爲符號沒有出現,所以我不能在它上面設置一個斷點,並且gdb不會展開它,這樣我就可以看到正在運行的代碼路徑 - 理解我不知道如何告訴gdb展開它
不幸的是,我想看看代碼路徑的這一部分...我該怎麼做?

編輯:正如湯姆的回答表明,我嘗試使用下面的file:line語法:

我的代碼文件看起來像這樣:

int foo(int arg) // The function that I suspect to be inlined - here is line 1 
{ 
    /* Blabla */ 
    return 42; 
} 

void foo2(void) 
{ 
    foo(0); // Line 9 
} 

我試過b file.c:1,並且斷點被擊中但foo()函數未展開。 當然,我正在生成調試符號,因爲我還設置了一個斷點到foo2來檢查發生了什麼(哪一個工作正常)。

+0

您是否嘗試過在特定的行上設置斷點而不是符號?此外,您可以強制編譯器不要內聯代碼。 – Hasturkun

+0

你使用了一些剝離選項? –

回答

2

你不說你正在使用什麼版本的gdb。

非常舊版本的gdb不支持內聯函數。這在6.8和甚至7.0中都是如此 - 我不記得了。您可以查看您的gdb的NEWS文件以查看。

然後有一些版本的gdb支持內聯函數的斷點,但只使用「file:line」語法。所以,你會做什麼是查找功能在編輯器中,並找到它的行號,並輸入,如:更近

(gdb) break myfile.c:777 

版本的gdb,從7.4或7.5(我忘了)會處理「打破功能「就好了,如果」功能「被內聯。

所有這些只有在您有debuginfo可用時纔有效。所以如果你嘗試了這個,並且失敗了,或者你有一個老的gdb,或者你忘了使用-g。

gdb裏面沒有什麼好的方法來查看編譯中缺少什麼對象-g。不過,通過在.o文件上運行「readelf -WS」,並查找沒有.debug_info部分的文件,您可以很容易地從shell中看到它。

+0

'gdb --version'告訴我'GNU gdb(Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1)7.4-2012.04'。我嘗試了使用語法「file:line」的建議。當代碼路徑到達它時,斷點已被很好地註冊並被標記爲命中,但指令永遠不會「解包」。 – Rerito

+0

我不知道「unwrapped」是什麼意思,對不起。 –

+0

我的意思是調試器不會向我顯示內聯函數的內部指令,如果我使用stepi運行,我只會一遍又一遍地顯示'foo(0);'行。 – Rerito

0

設置斷點到函數的簽名行不起作用。但是將一個設置爲內聯函數的指令行解決了我的問題。例如,考慮以下函數inline_foo,在myfile中找到。Ç

inline int inline_foo(int arg) // l.1 
{ 
    int a_var = 0; 
    do_smth(&a_var); 
    do_some_other_thing(); // l.5 
    if (a_var) { 
     a_var = blob(); 
    } else { 
     a_var = blub(); 
    return a_var; // l.10 
} 

我試圖b myfile.c:1,這似乎沒有工作。但是,如果我嘗試使用b myfile.c:3,斷點由GDB處理得很好。 由於該技術與湯姆先前描述的技術相同,我會接受他的答案。

相關問題