上篇《GDB调试指南-启动调试》咱们讲到了GDB启动调试的多种方式,分别应用于多种场景。今天咱们来介绍一下断点设置的多种方式。css
在介绍以前,咱们首先须要了解,为何须要设置断点。咱们在指定位置设置断点以后,程序运行到该位置将会“暂停”,这个时候咱们就能够对程序进行更多的操做,好比查看变量内容,堆栈状况等等,以帮助咱们调试程序。html
在学习断点设置以前,咱们可使用info breakpoints查看已设置断点:nginx
info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000004005fc in printNum2 at test.c:17
breakpoint already hit 1 time
2 hw watchpoint keep y a
breakpoint already hit 1 time
ignore next 3 hits
它将会列出全部已设置的断点,每个断点都有一个标号,用来表明这个断点。例如,第2个断点设置是一个观察点,而且会忽略三次。算法
断点设置有多种方式,分别应用于不一样的场景。借助示例程序进行一一介绍:数据库
1//test.c
2#include<stdio.h>
3void printNum(int a)
4{
5 printf("printNum\n");
6 while(a > 0)
7 {
8 printf("%d\n",a);
9 a--;
10 }
11}
12void printNum2(int a,int num)
13{
14 printf("printNum\n");
15 while(a > num && a>0)
16 {
17 printf("%d\n",a);
18 a--;
19 }
20}
21int div(int a,int b)
22{
23 printf("a=%d,b=%d\n",a,b);
24 int temp = a/b;
25 return temp;
26}
27int main(int argc,char *argv[])
28{
29 printNum2(12,5);
30 printNum(10);
31 div(10,0);
32 return 0;
33}
编译:编程
gcc -g -o test test.c
注意,编译时须要带上-g参数,具体缘由参见《GDB调试指南-启动调试》。bash
b 10 #break 可简写为b
或者微信
b test.c:10
程序运行到第10行的时候会断住。函数
一样能够将断点设置在函数处:学习
b printNum
程序在调用到printNum函数的时候会断住。
假设程序某处发生崩溃,而崩溃的缘由怀疑是某个地方出现了非指望的值,那么你就能够在这里断点观察,当出现该非法值时,程序断住。这个时候咱们能够借助gdb来设置条件断点,例如:
break test.c:23 if b==0
当在b等于0时,程序将会在第23行断住。
它和condition有着相似的做用,假设上面的断点号为1,那么:
condition 1 b==0
会使得b等于0时,产生断点1。而实际上能够很方便地用来改变断点产生的条件,例如,以前设置b==0时产生该断点,那么使用condition能够修改断点产生的条件。
例如须要对全部调用printNum函数都设置断点,可使用下面的方式:
rbreak printNum*
全部以printNum开头的函数都设置了断点。而下面是对全部函数设置断点:
#用法:rbreak file:regex
rbreak .
rbreak test.c:. #对test.c中的全部函数设置断点
rbreak test.c:^print #对以print开头的函数设置断点
假设某处的断点只想生效一次,那么能够设置临时断点,这样断点后面就不复存在了:
tbreak test.c:l0 #在第10行设置临时断点
假若有某个地方,咱们知道可能出错,可是前面30次都没有问题,虽然在该处设置了断点,可是想跳过前面30次,可使用下面的方式:
ignore 1 30
其中,1是你要忽略的断点号,能够经过前面的方式查找到,30是须要跳过的次数。这样设置以后,会跳过前面30次。再次经过info breakpoints能够看到:
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000004005e8 in printNum2 at test.c:16
ignore next 30 hits
有时候咱们须要观察某个值或表达式,知道它何时发生变化了,这个时候咱们能够借助watch命令。例如:
watch a
这个时候,让程序继续运行,若是a的值发生变化,则会打印相关内容,如:
Hardware watchpoint 2: a
Old value = 12
New value = 11
可是这里要特别注意的是,程序必须运行起来,不然会出现:
No symbol "a" in current context.
由于程序没有运行,当前上下文也就没有相关变量信息。
rwatch和awatch一样能够设置观察点前者是当变量值被读时断住,后者是被读或者被改写时断住。
微信公众号【编程珠玑】:专一但不限于分享计算机编程基础,Linux,C语言,C++,算法,数据库等编程相关[原创]技术文章,号内包含大量经典电子书和视频学习资源。欢迎一块儿交流学习,一块儿修炼计算机“内功”,知其然,更知其因此然。
有些断点暂时不想使用,但又不想删除,能够暂时禁用或启用。例如:
disable #禁用全部断点
disable bnum #禁用标号为bnum的断点
enable #启用全部断点
enable bnum #启用标号为bnum的断点
enable delete bnum #启动标号为bnum的断点,而且在此以后删除该断点
断点清除主要用到clear和delete命令。常见使用以下:
clear #删除当前行全部breakpoints
clear function #删除函数名为function处的断点
clear filename:function #删除文件filename中函数function处的断点
clear lineNum #删除行号为lineNum处的断点
clear f:lename:lineNum #删除文件filename中行号为lineNum处的断点
delete #删除全部breakpoints,watchpoints和catchpoints
delete bnum #删除断点号为bnum的断点
本文介绍了常见的断点设置方法,断点设置以后,能够便于咱们后期观察变量,堆栈等信息,为进一步的定位与调试作准备。
欢迎关注公众号【编程珠玑】