【Linux】GDB調試工具


GDB調試工具

Linux中包含一個很強大的調試工具GDB(GNU Debuger),可以用它來調試C和C++程序。

一. GDB的主要功能有:

  • 設置斷點,當程序運行到斷點處暫停
  • 顯示變量的值,可以打印或者監視某個變量,將變量的值顯示出來
  • 單步執行,GDB允許用戶單步執行程序,可以跟蹤進入函數和從函數中退出
  • 運行時修改變量的值,GDB允許在調試狀態下修改變量的值,此功能在測試程序的時候特別有用
  • 路徑跟蹤,GDB可以將代碼的路徑打印出來,方便用戶跟蹤代碼
  • 線程切換,在調試多線程的時候,此種功能是必須的
  • ……

 

二. 使用GDB調試程序

    要使用GDB調試程序,在編譯程序的時候需要加入 "-g"選項,例如:

$gcc –g –o helloworld helloworld.c

 

    1. gdb加載程序

    命令格式:"gdb 要調試的文件全名"

$gdb helloworld

    

    2. 設置程序的輸入參數

    命令格式:"set args 參數值1 參數值2 … "

    通常可執行文件在運行時需要輸入參數,可以用上面命令在GDB中向可執行文件輸入參數。例如,下面的命令"set args 3"表示向加載的程序中輸入的參數為3。

(gdb) set args 3

    

    3. 打印代碼內容

    命令格式:"list 開始的行號"

命令list用於列出已加載程序的源代碼。例如,"list 1"表示從第一行開始列出代碼,每次按下Enter鍵后順序向下列出代碼。

(gdb) list 1

 

    4. 設置斷點

    命令格式:"b 行號/函數名"

例如,在源程序的第10行設置一個斷點:

(gdb) b 10

    程序在斷點處暫停后,按"c"鍵繼續運行。

    5.運行程序

    命令格式:"run (后面可以加上傳遞給程序的參數)"

(gdb) run

 

    6. 顯示變量

    命令格式:"display 變量"

    程序運行到斷點處暫停,此時可以使用display命令顯示變量的值,以后每次停止都會顯示此變量的值。例如,顯示變量i的值:

(gdb) display i //每次停止時都會顯示變量i的值

 

    7. 修改變量的值

    命令格式:"set 變量名=值"

    例如,修改變量i的值為6:

(gdb) set i=6

 

    8. 退出GDB

    命令格式:"q"

(gdb) q

 

三. 常用命令詳解

1. 執行程序

    用GDB執行程序可以使用 gdb program 的方式,program是程序的程序名。假如在啟動GDB的時候沒有選擇程序名稱,可以在GDB啟動后使用file program的方法啟動:

(gdb) file test

 

2. 參數設置和顯示

    使用set args命令來設置發送給程序的參數;使用show args 命令顯示其默認的參數:

(gdb) set args 1 2 3

(gdb) show args

Argument list to give program being debugged when it is started is "1 2 3".

 

3. 打印程序源代碼

    打印文件代碼的命令時list,簡寫為l。

(gdb) list line1, line2

打印從line1到line2之間的代碼,如果不輸入參數,默認從當前行開始打印。

(gdb) l

1    #include<sys/stat.h>

2    #include<sys/types.h>

3    #include<unistd.h>

4    #include<stdio.h>

5    

6    int main(void)

7    {

8        struct stat st;

9        

10        if(-1==stat("test.txt",&st))

(gdb)

11        {

12            printf("get file status failure\n");

13            return -1;

14        }

15        printf("此文件的大小:%d\n",st.st_size);

16        printf("此文件的租后修改時間:%d\n",st.st_mtime);

17        printf("此文件的節點:%d\n",st.st_ino);

18        printf("此文件的保護模式:%d\n",st.st_mode);

19    }

 

4. 打印數據

打印變量或者表達式的值可以使用print命令,簡寫為p。

(gdb) print 變量名(或表達式)

 

5. 斷點

設置斷點的命令時break,簡寫為b。有3種設置方式:

  • b 行號:程序停止在設定的行之前
  • b 函數名稱:程序停止在設定的函數之前
  • b 行號或者函數 if條件:這是條件斷點,如果條件為真,則程序在到達指定行或函數時停止。

(1)設置斷點

如果程序由很多的文件構成,在設置斷點時要指定文件名:

(gdb) b man.c 10

(gdb) b subfunction.c 20

要設置一個條件斷點,可以利用b if 命令,在調試循環代碼段時這樣的設置比較有用,省略了大量的手動調試,例如,在一個循環函數中,在i=2時設置斷點:

(gdb) b 46 if i==2

 

(2)顯示當前GDB的斷點信息

使用info break命令顯示當前斷點的信息

(gdb) info b

Num Type Disp Enb Address What

1 breakpoint keep y 0x080484b1 in main at filestat.c:15

    breakpoint already hit 1 time

 

(3)刪除指定的斷點

    刪除斷點使用 delete b 斷點編號 命令。下面的命令會刪除第8個斷點:

