Linux中國

在 Linux 中如何使用 gdb 調試 C 程序

在我們開始之前,值得一提的是,文章中的所有說明和示例都已經在 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 <stdio.h>

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

    while(cnt < 10)
    {
        out = val[cnt];
        tot = tot + 0xffffffff/out;
        cnt++;
    }

    printf("n Total = [%d]n", tot);
    return 0;
}

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

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

$ ./gdb-test
Floating 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 調試器有一定的學習難度,但是它很值得你下功夫學習。

via: https://www.howtoforge.com/tutorial/how-to-debug-c-programs-in-linux-using-gdb/

作者:Ansh 譯者:zhb127 校對:jasminepeng

本文由 LCTT 原創編譯,Linux中國 榮譽推出


本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive

對這篇文章感覺如何?

太棒了
0
不錯
0
愛死了
0
不太好
0
感覺很糟
0
雨落清風。心向陽

    You may also like

    Leave a reply

    您的郵箱地址不會被公開。 必填項已用 * 標註

    這個站點使用 Akismet 來減少垃圾評論。了解你的評論數據如何被處理

    More in:Linux中國

    Linux中國

    捐贈 Let&apos;s Encrypt,共建安全的互聯網

    隨著 Mozilla、蘋果和谷歌對沃通和 StartCom 這兩家 CA 公司處罰落定,很多使用這兩家 CA 所簽發證書的網站紛紛尋求新的證書籤發商。有一個非盈利組織可以為大家提供了免費、可靠和安全的 SSL 證書服務,這就是 Let's Encrypt 項目。現在,它需要您的幫助
    Linux中國

    關於Linux防火牆iptables的面試問答

    Nishita Agarwal是Tecmint的用戶,她將分享關於她剛剛經歷的一家公司(印度的一家私人公司Pune)的面試經驗。在面試中她被問及許多不同的問題,但她是iptables方面的專家,因此她想分享這些關於iptables的問題和相應的答案給那些以後可能會進行相關面試的人。 所有的問題和相應的答案都基於Nishita Agarwal的記憶並經過了重寫。 嗨,朋友!我叫Nishita Agarwal。我已經取得了理學學士學位,我的專業集中在UNIX和它的變種(BSD,Linux)。它們一直深深的吸引著我。我在存儲方面有1年多的經驗。我正在尋求職業上的變化,並將供職於印度的P
    Linux中國

    Lets Encrypt 已被所有主流瀏覽器所信任

    旨在讓每個網站都能使用 HTTPS 加密的非贏利組織 Lets Encrypt 已經得了 IdenTrust的交叉簽名,這意味著其證書現在已經可以被所有主流的瀏覽器所信任。從這個裡程碑事件開始,訪問者訪問使用了Lets Encrypt 證書的網站不再需要特別配置就可以得到 HTTPS 安全保護了。 Lets Encrypt 的兩個中級證書 ...