天天看點

《深入分析GCC 》——2.2 GNU gdb調試工具0 toplev_main (argc=1, argv=0xbffff434) at ../.././gcc/toplev.c:22121 main (argc=1, argv=0xbffff434) at ../.././gcc/main.c:35

本節書摘來自華章出版社《深入分析gcc 》一書中的第2章,第2.2節,作者 王亞剛 ,更多章節内容可以通路雲栖社群“華章計算機”公衆号檢視。

調試工具是代碼分析中至關重要的工具之一。在使用vim+ctags檢視代碼時,經常會遇到難以了解的部分,此時,可以借助調試工具,對代碼的運作過程進行跟蹤,通過跟蹤運作過程以及關鍵資料的變化,可以從程式執行的過程中了解源代碼的功能。

調試工具有很多種,最常用的是gnu gdb工具。下面通過一個例子,介紹如何使用gdb,這些調試指令幾乎就是筆者調試程式的所有指令,簡單且實用。關于完整的gdb的使用,請參與gnu gdb文檔,或者使用man gdb進行線上查詢。

本例主要使用gdb來跟蹤gcc的運作過程,是以,需要事先編譯gcc源代碼(編譯時需要使用-g選項),生成可執行的編譯程式cc1,下面利用gdb對cc1程式的運作進行跟蹤。

首先,可以在程式入口處設定斷點(break point):

單步跟蹤程式的執行,step指令和next指令均可以進行單步跟蹤,二者的主要差別在于step在單步執行函數代碼時,會進入被調用的函數,而next則會将函數調用看作“單步”,一次執行完一個函數的調用。對于其他代碼,step和next指令的功能基本相同。

此時可以看到,使用run指令執行程式後,程式執行到前面定義的斷點處暫停執行。

如果此時需要檢視toplev_main函數的執行細節,應該使用step指令進入該函數。

<code>(gdb) step ? 單步跟蹤</code>

<code>toplev_main (argc=1, argv=0xbffff434) at ../.././gcc/toplev.c:2212</code>

對于程式執行過程中,需要檢視某些變量的值,可以使用print指令。

檢視變量的值可以使用print指令,如果在每一條指令後都需要檢視某些變量的值,使用print顯得有些煩瑣,可以使用display指令,設定顯示的變量。

可以看出,每執行一步,變量argc的值都會輸出顯示。

當需要連續執行程式時,可以使用continue指令,程式則恢複運作,直到下一個斷點處再次暫停運作。

通常,在執行到某個斷點處時,當需要了解目前函數的調用情況時,可以使用bt指令(backtrace)。

(gdb) bt ? 顯示函數調用的堆棧

可以看出目前執行的函數為toplev_main函數,其調用者為函數main,并且這兩個函數所在的檔案及位置資訊也在bt的輸出中給出。bt指令的輸出可以很詳細地展示目前函數的調用關系,對于了解程式的執行流程非常有幫助。

另外,gdb在輸入指令時,如果輸入指令的開始部分可以完全确定一個指令時,則可以簡寫該指令,例如,一般使用者經常将指令run簡寫為r,step指令簡寫為s,next指令簡寫為n,continue指令簡寫為c等,如果使用者沒有輸入指令,直接按Enter鍵,則gdb預設會執行上一次輸入的指令。例如在單步跟蹤時,如果輸入了指令next,後續單步跟蹤則可以隻需要按[enter]鍵就可以了。這些規律,讀者可以在使用過程中不斷總結,提高調試效率。

界面如圖2-3所示,可以看到cgdb中能夠很友善地檢視源代碼。關于cgdb的使用請查閱相關文檔,不再贅述。

繼續閱讀