首頁 > 系統教程 > Linux > 主體

在 Linux 中調試 C 程式的福音-gdb

王林
發布: 2024-02-11 20:12:02
轉載
960 人瀏覽過

每個程式設計師,無論經驗如何豐富,都無法完全避免軟體中出現bug的情況。因此,排查和修復bug成為軟體開發週期中至關重要的任務之一。雖然有許多方法可以用來排查bug,例如測試和程式碼自審,但專用偵錯器軟體也可以幫助準確地定位問題所在,以便進行修復。

對於那些使用C/C 程式語言或Fortran和Modula-2開發軟體的程式設計師來說,有一款優秀的調試工具——GDB,將會是他們的福音。 GDB不僅可以幫助程式設計師更輕鬆地偵錯程式碼中的bug和其他問題,而且還提供了許多有用的功能和選項。在本文中,我們將討論一些GDB偵錯器的基礎知識,以及它所提供的一些實用功能和選項。

在 Linux 中调试 C 程序的福音——gdb

在我們開始之前,值得一提的是,文章中的所有說明和範例都已經在 Ubuntu 14.04 LTS 中測試過。教程中的範例程式碼都是 C 語言寫的;使用的 shell 為 bash(4.3.11);GDB 版本為 7.7.1。

GDB 偵錯器基礎

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

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

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

下一步,確保在你的系統中已經安裝 GDB 偵錯器。如果沒有安裝,而且你使用的是基於 Debian 的系統(如 Ubuntu),那麼你就可以使用以下命令輕鬆安裝該工具:

sudo apt-get install gdb
登入後複製

在其他發行版上的安裝方法,請看這裡。

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

gdb [可执行程序的名称]
登入後複製

這樣做會初始化 GDB 偵錯器,但你的執行程式此時還不會被啟動。在這個時候你就可以定義調試相關的設定。例如,你可以在特定行或函數中設定一個斷點讓 GDB 在該行暫停程式的執行。

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

run
登入後複製
登入後複製

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

run [参数]
登入後複製

GDB 提供了許多有用的指令,在調試的時候總是能派的上用場。我們將在下一節討論其中一部分命令。

GDB 偵錯器用例

#現在我們對 GDB 及其用法有了基本的概念。因此,讓我們舉例來應用所學的知識。這是一段範例程式碼:

#include 
int main()
{
    int out = 0, tot = 0, cnt = 0;
    int val[] = {5, 54, 76, 91, 35, 27, 45, 15, 99, 0};

    while(cnt 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)
登入後複製

如上所示,值 5被打印出来了。这个时候一切都还是正常的。让调试器继续执行程序直到命中下一个断点,可以通过使用 c 命令来完成:

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 调试器有一定的学习难度,但是它很值得你下功夫学习。

以上是在 Linux 中調試 C 程式的福音-gdb的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:lxlinux.net
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!