Linux学习之gdb的使用

2023-09-21 23:36:44

目录

1.Debug与Release模式

如何证明debug是可以被调试的?

2.Linux调试器-gdb使用 

gdb调试的指令

指令一:list(l) 查看源代码

编辑      ​编辑 命令二:run(r)运行程序

命令三:breakpoint(b)设置断点

命令四:infobreak(info)查看断点 命令五:delete breakpoint(d)删除断点

命令六:启用/禁用断点enable /disable breakpoint

命令七:next(n)逐过程运行

         命令八:step(s)逐语句运行

命令九: printf 变量(p 变量)查看变量

命令十: displayundisplay 变量       常显示查看变量(跟踪变量)

命令十一:undisplay 跟踪编号       取消常显示(取消跟踪)

命令十二:until  行号     执行中跳至x行

命令十三:finish 直接运行结束

 命令十四:continue(c) 当前位置开始连续而非单步执行程序

命令十五:bt   查看调用堆栈

 命令十六:set var 变量    修改变量


1.Debug与Release模式

在学习c++时我们就已经了解到这两种编译模式。

Debug 通常称为调试版本,是通过一系列编译选项的配合,编译的结果通常包含调试信息,而且不做任何优化,以为开发人员提供 强大的应用程序调试能力。

Release:Release通常称为 发布版本,是为用户使用的,一般客户不允许在发布版本上进行调试。所以不保存调试信息,同时,它往往进行了各种优化,以期达到代码最小和速度最优

  总的来看,Debug与release是两种代码编译模式,Debug下代码可以被调试,而Release下会将代码优化

如何证明debug是可以被调试的?

     1.Debug模式下可以被调试主要是因为在编译后会添加Debug信息,从而使得文件可以被调试。

对于Release是没有这些信息的,仔细发现两种方式下编译的可执行程序大小是不一样的

ll 文件名//查看两种方式下的可执行程序大小

 2.我们还可以查看可执行程序里面的内容,很容易看出两者是存在差异的:

readelf -a 文件名 //可以查看二进制文件
readelf -S 文件名 | grep -i debug //通过管道筛选出是否有debug信息

 

如果一份代码要进行调试,这份代码的发布模式必须是Debug模式的,而当一份代码要进行发布时,测试人员进行测试的是Release版本,测试完成之后就会上线。

2.Linux调试器-gdb使用 

当我们学会了编译代码时,就想知道代码书写错误,程序报错如何去调试,对于Linux提供了gdb用来调试:

GDB是GNU symbolic debugger的缩写,是一款常用的程序调试器,主要用于调试C、C++、Go、Objective-C、OpenCL、Ada等编程语言编写的程序。

它可以帮助我们完成以下四个方面的功能:

  1. 启动你的程序,可以按照你的自定义的要求随心所欲地运行程序。
  2. 在某个指定的地方或条件下暂停程序。
  3. 当程序被停住时,可以检查此时你的程序中所发生的事。
  4. 在程序执行过程中修改程序中的变量或条件,将一个bug产生的影响修正从而测试其他bug。

其次我们还需要知道的是在linux环境下编译默认都是Release模式下,故无法被调试。我们需要借助gdb,那么我们如何调试呢?

gdb调试的指令

首先对于调试工具gdb也为我们提供了多种调试方法

调试命令:

退出: ctrl + d 或 quit 。

我们现在以一个求某个数的累加和的.c程序为例,在下面实验我们去如何调试:

对于gdb默认一般都是安装的,我们也可以查看是否拥有gdb:

gdb --v

查看拥有gdb之后,我们先尝试去gdb调试,先将我们的文件直接gcc编译生成可执行文件,之后我们直接对我们想要调试的可执行程序进行gdb 文件名:

gdb 文件名

之后我们就进入了gdb下命令窗口:

 可以看到对于我们想要调试的程序,这里会说对于我这个可执行文件(code.c),是没有debug的信息被发现,当前是无法被调试的,即当前调试指令时无效的。

这里对于Linux下的gcc 编译工具默认是在Release模式下编译,编译生成的文件是无法被调试的,故会报错无调试信息。那么如何去增加debug信息呢?

我们需要在编译生成可执行程序时增加编译选项:

gcc -g 文件 -o 目标文件 //添加-g选项,以debug方式编译文件

