GDB使用教程
前言: gdb(GNU debugger)是GNU开发组织发布的一个强大的UNIX/Linux下的程序调试工具。
启动gdb
gcc -g main.c //调试性编译
gdb a.out
启动后出现软件信息:
列出源代码
(gdb) list
9
10 int add(int n)
11 {
12 return n+1;
13 }
14
15 int main(int argc,const char *argv[])
16 {
17
18 if(argc == 2)
(gdb) l //list缩写
19 {
20 printf("argu:%s\n",argv[1]);
21 }
22
23 int n=1;
24 printf("add:n=%d\n",add(n));
25
26 int arr[4]={1,2,3,4};
27 int i=0;
28 for(i=0;i<4;i++)
(gdb) //空命令执行最近执行的那个命令
29 printf("arr[i]=%d\n",arr[i]);
30
31 return 0;
32 }
(gdb) list //最后显示总行数
Line number 33 out of range; main.c has 32 lines.
(gdb) list 22 //可以指定行号,显示其前后的代码
17
18 if(argc == 2)
19 {
20 printf("argu:%s\n",argv[1]);
21 }
22
23 int n=1;
24 printf("add:n=%d\n",add(n));
25
26 int arr[4]={1,2,3,4};
(gdb) list main //可以指定函数名,显示其前后的代码
11 {
12 return n+1;
13 }
14
15 int main(int argc,const char *argv[])
16 {
17
18 if(argc == 2)
19 {
20 printf("argu:%s\n",argv[1]);
(gdb)
运行程序
(gdb) run answer //若函数有参数,需加上参数运行
Starting program: /home/answer/gdb/a.out answer
argu:answer
add:n=2
arr[i]=1
arr[i]=2
arr[i]=3
arr[i]=4
[Inferior 1 (process 2959) exited normally]
(gdb)
设置断点
(gdb) break 24 //在24行设置
Breakpoint 1 at 0x400575: file main.c, line 24.
(gdb) break add //在add()函数入口设置
Breakpoint 2 at 0x400534: file main.c, line 12.
查看断点信息
(gdb) info break
Num Type Disp Enb Address What
1 breakpoint keep y 0x0000000000400575 in main at main.c:24
2 breakpoint keep y 0x0000000000400534 in add at main.c:12
检查变量
(gdb) run answer
Starting program: /home/answer/gdb/a.out answer
argu:answer
Breakpoint 1, main (argc=2, argv=0x7fffffffdec8) at main.c:24
24 printf("add:n=%d\n",add(n)); //在断点1处停下
(gdb) print n //简写为p,检查变量
$1 = 1
单步执行
(gdb) break main //在main()处增加断点
(gdb) run answer
Starting program: /home/answer/gdb/a.out answer
Breakpoint 3, main (argc=2, argv=0x7fffffffdec8) at main.c:18
18 if(argc == 2)
(gdb) next //单步执行
20 printf("argu:%s\n",argv[1]);
(gdb) n //next的缩写
argu:answer
23 int n=1;
(gdb) step //单步执行
Breakpoint 1, main (argc=2, argv=0x7fffffffdec8) at main.c:24
24 printf("add:n=%d\n",add(n));
(gdb) s //step的缩写
Breakpoint 2, add (n=1) at main.c:12
12 return n+1;
(gdb)
继续执行
(gdb) continue //同cont、c
Continuing.
add:n=2
arr[i]=1
arr[i]=2
arr[i]=3
arr[i]=4
[Inferior 1 (process 2982) exited normally]
查看堆栈信息
(gdb) backtrace
#0 add (n=1) at main.c:12
#1 0x000000000040057f in main (argc=2, argv=0x7fffffffdec8) at main.c:24
(gdb) bt //backtrace缩写
#0 add (n=1) at main.c:12
#1 0x000000000040057f in main (argc=2, argv=0x7fffffffdec8) at main.c:24
(gdb) where //作用同bt相同
#0 add (n=1) at main.c:12
#1 0x000000000040057f in main (argc=2, argv=0x7fffffffdec8) at main.c:24
查看数组
(gdb) print arr[0] //查看单个数组元素
$1 = 1
(gdb) print arr[0]@4 //查看数组所有元素
$2 = {1, 2, 3, 4}
删除断点
(gdb) disable break 1
x 命令检查内存
(gdb) set var i=0x12345678 //为i赋值
(gdb) x/4xb &i //检查 4 个值,格式是十六进制,一次显示一个字节
0x7fffffffddd8: 0x78 0x56 0x34 0x12 //小端模式
使用 ptype 检查类型
(gdb) ptype i
type = int
(gdb) ptype &i
type = int *
(gdb) ptype main
type = int (int, const char **)
(gdb) ptype arr
type = int [4]
core文件
在程序崩溃时,Linux和UNIX系统通常会产生一个核心转储(core dump),并保存在core文件中。这个文件是程序的内存映像文件,包含程序失败的那个时刻的全局变量。
用gdb调试core:
ulimit -c unlimited //允许生成core文件
gdb a.out core
这样就可以看出是哪里出现了问题。
帮助
(gdb) help
(gdb) help list
这样就可以查看一些gdb的命令或一些命令的解释。
退出函数
(gdb) finish
退出
(gdb) quit
总结
gdb的功能绝不止上面这些,我只是列举了一些常用的功能。如果你还想了解更多的高级功能,那么请自行查阅资料。
反馈与建议
- 微博:@AnSwEr不是答案
- github:AnSwErYWJ
- 博客:AnSwEr不是答案的专栏