2014-02-26 16 views
3

我們都知道內聯函數可以使調試更加棘手,因爲它們可以從堆棧跟蹤等中消除。但假設我想從gdb中調用內聯函數,並且知道其名稱和參數。我想我應該能夠做到這一點,但我得到這個:可能調用gdb中的內聯函數和/或使用GCC發出它們?

Cannot evaluate function -- may be inlined 

我以前nm列出在我使用的共享庫的符號,並發現我要呼叫的功能在那裏。沒有什麼大驚喜。我想要的是一種生成這些內聯函數的可見定義的方法。我可以訪問當前包含內聯定義的頭文件,但我無法真正修改這些頭文件。也許有一些方法可以告訴編譯器發佈它在翻譯單元中看到的所有內聯函數的定義?或者其他一些技巧,可以更容易地調用和檢查gdb中的內聯函數的結果?

我在Linux上使用GCC 4.7.2和GDB 7.5.1。而且我不能切換到非優化版本,因爲我正在從生產中調試核心轉儲(在開發中,我只是關閉優化,然後事情就更容易了)。

回答

4

一種方式是包括碼取函數的地址。還有一個選項,你可以給gcc。從the gcc documentation on inline functions

當一個函數內聯和靜態的,如果對函數的所有調用 集成到調用,並且從未使用過該函數的地址,然後 函數自身的彙編代碼不會被引用。在這種情況下,除非您指定選項 -fkeep-inline-functions,否則GCC不會 實際輸出該函數的彙編程序代碼。

+0

我有很多內聯函數,我想保留,所以不希望需要明確地採取每個地址。所以我非常喜歡你的'gcc -fkeep-inline-functions'建議。它的工作原理!但另一方面,它使我的可執行文件大50%(可見符號的數量增加了200%)。如果有一種方法可以指定一個目錄或一組文件來應用保留內聯,並省略其餘部分,那將會很好。但是這可能太多問了嗎? –

+0

你的構建系統應該能夠幫助解決這個問題。使用'make',每個目錄的'Makefile'可以有'CFLAGS + = -fkeep-inline-functions'這樣的類似的對象。 –

+0

對不起,我的意思是我想從目錄X中的#includes保持內聯,但是忽略它們(例如/ usr/include和其他)。 –

1

使用GCC選項-gdwarf-2構建您的項目可能對此有所幫助。

根據GDB文檔中11.1 Inline Functions

廣發行,以支持內聯函數,編譯器必須記錄有關的調試信息內聯信息 - 使用矮2格式做這個海灣合作委員會等幾個編譯器做也。 gdb在使用矮人時只支持內聯函數2. 4.1之前版本的gcc不會發出兩個必需的屬性('DW_AT_call_file'和'DW_AT_call_line'); gdb不會顯示帶有早期版本的gcc的內聯函數調用。它將調用者中的內聯函數的參數和局部變量顯示爲局部變量。

還見得到編譯器生成一個內聯函數的可調用版本3.9 Options for Debugging Your Program or GCC