- gdb 基本命令2
命令 | 描述 |
---|---|
break ( 或b ) 行号 | 在某一行设置断点 |
break 函数名 | 在某个函数开头设置断点 |
break … if … | 设置条件断点 |
continue (或 c) | 从当前位置开始连续运行程序 |
delete breakpoints 断点号 | 删除断点 |
display 变量名 | 跟踪查看某个变量,每次停下来都显示它的值 |
disable breakpoints 断点号 | 禁用断点 |
enable 断点号 | 启用断点 |
info (或 i) breakpoints | 查看当前设置了哪些断点 |
run (或 r) | 从头开始连续运行程序 |
undisplay 跟踪显示号 | 取消跟踪显示 |
代码作用,将输入的字符串转为数字:
程序文件(main.c)
1 #include <stdio.h>
2
3 int main(void)
4 {
5
6 int sum = 0, i = 0;
7 char input[5];
8
9 while(1){
10 scanf("%s",input);
11 for (i = 0;input[i] != '\0';i++)
12 sum = sum*10 + input[i] - '0';
13 printf("input=%d\n",sum);
14 }
15 return 0;
16 }
以上代码运行结果为:
# gcc -g main.c -o main
# ./main
123
input=123
234
input=123234
第一个结果是正确的,第二个结果不应该出现前面三个数的,下面我们通过调试来找出错误的原因。
调试Demo
开始调试
# gdb main
...
(gdb) start
Temporary breakpoint 1 at 0x40059e: file main.c, line 4.
Starting program: /home/liyongfeng/code/gdb_Demo/Demo2/main
Temporary breakpoint 1, main () at main.c:4
4 {
- display命令 每次停下了的时候都显示当前sum的值
有了上一次的经验,sum 被列为重点怀疑对象,我们可以用display命令使得每次停下了的时候都显示当前sum的值,然后继续往下走:
(gdb) display sum
1: sum = 4195488
(gdb) n
6 int sum = 0, i = 0;
1: sum = 4195488
(gdb)
10 scanf("%s",input);
1: sum = 0
- undisplay命令 取消跟踪显示
变量sum的编号为1,可以用 undisplay 1 命令来取消它的跟踪显示。
- break命令 设置断点
如果不想一步一步执行,可以在第10行位置设置一个断点。
(gdb) l
5
6 int sum = 0, i = 0;
7 char input[5];
8
9 while(1){
10 scanf("%s",input);
11 for (i = 0;input[i] != '\0';i++)
12 sum = sum*10 + input[i] - '0';
13 printf("input=%d\n",sum);
14 }
(gdb) b 10
Breakpoint 2 at 0x4005bb: file main.c, line 10.
- continue命令 连续运行直到遇到断点
(gdb) c
Continuing.
123
input=123
Breakpoint 2, main () at main.c:10
10 scanf("%s",input);
1: sum = 123
//再次输入数字,进行下一次循环
(gdb) n
234
11 for (i = 0;input[i] != '\0';i++)
1: sum = 123
这里已经可以看出问题了,新的转换sum应该再次从0开始累加,但是这里却是123了,应该在一次循环结束后,将sum做归零处理。
一次调试可以设置多个断点,用info命令可以查看已经设置的断点
(gdb) b 13
Breakpoint 3 at 0x40060f: file main.c, line 13.
(gdb) i breakpoints
Num Type Disp Enb Address What
2 breakpoint keep y 0x00000000004005bb in main at main.c:10
breakpoint already hit 1 time
3 breakpoint keep y 0x000000000040060f in main at main.c:13
每个断点都有一个编号,可以用编号指定删除某个断点:
(gdb) delete breakpoints 2
(gdb) i breakpoints
Num Type Disp Enb Address What
3 breakpoint keep y 0x000000000040060f in main at main.c:13
有时候可以将一个断点禁用掉而不必删除,这样以后想用的时候可以直接启用,而不必从新从代码里设置,可以通过看Enb字段来查看断点的状态是开启还是禁用:
(gdb) disable breakpoints 3
(gdb) i breakpoints
Num Type Disp Enb Address What
3 breakpoint keep n 0x000000000040060f in main at main.c:13
(gdb) enable 3
(gdb) i breakpoints
Num Type Disp Enb Address What
3 breakpoint keep y 0x000000000040060f in main at main.c:13
(gdb) delete breakpoints
Delete all breakpoints? (y or n) y
gdb 断点功能非常灵活,可以设置断点在满足某个条件时才激活。
例如:我们在循环开头设置断点,但是仅当sum不等于0时才中断,然后用run命令(简写r)重新从程序开头连续运行:
(gdb) break 10 if sum != 0
Breakpoint 6 at 0x4005bb: file main.c, line 10.
(gdb) i breakpoints
Num Type Disp Enb Address What
6 breakpoint keep y 0x00000000004005bb in main at main.c:10
stop only if sum != 0
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/liyongfeng/code/gdb_Demo/Demo2/main
123
input=123
Breakpoint 6, main () at main.c:10
10 scanf("%s",input);
1: sum = 123
程序在第一次执行scanf之前没有中断,第二次执行scanf时因为 sum 满足条件 sum != 0 所以中断。