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]$

猜你喜欢

转载自blog.csdn.net/X_Perseverance/article/details/83153166