前言

上篇《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. 死磕 java集合之ArrayList源码分析

    欢迎关注我的公众号"彤哥读源码",查看更多源码系列文章, 与彤哥一起畅游源码的海洋. 简介 ArrayList是一种以数组实现的List,与数组相比,它具有动态扩展的能力,因此也可 ...

  2. Filebeat 模块与配置

    续 • <开始使用Filebeat> 1.  关于Filebeat 当你要面对成百上千.甚至成千上万的服务器.虚拟机和容器生成的日志时,请告别 SSH 吧!Filebeat 将为你提供一种 ...

  3. ASP.NET Core DI 手动获取注入对象

    ASP.NET Core DI 一般使用构造函数注入获取对象,比如在ConfigureServices配置注入后,通过下面方式获取: private IValueService _valueServi ...

  4. github访问很慢解决方案

    首先要解决的就是这个访问速度的问题: 获取Github相关网站的ip 访问https://www.ipaddress.com,拉下来,找到页面中下方的“IP Address Tools – Quick ...

  5. leetcode — remove-duplicates-from-sorted-list-ii

    /** * Source : https://oj.leetcode.com/problems/remove-duplicates-from-sorted-list-ii/ * * * Given a ...

  6. 性能测试-Jmeter3.1 使用技巧

    一.JMeter官网 下载地址 http://jmeter.apache.org/download_jmeter.cgi Jmeter wiki https://wiki.apache.org/jme ...

  7. Docker在Linux/Windows上运行NetCore文章系列

    Windows系列 因为Window很简单,VS提供界面化配置,所以只写了一篇文章 Docker在Windows上运行NetCore系列(一)使用命令控制台运行.NetCore控制台应用 Linux( ...

  8. arcgis 10.0中的server报错说工作站服务没有打开

    大家好! 写这篇文章其实我也不知道该不该写,感觉问题其实也不是自己解决的,但是这个问题困恼了我2天,我还将arcgis10.0重装了一次. 下面也不多说了,主要是由于公司的需求,将自己的arcgis1 ...

  9. [PHP] 简单多进程并发

    企邮搬家进程管理逻辑,经过简化后的功能实现 <?php //守护进程 umask(0); //把文件掩码清0 if (pcntl_fork() != 0){ //是父进程,父进程退出 exit( ...

  10. PHP和Go中的闭包变量作用域

    关于闭包函数,之前在聊过.这里忽略了一点,不管是Go/Php/Python,闭包都存在局部变量的引用.我们还是先看个例子: PHP示例: $list = []; for ($i = 0; $i < ...