Linux工具之調試器gdb

一、介紹

     GDB是一個在UNIX/LINUX操作系統下基於命令行的且功能強大的程序調試工具,由GNU開源組織發佈。

二、基本用法

1.如何進入調試?

     (1)要使用gdb調試,我們必須首先在源代碼生成二進制程序的時候,加上 -g 選項,從而生成調試信息

例:gcc -g test.c -o test

     (2)接着可以使用gdb指令進入調試界面

方法一:
	gdb test
方法二:
	gdb
	file test

2.命令列表

命令 說明
list/l 多行顯示源代碼,接着上次的位置往下列,每次列10行
list/l n 顯示第n行附近的代碼
list/l 函數名 列出某個函數的源代碼
run/r 運行程序
start 開始逐步調試
next/n 執行下一條語句,如果該語句爲函數調用,不會進入函數內部執行(即不會一步步地調試函數內部語句)
step/s 執行下一條語句,如果該語句爲函數調用,則進入函數內部執行
break/b 行號 在某一行設置斷點
break/b 函數名 在某個函數開頭設置斷點
info/i break/b 查看斷點信息
delete/d breakpoints 刪除所有斷點
delete/d breakpoints n 刪除序號爲 n 的斷點
disable breakpoints 禁用斷點
enable breakpoints 啓用斷點
continue/c 從當前位置開始連續而非單步執行程序,直到遇到下一個斷點或程序結束
watch 變量名 監控某個變量的改變
print/p 變量名 打印某個變量的值
set var 變量名=value 設置某個變量的值爲value
display 變量名 跟蹤查看某個變量,每次停下來都顯示它的值
undisplay 取消對先前設置的那些變量的跟蹤
until n 跳轉到第n行
backtrace/bt 打印函數調用棧,查看各級函數調用及參數
info/i locals 查看當前棧幀局部變量的值
quit/q/Ctrl+d 退出gdb調試

三、實例演示

 #include <stdio.h>
 
 void Swap(int* a, int* b)
 {
     int tmp = *a;
     *a = *b;
     *b = tmp;
 }

 int main()
 {
      int a = 1, b = 10;
      while(a!=5)
      {
          a++;
      }
      Swap(&a, &b);
      printf("a=%d  b=%d\n", a, b);
      return 0;
  }

1. 進入調試

第一步:
[admin@localhost tools]$ gcc -g test.c -o test
第二步:
[admin@localhost tools]$ gdb test
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-92.el6)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/admin/workspace/tools/test...done.
(gdb) 
或:
[admin@localhost tools]$ gdb
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-92.el6)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
(gdb) file test
Reading symbols from /home/admin/workspace/tools/test...done.
(gdb) 

2. list/l

(1)list/l

(gdb) list	//多行顯示源代碼,每次最多顯示10行
3	void Swap(int* a, int* b)
4	{
5		int tmp = *a;
6		*a = *b;
7		*b = tmp;
8	}
9	
10	int main()
11	{
12		int a = 1, b = 10;
(gdb) l	//多行顯示源代碼,每次最多顯示10行
13		while(a!=5)
14		{
15			a++;
16		}
17		Swap(&a, &b);
18		printf("a=%d  b=%d\n", a, b);
19		return 0; 
20	}
(gdb) 

(2)list/l 行號

(gdb) l 17	//列出第17行附近的代碼
12		int a = 1, b = 10;
13		while(a!=5)
14		{
15			a++;
16		}
17		Swap(&a, &b);
18		printf("a=%d  b=%d\n", a, b);
19		return 0; 
20	}
(gdb) 

(3)list/l 函數名

(gdb) l Swap	//列出Swap函數的源代碼
1	#include <stdio.h>
2	
3	void Swap(int* a, int* b)
4	{
5		int tmp = *a;
6		*a = *b;
7		*b = tmp;
8	}
9	
10	int main()
(gdb) 

3. run/r

(gdb) run	//運行程序
Starting program: /home/admin/workspace/tools/test 
a=10  b=5

Program exited normally.
(gdb) 

