前言

上篇《GDB调试指南-启动调试》我们讲到了GDB启动调试的多种方式,分别应用于多种场景。今天我们来介绍一下断点设置的多种方式。

为何要设置断点

在介绍之前,我们首先需要了解,为什么需要设置断点。我们在指定位置设置断点之后,程序运行到该位置将会“暂停”,这个时候我们就可以对程序进行更多的操作,比如查看变量内容,堆栈情况等等,以帮助我们调试程序。

查看已设置的断点

在学习断点设置之前,我们可以使用info breakpoints查看已设置断点:

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调试指南-启动调试》。

根据行号设置断点

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的断点

总结

本文介绍了常见的断点设置方法,断点设置之后,可以便于我们后期观察变量,堆栈等信息,为进一步的定位与调试做准备。

欢迎关注公众号【编程珠玑】

[原创]GDB调试指南-断点设置的更多相关文章

  1. GDB调试指南-变量查看

    前言 在启动调试以及设置断点之后,就到了我们非常关键的一步-查看变量.GDB调试最大的目的之一就是走查代码,查看运行结果是否符合预期.既然如此,我们就不得不了解一些查看各种类型变量的方法,以帮助我们进 ...

  2. GDB调试指南-单步调试

    前言 前面通过<启动调试>,<断点设置>,<变量查看>,我们已经了解了GDB基本的启动,设置断点,查看变量等,如果这些内容你还不知道,建议先回顾一下前面的内容.在启 ...

  3. GDB 调试指南

    本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复 「1024」 即可领取,欢迎大家关注,二维码文末可以扫. 00 介绍 ...

  4. GDB调试指南-启动调试

    前言 GDB(GNU Debugger)是UNIX及UNIX-like下的强大调试工具,可以调试ada, c, c++, asm, minimal, d, fortran, objective-c, ...

  5. roslaunch & gdb 调试指南(待补充)

    1. 安装xterm sudo apt-get install xterm 2. 在launch文件中添加如下内容: <node name="navigation" pkg= ...

  6. gdb常用命令及使用gdb调试多进程多线程程序

    一.常用普通调试命令 1.简单介绍GDB 介绍: gdb是Linux环境下的代码调试⼯具.使⽤:需要在源代码⽣成的时候加上 -g 选项.开始使⽤: gdb binFile退出: ctrl + d 或 ...

  7. gdb常用命令及gdb调试多进程/线程程序&coredump

    一.常用普通调试命令 1.简单介绍GDB 介绍: gdb是Linux环境下的代码调试⼯具.使⽤:需要在源代码⽣成的时候加上 -g 选项.开始使⽤: gdb binFile退出: ctrl + d 或 ...

  8. Linux多进程和多线程的一次gdb调试实例

    转载https://typecodes.com/cseries/multilprocessthreadgdb.html 1 原文整理 默认设置下,在调试多进程程序时gdb只会调试主进程.gdb7以上的 ...

  9. gdb 调试 报 stepping until--- has no line number information

    gdb 经常用 ,但今天使用gdb 调试的时候, break 打断点, 结果也没有打出 哪一行的信息,就只是提示一个具体地址. 使用单步调试 结果爆出 stepping until exit from ...

随机推荐

  1. visual studio git for coding

    直接放图吧 双击存储库项目进入Git操作页面 点击之后输入你要发布的git地址 选择你的操作 如果你登录的密码错了 就需要去修改 否则永远都pull失败 打开控制面板 在这里修改

  2. Leetcode 137. 只出现一次的数字 II - 题解

    Leetcode 137. 只出现一次的数字 II - 题解 137. Single Number II 在线提交: https://leetcode.com/problems/single-numb ...

  3. Linux~Sh脚本一点自己的总结

    从.netCore开源项目来看,eShopOnContainers来说,它的部署是跨平台的,可以部署在linux,docker上,在linux上运行它也可以写一些集成的小脚本,这是微信工程师为我们提供 ...

  4. RDIFramework.NET ━ .NET快速信息化系统开发框架 V3.2 新增解压缩工具类ZipHelper

    在项目对文件进行解压缩是非常常用的功能,对文件进行压缩存储或传输可以节省流量与空间.压缩文件的格式与方法都比较多,比较常用的国际标准是zip格式.压缩与解压缩的方法也很多,在.NET 2.0开始,在S ...

  5. #12 Python函数

    前言 矩形的面积 S = ab,只要知道任一矩形的的长和宽,就可以带入上式求得面积.这样有什么好处呢?一个公式,适用于全部矩形,一个公式,重复利用,减少了大脑的记忆负担.像这类用变量代替不变量的思想在 ...

  6. Springboot 系列(二)Spring Boot 配置文件

    注意:本 Spring Boot 系列文章基于 Spring Boot 版本 v2.1.1.RELEASE 进行学习分析,版本不同可能会有细微差别. 前言 不管是通过官方提供的方式获取 Spring ...

  7. Scala(三)

    一.控制语句 var x = 40 if(x == 40){ println("greate") } 二.循环 (1) 一般循环 while(a>1){ if(a==2){ ...

  8. Java开发笔记(七十八)面向对象的后门——反射

    作为一门面向对象的编程语言,Java认为一切皆是对象,每个对象都能归属于某个类,甚至每个类均可提取出一种特殊的类型,即Class类型.早在前面介绍多态的时候,就提到每个类都存在独一无二的基因,通过比较 ...

  9. 轻松搞定RocketMQ入门

    RocketMQ是一款分布式.队列模型的消息中间件,具有以下特点: 能够保证严格的消息顺序 提供丰富的消息拉取模式 高效的订阅者水平扩展能力 实时的消息订阅机制 亿级消息堆积能力 RocketMQ网络 ...

  10. Asp.Net MVC WebAPI的创建与前台Jquery ajax后台HttpClient调用详解

    1.什么是WebApi,它有什么用途? Web API是一个比较宽泛的概念.这里我们提到Web API特指ASP.NET MVC Web API.在新出的MVC中,增加了WebAPI,用于提供REST ...