天天看點

Linux下C語言的調試

調試是每個程式員都會面臨的問題. 如何提高程式員的調試效率, 更好更快地定位程式中的問題進而加快程式開發的進度, 是大家共同面對的問題. 可能windows使用者順口就會說出:用vc呗 :-) , 它提供了設定斷點, 單步跟蹤等的圖形界面, 使調試起來直覺易用. 但​​linux​​使用者可能要生悶氣了 o:-) : 難道我們linux程式員就隻能使用原始的調試方法, 在代碼中加入printf資訊嗎?難道linux下就沒有好的​​c語言​​調試工具嗎?

當然不是了. gnu早就組織開發了一套c語言編譯器(gcc)和調試工具(gdb). gdb雖然沒有圖形化的友好界面, 但是它強大的功能也足以與微軟的vc工具相媲美, 給linux程式員帶來了福音. 下面通過一個簡單的例子, 示範一下gdb的使用流程:

示例檔案 demo.c 的源代碼如下:

編譯源檔案, 生成可執行檔案

雖然這段程式沒有錯誤, 但調試完全正确的程式可以更加了解gdb的使用流程. 接下來就啟動gdb進行調試.

注意:

gdb進行調試的是可執行檔案, 而不是”.c”源檔案, 是以, 需要先通過gcc編譯生成可執行檔案才能用gdb進行調試.

一定要加上選項”-g”, 這樣編譯出的可執行代碼中才包含調試資訊, 否則gdb無法載入該可執行檔案.

不能使用 -o2選項對可執行檔案進行優化, 因為優化之後可執行檔案裡的符号表資訊将被删除, 這樣gdb就無法找到使可執行檔案與源檔案之間的關聯了, 也就不能調試了.

(1) 啟動gdb

可以看出, 在gdb的啟動畫面中指出了gdb的版本号, 使用的庫檔案等頭資訊, 接下來就進入了由”(gdb)”開頭的指令行界面了.

(2) 檢視源檔案

在gdb中鍵入”l”(list的縮寫)可以檢視所載入的檔案, 如下所示:

可以看出, gdb列出的源代碼中明确地給出了對應的行号, 這樣就可以大大地友善代碼的定位.

(3) 設定斷點

設定斷點是調試程式中一個非常重要的手段, 它可以使程式到一定位置暫停運作. 是以,可以在該位置友善地檢視變量的值, 堆棧情況等, 進而找出代碼的症結所在.

在gdb中設定斷點非常簡單, 隻需在”b”後加入對應的行号即可(這是最常用的方式). 如下所示:

注意: 該斷點的作用是當程式運作到第 9 行時暫停(第 8 行執行完畢, 第 9 行未執行)

(4) 檢視斷點資訊

(5) 運作代碼

接下來就可運作代碼了, gdb預設從首行開始運作代碼, 可鍵入”r”(run的縮寫)即可. 若想從程式中指定的行開始運作, 可在r後面加上行号.

可以看到程式運作到斷點處就停止了.

(6) 檢視變量值

鍵入p(print的縮寫)+變量名即可檢視該變量在此時的值

注意: 這裡之是以result是一個莫名其妙的值, 是因為聲明result是沒有初始化, 其值是不固定的。

(7) 單步執行

單步運作可以使用n(next的縮寫)或者s(step的縮寫), 它們之間的差別在于: 若有函數調用的時候, s會進入該函數而n不會. 是以, s就類似于vc等工具中的”step in”, n就類似于vc等工具中的”step over”.

如果使用n指令顯示如下:

下面使用 s 指令,跟蹤進入 sum 函數:

可以看出執行 s 指令時進入了sum函數内部, 如果用 n 指令則跳過函數的調用部分

(8) 恢複程式運作

在檢視變量值以及堆棧之後, 就可以使用指令c(continue)恢複程式的正常運作了. 這時, 它會把剩餘還未執行的程式執行完, 并顯示剩餘程式的執行結果.

可以看出, 程式在運作完後退出, 之後程式處于”停止狀态”.

說明: 在gdb中, 程式的運作狀态有”運作”,”暫停”和”停止”3種. 其中”暫停”狀态是程式遇到了斷點或者觀察點, 程式暫時停止運作, 而此時函數的位址, 函數參數, 函數内的局部變量都會被壓入”棧(stack)中. 故在這種狀态下可以檢視函數的變量值等各種屬性. 但在函數處于”停止”狀态之後, “棧”就會自動撤銷, 它也就無法檢視各種資訊了

關于gdb的更多指令, 你可以在啟用gdb後, 輸入help指令檢視.

繼續閱讀