4. start

(gdb) start	//開始逐步調試
Temporary breakpoint 1 at 0x80483ef: file test.c, line 12.
Starting program: /home/admin/workspace/tools/test 

Temporary breakpoint 1, main () at test.c:12
12		int a = 1, b = 10;
(gdb) 

5. next/n

(gdb) start
Temporary breakpoint 1 at 0x80483ef: file test.c, line 12.
Starting program: /home/admin/workspace/tools/test 

Temporary breakpoint 1, main () at test.c:12
12		int a = 1, b = 10;
(gdb) n	//執行下一條語句
13		while(a!=5)
(gdb) n
15			a++;
(gdb) n
13		while(a!=5)
(gdb) n
15			a++;
(gdb) n
13		while(a!=5)
(gdb) n
15			a++;
(gdb) n
13		while(a!=5)
(gdb) n
15			a++;
(gdb) n
13		while(a!=5)	//跳出循環
(gdb) n
17		Swap(&a, &b);
(gdb) n	//不進入Swap函數內部執行
18		printf("a=%d  b=%d\n", a, b);
(gdb) 

6. step/s

(gdb) start
Temporary breakpoint 1 at 0x80483ef: file test.c, line 12.
Starting program: /home/admin/workspace/tools/test 

Temporary breakpoint 1, main () at test.c:12
12		int a = 1, b = 10;
(gdb) s	//開始執行下一條語句
13		while(a!=5)
(gdb) s
15			a++;
(gdb) s
13		while(a!=5)
(gdb) s
15			a++;
(gdb) s
13		while(a!=5)
(gdb) s
15			a++;
(gdb) s
13		while(a!=5)
(gdb) s
15			a++;
(gdb) s
13		while(a!=5)	//循環跳出
(gdb) s
17		Swap(&a, &b);
(gdb) s	//進入Swap函數內部執行
Swap (a=0xbffff65c, b=0xbffff658) at test.c:5
5		int tmp = *a;
(gdb) s
6		*a = *b;
(gdb) s
7		*b = tmp;
(gdb) s
8	}
(gdb) s
main () at test.c:18
18		printf("a=%d  b=%d\n", a, b);
(gdb)

7. break/b

(1)break/b 行號

(gdb) break 13	//在第13行設置斷點
Breakpoint 4 at 0x80483ff: file test.c, line 13.
(gdb)

(2)break/b 函數名

(gdb) b Swap	//在Swap函數開頭設置斷點
Breakpoint 5 at 0x80483ca: file test.c, line 5.
(gdb) 

8. info/i break/b

(gdb) info break	//查看斷點信息
Num     Type           Disp Enb Address    What
4       breakpoint     keep y   0x080483ff in main at test.c:13
5       breakpoint     keep y   0x080483ca in Swap at test.c:5
(gdb) i b	//查看斷點信息
Num     Type           Disp Enb Address    What
4       breakpoint     keep y   0x080483ff in main at test.c:13
5       breakpoint     keep y   0x080483ca in Swap at test.c:5
(gdb) 

9. delete/d breakpoints

(1)delete/d breakpoints

(gdb) d breakpoints	//刪除所有斷點
Delete all breakpoints? (y or n) y
(gdb) i b	//此時查看斷點信息,發現並沒有任何斷點
No breakpoints or watchpoints.
(gdb) 

(2)delete/d breakpoints n

(gdb) i b
Num     Type           Disp Enb Address    What
4       breakpoint     keep y   0x080483ff in main at test.c:13
5       breakpoint     keep y   0x080483ca in Swap at test.c:5
(gdb) d breakpoints 4	//刪除序號爲4的斷點
(gdb) i b	//此時查看斷點信息,發現只剩下一個序號爲5的斷點
Num     Type           Disp Enb Address    What
5       breakpoint     keep y   0x080483ca in Swap at test.c:5
(gdb) 

10. continue/c

(gdb) start	//開始逐步調試
Temporary breakpoint 1 at 0x80483ef: file test.c, line 12.
Starting program: /home/admin/workspace/tools/test 

