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]$
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值