在 Linux 中調試 C 程序的福音——gdb

若是你是 C/C++ 程序員,或者使用 Fortran 和 Modula-2 編程語言開發軟件,那麼你將會很樂意知道有這麼一款優秀的調試器 - GDB - 能夠幫你更輕鬆地調試代碼 bug 以及其它問題。在這篇文章中,咱們將討論一下 GDB 調試器的基礎知識,包括它提供的一些有用的功能/選項。html

在 Linux 中調試 C 程序的福音——gdb在 Linux 中調試 C 程序的福音——gdb

在咱們開始以前,值得一提的是,文章中的全部說明和示例都已經在 Ubuntu 14.04 LTS 中測試過。教程中的示例代碼都是 C 語言寫的;使用的 shell 爲 bash(4.3.11);GDB 版本爲 7.7.1。linux

GDB 調試器基礎程序員

通俗的講,GDB 可讓你看到程序在執行過程時的內部流程,並幫你明確問題的所在。咱們將在下一節經過一個有效的示例來討論 GDB 調試器的用法,但在此以前,咱們先來探討一些以後對你有幫助的基本要點。shell

首先,爲了可以順利使用相似 GDB 這樣的調試器,你必須以指定的方式編譯程序,讓編譯器產生調試器所需的調試信息。例如,在使用 gcc 編譯器(咱們將在本教程以後的章節用它來編譯 C 程序示例)編譯代碼的時候,你須要使用-g 命令行選項。編程

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

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

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-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 調試你的程序。

本文地址:http://www.linuxprobe.com/linux-gdb-c.html

相關文章
相關標籤/搜索