之后我们就可以调试该文件:

指令一:list(l) 查看源代码

l按gdb的方式显示代码                                 l  0  从开头开始打印

再次回车时(gdb会自动记录上一个命令),显示后面的源码,直到全部,此时会提示我们多少行已全部显示

         命令二:run(r)运行程序

直接r可以看到程序直接被运行完,结果出现

 

  命令三:breakpoint(b)设置断点

b 行号  //该行处设置断点

 设置完毕会返回关于断点的信息。

对于多源文件,gdb也可以打断点

b 文件名:行号

 其次我们还可以直接给出函数名来设置断点

b 函数名  //默认打断点在函数的入口处
b 文件名:函数名

 命令四:infobreak(info)查看断点

 可以看到在第六行设置一个断点,还有其地址,类型等。

 命令五:delete breakpoint(d)删除断点

d 断点编号

虽然打断点可以直接用行号和函数名,但是删除断点必须要用他的断点编号,所谓的断点编号就是在我们设置断点后返回的断点信息中的NUM,利用info也可以查看到。

 其中对于一个周期的调试下,断点的编号是一直递增的,当我们退出调试后,重新在调试即开启下一个周期,之前的都会被清除。

命令六:启用/禁用断点enable /disable breakpoint

对于一个断点,我们目前不想使用它,但不取消它,用来记录我们调试的区域,可以禁用它让他不起作用,其次我们也可以查看到一个断点的状态(y代表启用,n代表禁止)

现在我么来禁用一个端点

disable 断点编号

再开启它:

enable 断点编号

命令七:next(n)逐过程运行

 对于断点设置好之后就可以run了,程序直接跑到断点处执行,类比于vs的F10,之后断点处输入n就可以逐过程(一行一行的运行,遇到空行直接跳过)的运行程序,

可以看到运行到了下一行第7行,再次n,又运行到下一行,直到退出。

命令八:step(s)逐语句运行

所谓逐语句区别于逐过程,逐语句执行更加的严密仔细,一个一个语句运行,遇到函数直接进入函数内部,s之后,继续执行:

可以看到断点处开始执行,遇到函数,进入函数内部。

命令九: printf 变量(p 变量)查看变量

在上述逐语句的过程中,我们此时再循环内,此时就可以查看一些变量的值:

例如这里循环了四次,累加了四次,此时 i=4,sum =6,之后再运行再查看,就可以观察到变量的变化了。

当然我们也可以查看变量的地址:

命令十: displayundisplay 变量       常显示查看变量(跟踪变量)

对于上述p查看变量每次查看我都要输入,怎样可以跟vs的监视窗口的 效果一样的,长时间显示我们变量的变化,利用display我们也可以做到。、

 可以看到每一next逐过程执行时都会为我们自动打印我们所要看的变量的值。

命令十一:undisplay 跟踪编号       取消常显示(取消跟踪)

对于我们不长时间查看的变量,我们不能直接undisplay 变量来取消,仔细发现在我们每一次跟踪变量时,每一次显示都可以看到变量前有一个编号,而取消编号才能做取消跟踪。

可以看到取消掉了跟踪,不再显示变量。

命令十二:until  行号     执行中跳至x行

由于我此时在循环里,且循环比较大,一直next循环结束太过离谱,英雌我们可以直接跳至程序某一行。

 现在我跳至程序的第7行,打印结果,此时代码是抬到了20行,可以看到如果遇到断点会跳到断点处,若没有断点此时会跳至第7行。

故跳出循环有两种方式,一是设置断点,再run或者until眺出去,二是不设置断点直接跳出去。

命令十三:finish 直接运行结束

可以看到直接到程序结束,打印了结果

 命令十四:continue(c) 当前位置开始连续而非单步执行程序

简单说可以理解为从一个断点跳至另一个断点处。

命令十五:bt   查看调用堆栈

在运行过程中,查看函数的调用顺序,这里先调用主函数再调用addtop,因为这里是以栈的方式,故是倒着的顺序。

 命令十六:set var 变量    修改变量

我们可以在调试的过程中去修改变量达到我们想要的调试情况:

如这里i我们可以直接修改为10,查看我们改变时运行的效果。

更多推荐

Java学习笔记39——网络编程03

