在 Linux 中除錯 C 程式的福音 gdb

2022-06-18 20:42:08 字數 3225 閱讀 5653

如果你是 c/c++ 程式設計師,或者使用 fortran 和 modula-2 程式語言開發軟體,那麼你將會很樂意知道有這麼一款優秀的偵錯程式 - gdb - 可以幫你更輕鬆地除錯** bug 以及其它問題。在這篇文章中,我們將討論一下 gdb 偵錯程式的基礎知識,包括它提供的一些有用的功能/選項。

在我們開始之前,值得一提的是,文章中的所有說明和示例都已經在 ubuntu 14.04 lts 中測試過。教程中的示例**都是 c 語言寫的;使用的 shell 為 bash(4.3.11);gdb 版本為 7.7.1。

gdb 偵錯程式基礎

通俗的講,gdb 可以讓你看到程式在執行過程時的內部流程,並幫你明確問題的所在。我們將在下一節通過乙個有效的示例來討論 gdb 偵錯程式的用法,但在此之前,我們先來**一些之後對你有幫助的基本要點。

首先,為了能夠順利使用類似 gdb 這樣的偵錯程式,你必須以指定的方式編譯程式,讓編譯器產生偵錯程式所需的除錯資訊。例如,在使用 gcc 編譯器(我們將在本教程之後的章節用它來編譯 c 程式示例)編譯**的時候,你需要使用-g 命令列選項。

想要了解 gcc 編譯器手冊頁中關於 -g 命令列選項相關的內容,請看這裡。

sudo apt-get install gdb
在其他發行版上的安裝方法,請看這裡。

現在,當你按照上述的方式編譯完程式(gcc -g 命令列選項),同時也已經安裝好 gdb 偵錯程式,那麼你就可以使用以下命令讓程式在除錯模式中執行:

gdb [可執行程式的名稱]
這樣做會初始化 gdb 偵錯程式,但你的可執行程式此時還不會被啟動。在這個時候你就可以定義除錯相關的設定。例如,你可以在特定行或函式中設定乙個斷點讓 gdb 在該行暫停程式的執行。

接著,為了啟動你的程式,你必須輸入執行以下 gdb 命令:

run
在這裡,值得一提的是,如果你的程式需要一些命令列引數,那麼你可以在這裡指定這些引數。例如:

run [引數]
gdb 提供了很多有用的命令,在除錯的時候總是能派的上用場。我們將在下一節討論其中一部分命令。

gdb 偵錯程式用例

現在我們對 gdb 及其用法有了基本的概念。因此,讓我們舉例來應用所學的知識。這是一段示例**:

#include int main()

; while(cnt < 10)

printf("/n total = [%d]/n", tot);

return 0;

}

簡單說明一下這段**要做什麼事。獲取 val陣列中每乙個值,將其賦值給out 變數,然後將tot 之前的值與0xffffffff/out的結果值累加,賦值給 tot 變數。

這裡遇到的問題是,當執行這段**編譯後的可執行程式時,產生以下錯誤:

$ ./gdb-testfloating point exception (core dumped)
因此,要除錯這段**,第一步是使用

-g選項編譯程式。命令如下:

gcc -g -wall gdb-test.c -o gdb-test
接著,讓我們執行 gdb 偵錯程式並指定要除錯的可執行程式。命令如下:

gdb ./gdb-test
現在,我剛才得到的錯誤是 floating point exception,大部分人可能已經知道,這是因為 n % x,當 x 為 0 時導致的錯誤。所以,考慮到這一點,我在 11 行**除法運算的位置處新增了乙個斷點。如下:

(gdb)&;break 11
注意 (gdb) 是偵錯程式的提示資訊,我只輸入了break 11 命令。

現在,讓 gdb 開始執行程式:

run
當斷點第一次被命中時,gdb 顯示如下輸出:

breakpoint 1, main () at gdb-test.c:11

11 tot = tot + 0xffffffff/out;

(gdb)

正如你所看到的那樣,偵錯程式會顯示斷點所在的行**。現在,讓我們列印出此時out 的值。如下:

(gdb) print out

$1 = 5

(gdb)

c
重複上述操作,直到 out值變為0 時。

...

......

breakpoint 1, main () at gdb-test.c:11

11 tot = tot + 0xffffffff/out;

(gdb) print out

$2 = 99

(gdb) c

continuing.

breakpoint 1, main () at gdb-test.c:11

11 tot = tot + 0xffffffff/out;

(gdb) print out

$3 = 0

(gdb)

現在,為了進一步確認問題,我使用 gdb 的s (或 step) 命令代替 c 命令。因為,我只想讓當前程式在第 11 行之後暫停,再一步步執行,看看這個時候是否會發生崩潰。

以下是執行之後輸出資訊:

(gdb) s

program received signal sigfpe, arithmetic exception.

0x080484aa in main () at gdb-test.c:11

11 tot = tot + 0xffffffff/out;

是的,如上輸出的第一行內容所示,這就是丟擲異常的地方。當我再次嘗試執行s 命令時,問題最終也得到了確認:

(gdb) s

program terminated with signal sigfpe, arithmetic exception.

the program no longer exists.

通過這種方式,你就可以使用 gdb 除錯你的程式。

總結

gdb 提供了很多功能供使用者研究和使用,在這裡,我們僅僅只介紹了很少一部分內容。通過 gdb 的手冊頁可以進一步了解這個工具,當你在除錯**的時候,嘗試使用一下它。gdb 偵錯程式有一定的學習難度,但是它很值得你下功夫學習。

via: 

本文由 lctt 原創編譯,linux中國 榮譽推出

在linux中如何除錯C語言程式

在linux下面可以使用下面幾種形式對c語言進行除錯 1 gdb gdb program這是最原始的除錯方法,若非熟悉命令列,這種方式其實是比較麿人的。有興趣的可以參考一些我之前的博文。這裡再附一圖 gdbtui program比gdb的方式更加友好一些,但也不大好用。安裝ddd之後執行 安裝了ne...

Linux中C程式除錯 makefile

gcc基本語法格式 gcc 選項 原始檔 選項 目標檔案,gcc編譯c程式的過程 預處理 gcc e hello.c hello.i。e指定執行到預處理結束,下面類似。編譯 gcc s hello.i o hello.s。彙編 gcc c hello.s o hello.o。函式庫有靜態庫和動態庫兩...

在Clion中除錯ROS程式

在ros wiki 中有幾種ide的配置方法,但沒有clion的相關介紹。下面介紹一下clion的相關配置。ros clion配置 在終端中開啟jetbrains clion desktop vimjetbrains clion desktop 將檔案中exec home clion 2016.2 ...