Temporary breakpoint 1, main () at test.c:12
12		int a = 1, b = 10;
(gdb) b 17	//在第17行設置斷點
Breakpoint 10 at 0x8048415: file test.c, line 17.
(gdb) c	//從當前位置開始連續執行程序,在第17行停下來
Continuing.

Breakpoint 10, main () at test.c:17
17		Swap(&a, &b);
(gdb) 

11. watch 變量名

(gdb) start
Temporary breakpoint 1 at 0x80483ef: file test.c, line 12.
Starting program: /home/admin/workspace/tools/test 

Temporary breakpoint 1, main () at test.c:12
12		int a = 1, b = 10;
(gdb) n
13		while(a!=5)
(gdb) watch a	//監控變量a的改變
Hardware watchpoint 12: a
(gdb) i watchpoints 查看監視信息
Num     Type           Disp Enb Address    What
12      hw watchpoint  keep y              a
(gdb)

12. print/p 變量名

(gdb) start
Temporary breakpoint 1 at 0x80483ef: file test.c, line 12.
Starting program: /home/admin/workspace/tools/test 

Temporary breakpoint 1, main () at test.c:12
12		int a = 1, b = 10;
(gdb) n
13		while(a!=5)
(gdb) watch a	//監控變量a的改變
Hardware watchpoint 12: a
(gdb) p a	//打印變量a的值
$1 = 1
(gdb) 

13. set var 變量名=value

(gdb) p a
$1 = 1
(gdb) set var a=3	//設置變量a的值爲3
(gdb) print a	//此時打印變量a的值,發現變爲3
$2 = 3
(gdb)

14. display 變量名

(gdb) start
Temporary breakpoint 1 at 0x80483ef: file test.c, line 12.
Starting program: /home/admin/workspace/tools/test 

Temporary breakpoint 1, main () at test.c:12
12		int a = 1, b = 10;
(gdb) n
13		while(a!=5)
(gdb) display a	//跟蹤查看變量a
1: a = 1	//每次停下來都會顯示變量a的值
(gdb) n
15			a++;
1: a = 1
(gdb) n
13		while(a!=5)
1: a = 2
(gdb)

15. undisplay

(gdb) undisplay	//取消對先前設置的那些變量的跟蹤
Delete all auto-display expressions? (y or n) y
(gdb) 

16. until n

(gdb) start
Temporary breakpoint 1 at 0x80483ef: file test.c, line 12.
Starting program: /home/admin/workspace/tools/test 

Temporary breakpoint 1, main () at test.c:12
12		int a = 1, b = 10;
(gdb) until 17	//跳轉到第17行

Breakpoint 10, main () at test.c:17
17		Swap(&a, &b);
(gdb)

17. backtrace/bt

(gdb) s
Swap (a=0xbffff65c, b=0xbffff658) at test.c:5
5		int tmp = *a;
(gdb) bt	//打印函數調用棧,查看各級函數調用及參數
#0  Swap (a=0xbffff65c, b=0xbffff658) at test.c:5
#1  0x08048429 in main () at test.c:17
(gdb) backtrace
#0  Swap (a=0xbffff65c, b=0xbffff658) at test.c:5
#1  0x08048429 in main () at test.c:17
(gdb)

18. info/i locals

(gdb) s
Swap (a=0xbffff65c, b=0xbffff658) at test.c:5
5		int tmp = *a;
(gdb) n
6		*a = *b;
(gdb) i locals	//查看當前棧幀局部變量tmp的值
tmp = 5
(gdb) 

19. quit/q/Ctrl+d

(gdb) start
Temporary breakpoint 1 at 0x80483ef: file test.c, line 12.
Starting program: /home/admin/workspace/tools/test 

Temporary breakpoint 1, main () at test.c:12
12		int a = 1, b = 10;
(gdb) quit	//退出調試
A debugging session is active.

	Inferior 1 [process 2928] will be killed.

Quit anyway? (y or n) y
[admin@localhost tools]$
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章