TCP通信程序TCP通信程序TCP通信原理TCP发送数据的步骤TCP接收数据的步骤TCP通讯程序练习练习1练习2练习3练习4练习5练习6TCP通信程序TCP通信原理TCP通信协议是一种可靠的网络协议,它在通信的两端各建立一个Socket对象,从而在通信的两端形成网络虚拟链路,一旦建立了虚拟的网络链路,两端的程序就可以通

URL与URI小结

文章目录一、URL是什么?URL的一般形式:二、分类三、URI总结一、URL是什么?每条由Web服务器返回的内容都是和它管理的某个文件相关联的,这些文件中的每一个都有一个唯一的名字,叫做URL(通用资源定位符),是互联网上一种资源的地址。例如:http://www.google.com:80/index.htmlURL

实训笔记——Spark计算框架

实训笔记——Spark计算框架Spark计算框架一、Spark的概述二、Spark的特点三、Spark的安装部署(安装部署Spark的ClusterManager-资源调度管理器的)3.1本地安装--无资源管理器3.2Spark的自带独立调度器Standalone3.2.1主从架构的软件3.2.2Master/work

第26章_瑞萨MCU零基础入门系列教程之独立看门狗定时器-IWDT

本教程基于韦东山百问网出的DShanMCU-RA6M5开发板进行编写,需要的同学可以在这里获取:https://item.taobao.com/item.htm?id=728461040949配套资料获取:https://renesas-docs.100ask.net瑞萨MCU零基础入门系列教程汇总:https://b

在springboot下将mybatis升级为mybatis-plus

在springboot下将mybatis升级为mybatis-plus1.整体描述2.具体步骤2.1更新pom引用2.2更新yml配置2.3更新config配置2.4BaseEntity修改3.程序启动4.总结1.整体描述之前项目工程用的是mybatis,现在需要将其替换为mybatis-plus,mybatis-pl

电商项目高级篇-01 elasticsearch

电商项目高级篇-01elasticsearch1、linux下安装elasticsearch和可视化工具2、docker设置虚拟机开机启动和容器开机启动3、elasticsearch的curd3.1、新增、更新3.2、查询1、linux下安装elasticsearch和可视化工具将安装好jdk1.8和tomcat的ce

使用jmeter+ant+jenkins+git搭建自动化测试平台

最近正在学习自动化测试,于是随手搭建了一下jmeter+ant+jenkins+git平台。接下来,我会按照jdk,jmeter,ant,jenkins,git这个顺序一步一步的搭建起来。一、jdk。这个就不多说了。我用的是1.8版本的,配环境变量网上一大堆。二、jmeter。官网下载:ApacheJMeter-Dow

数据科学的文本技术 Text Technology(IR信息检索、搜索引擎)

一、文章摘要1.内容*IntroductiontoIRandtextprocessing,systemcomponents*Zipf,Heaps,andothertextlaws*Pre-processing:tokenization,normalisation,stemming,stopping.*Indexing:

在IntelliJ IDEA 中安装阿里P3C以及使用指南

在IntelliJIDEA中安装阿里P3C以及使用指南1.关于阿里p3c1.1说明1.2什么是P3C插件1.3p3c的作用是什么2如何在IDEA中安装p3c2.1插件安装2.2插件使用3.参考连接1.关于阿里p3c1.1说明代码规范检查插件P3C,是根据《阿里巴巴java开发手册(黄山版)》转化而成的自动化插件。1.2

Lnmp架构之mysql数据库实战1

1、mysql数据库编译编译成功2、mysql数据库初始化配置数据目录全局文件修改内容生成初始化密码并进行初始化设定3、mysql主从复制什么是mysql的主从复制?MySQL的主从复制是一种常见的数据库复制技术,用于将一个数据库服务器(称为主服务器)上的数据同步到另一个或多个数据库服务器(称为从服务器)上。在主从复制

ElasticSearch

文章目录一、引言1.1海量数据1.2全文检索二、ES概述2.1ES的介绍2.2ES的由来三、ElasticSearch安装3.1安装ES&Kibana3.2安装IK分词器四、ElasticSearch基本操作4.1ES的结构4.1.1索引Index,分片和备份4.1.2类型Type4.1.3文档Doc4.1.4属性Fi

热文推荐