(gdb) delete b 8

 

    (4)禁止斷點

    禁止斷點使用 disable b 斷點編號 命令。下面的命令會禁用第9個斷點:

(gdb) disable b 9

 

    (5)允許斷點

    允許斷點使用 enable b 斷點編號 命令。下面的命令會禁用第9個斷點:

(gdb) enable b 9

 

    (6)清除斷點

    一次性的清除某行處的所有斷點使用命令 clean 行號。下面的命令會清除在源代碼中第32行的所設置的斷點:

(gdb) clean 32

 

6. 變量類型檢測

在調試過程中有需要查看變量類型的情況,需要使用命令whatis 和ptype等。

  • whatis 變量名 :查看變量的類型,只能查看變量的類型名稱,不能得到類型的詳細信息。

(gdb) whatis st

type = struct stat

  • ptype 變量名:查看變量類型的詳細信息。

(gdb) ptype st

type = struct stat {

__dev_t st_dev;

short unsigned int __pad1;

__ino_t st_ino;

__mode_t st_mode;

__nlink_t st_nlink;

__uid_t st_uid;

__gid_t st_gid;

__dev_t st_rdev;

short unsigned int __pad2;

__off_t st_size;

__blksize_t st_blksize;

__blkcnt_t st_blocks;

struct timespec st_atim;

struct timespec st_mtim;

struct timespec st_ctim;

long unsigned int __unused4;

long unsigned int __unused5;

}

 

7. 單步調試

單步跟蹤:next 簡寫為n

進入函數體:step 簡寫為 s

退出已進入的函數:finish

(gdb) n

(gdb) s

(gdb) finish

 

8. 設置監測點

display命令可以設置監測變量的值,當遇到斷點時,會顯示監測變量的值。

(gdb) display i

i=1

 

9. 調用路徑

backtrace命令可以打印函數的調用路徑,提供前向跟蹤功能,此命令對跟蹤函數很有用處。Backtrace打印一個順序列表,函數從最近到最遠的調用過程,包含調用函數和其中的參數。簡寫為bt。

 

10. 信息info

Info命令可獲得當前命令的信息,例如獲得斷點的情況,參數的設置情況等。

例如:

(gdb) info frame //查看棧信息

Stack level 0, frame at 0xbffff760:

eip = 0x80484c5 in main (filestat.c:16); saved eip 0xb7e88e46

source language c.

Arglist at 0xbffff758, args:

Locals at 0xbffff758, Previous frame's sp is 0xbffff760

Saved registers:

ebp at 0xbffff758, eip at 0xbffff75c

 

(gdb) info locals //查看所有局部變量

 

11. 多線程

多線程是現代程序中經常采用的編程方法,而多線程由於執行過程中的調度隨機性,不好調試。多線程調試主要有兩點:先獲得線程的ID好,然后轉到該線程進行調試。

    Info thread 命令列出當前進程中的線程號,其中最前面的為調試用的ID。

    thread id 命令進入需要調試的線程。

(gdb) info thread

Id Target Id Frame

* 1 process 7854 "filestat" main () at filestat.c:15

 

12. 反匯編

Disassamble命令打印指定處的匯編代碼,例如printf的匯編代碼如下:

(gdb) disassemble printf

Dump of assembler code for function printf:

0xb7ebbc80 <+0>:    push %ebp

0xb7ebbc81 <+1>:    mov %esp,%ebp

0xb7ebbc83 <+3>:    push %ebx

0xb7ebbc84 <+4>:    call 0xb7f85bc6

0xb7ebbc89 <+9>:    add $0x11a36b,%ebx

0xb7ebbc8f <+15>:    sub $0xc,%esp

0xb7ebbc92 <+18>:    lea 0xc(%ebp),%eax

0xb7ebbc95 <+21>:    mov %eax,0x8(%esp)

0xb7ebbc99 <+25>:    mov 0x8(%ebp),%eax

0xb7ebbc9c <+28>:    mov %eax,0x4(%esp)

0xb7ebbca0 <+32>:    mov -0x7c(%ebx),%eax

0xb7ebbca6 <+38>:    mov (%eax),%eax

0xb7ebbca8 <+40>:    mov %eax,(%esp)

0xb7ebbcab <+43>:    call 0xb7eb17e0 <vfprintf>

0xb7ebbcb0 <+48>:    add $0xc,%esp

0xb7ebbcb3 <+51>:    pop %ebx

0xb7ebbcb4 <+52>:    pop %ebp

0xb7ebbcb5 <+53>:    ret

End of assembler dump.

 

13. help幫助信息

用法類似於man。例如想查看命令c的信息:

(gdb) help c

Continue program being debugged, after signal or breakpoint.

If proceeding from breakpoint, a number N may be used as an argument,

which means to set the ignore count of that breakpoint to N - 1 (so that

the breakpoint won't break until the Nth time it is reached).

 

If non-stop mode is enabled, continue only the current thread,

otherwise all the threads in the program are continued. To

continue all stopped threads in non-stop mode, use the -a option.

Specifying -a and an ignore count simultaneously is an error.

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM