原帖:向日葵智慧

前言

windows 的介面操作非常豐富,對程式開發也是如此,各種強大的 IDE 真是非常方便。轉入 linux 程式設計後,沒有介面,用 vim gcc 搞程式開發,一開始還真是不適應。現在用的多了,反而習慣用 linux 開發了。但是,沒法除錯程式真是太痛苦了,只能逐行加 printf。。。

其實早就聽說 linux 程式開發有 gdb 工具可以用於除錯,一直沒有去了解。今天加 printf 實在是加到崩潰,肯定要了解一下的。瞭解後,才發現,gdb 並不複雜,很容易用的工具。好用的工具肯定都是容易使用的。

gdb 是什麼,可以做什麼?

gdb 就是一個除錯工具,一般來說,GDB主要幫助你完成下面四個方面的功能:

  • 啟動你的程式,可以按照你的自定義的要求隨心所欲的執行程式。
  • 可讓被除錯的程式在你所指定的調置的斷點處停住。(斷點可以是條件表示式)
  • 當程式被停住時,可以檢查此時你的程式中所發生的事。
  • 你可以改變你的程式,將一個BUG產生的影響修正從而測試其他BUG。

gdb 除錯實戰專案,牛刀小試

c 語言小 demo

咱們先用 c 語言隨便寫一個小 demo 作為測試物件:

// 檔名 test.c
#include <stdio.h>

int GetSum(char num1, char num2)
{
    int res = 0;
    res = num1 + num2;
    return res;
}

int main()
{
    char i = 10, j = 10;
    int sum = 0;

    i ++;
    j ++;   
    sum = GetSum(i, j); 
    printf("i + j = %d\n", sum);    

    return 0;
}

很簡單的程式,如果打算使用 gdb 除錯它,記得編譯的時候加上 -g 選項。

gcc -g -Wall -o test test.c
Bash

得到可執行程式後,就可以使用 gdb 除錯了。

gdb 除錯命令

gdb 全速執行

(gdb)run,也可只輸入 r,程式會開始執行,停在第一個斷點處。
(gdb)continue,也可只輸入 c,程式繼續執行,停在下一個斷點處。

gdb 新增搜尋程式碼原始檔路徑

(gdb)directory [path],也可輸入 dir [path],將 path 新增到搜尋目錄中。

gdb 列印程式碼

gdb + 可執行程式即可進入 gdb 除錯:
輸入 l 可以打印出程式碼,如果想輸出指定行號的程式碼,可以加上數字,例如 l 5

gdb 斷點

下斷點有兩種方式:
  • (gdb)break(也可只輸入b) + 函式名
  • (gdb)break + 行號
  • (gdb)break + 條件。這個命令必須在變數i被定義之後才會成功執行,為了解決這個問題,首先在變數 i 被定義的後一行設定中斷,然後使用run命令執行程式,程式暫停後就可以使用watch i==99設定斷點了。例如
    • break 7 if i==99
    • watch i==99
檢視斷點
  • 顯示當前gdb的斷點資訊:
    (gdb) info break
  • 刪除指定的某個斷點:
    (gdb) delete breakpoint 1
  • 該命令將會刪除編號為1的斷點,如果不帶編號引數,將刪除所有的斷點
    (gdb) delete breakpoint
  • 禁止使用某個斷點
    (gdb) disable breakpoint 1
    該命令將禁止斷點1,同時斷點資訊的 (Enb)域將變為 n
  • 允許使用某個斷點
    (gdb) enable breakpoint 1
    該命令將允許斷點1,同時斷點資訊的 (Enb)域將變為 y
  • 清除原始檔中某一程式碼行上的所有斷點
    (gdb)clear number
    注:number 為原始檔的某個程式碼行的行號

變數檢查賦值編輯

  • whatis:識別陣列或變數的型別
  • ptype:比whatis的功能更強,他可以提供一個結構的定義
  • set variable = value:將值賦予變數
  • print variable = value or p variable = value : 除了顯示一個變數的值外,還可以用來賦值

單步執行編輯

  • next 不進入的單步執行
  • step 進入的單步執行如果已經進入了某函式,而想退出該函式返回到它的呼叫函式中,可使用命令finish

函式呼叫編輯

  • call name 呼叫和執行一個函式
    (gdb) call gen_and_sork(1234,1,0)
    (gdb) call printf(“abcd”)
    =4
  • finish 結束執行當前函式,顯示其返回值(如果有的話)

gdb 除錯linux程式實戰

咱們以上面的小 demo 為例。

首先看看程式碼,然後再 main 處和第 15 行下斷點

輸入 r(run) 執行,可以看出,執行停在 main 函式入口處了:

輸入 n(next) 跳過,期間可以輸入 l 檢視程式碼:

來到 GetSum 函數出,輸入 s(step into),進入 GetSum 函式:

輸入 p(print) + 變數,可以檢視變數值。

至此,基本的除錯流程已經走完了,輸入 run 全速執行,程式執行結束,咱們選擇從頭開始:

這次取消全部斷點,全速執行:

可以看出,直接就執行到程式最後了。

這樣,我以後就不用再一行一行輸入 printf 除錯了, gdb 除錯 linux 程式就這樣實現了。
轉載自:https://www.xrkzn.cn/note/linux-note/linux-shell-programming-and-how-to-use-gdb-debug/