当前位置: 首页 > news >正文

Linux - 还不懂 gdb 调试器?(调试软件)

前言

当前,我们可以使用 make/makefile 来程序化执行代码文件;可以使用 gcc/g++ 等编译器来编译代码;可以使用 vim 编辑器来编写代码;其实在 Linux 当中还有一个工具,可以实现调试工作,这个工具就是 -- gdb。

在了解调试器之前,你应该对代码的发布版本做一些了解:

我们在 VS 当中,在开始执行代码之前,可以选择以两种方式执行这个代码:debug & release :

一般在开发期间使用的都是 debug 模式,在编写好代码之后,如果我们的代码提交到远端,到客户手上的时候,比如在公司当中,用git提交到公司的 仓库当中,公司就可以以release 版本发布,同时,测试人员测试的模式也是 release 版本的。

debug 版本能调试 而 release 版本不能调试。而且,debug 版本代码文件要比 release 版本文件要大上不少。release 版本在执行效率上也要比 debug 要高。

那么出现上述几种区别的原因就是:debug 版本的代码,在形成可执行文件的时候,会生成调试信息,而 这个调试信息 是 release 版本没有的。

在 Linux 当中使用 gcc/g++ 编译器编译可执行文件时候,默认是以 release 的方式进行发布的。无法直接调试,如果要想以 dubug 方式发布,在使用 gc/g++ 编译的时候,需要带上 -g 选项来进行编译。 

 在 下述博客的  进行了详细介绍,包括 如果查看 debug 文件等等:

Linux - 配置系统白名单 - gcc/g++_linux 白名单-CSDN博客

gdb 调试器

 使用如下命令,就可以调试一个 可执行文件:

gdb 可执行文件名

如果,在使用上述命令之后,出现如下这个谈话框,并且没有任何报错的话,说明,当前你已经进入了 调试的 交互界面了:

如上所示,text 是一个可以调试的可执行程序,出现上述界面代表你已经成功进入到 调试界面了。 

如果想退出的话,可以使用 q/quit

 此时,我们还看不到代码,因为gdb 是以命令行的形式来进行 查看代码 和 调试代码的,不像 windows 当中 是使用图形化界面来实现,我们可以直接看到代码。

此时,你可以使用 list/l 来查看全部代码 :

你可以发现,我们上述是使用了两次命令(一次 list 一次 l),才查看到了全部的代码,其实 单独使用 list/l 不一定会从第一行显示全部的代码。 所以,我们的带上参数:

l/list 0  (0代表行数,可是代码当中任意行开始)就代表 从第 0 行开始显示:
 

 上述都是只打印了 10 行,如果我们想显示全部代码的话,下面有一种方式:

当我们使用了 l/list 0 这个命令之后,其实 gdb 是会自动记录上一条指令的,当我们按下 回车之后(前提是 使用了 l/list 0 这个命令之后 ) ,他就会认为我们此时想要继续执行 list/l 命令,那么他就会继续显示代码(在上一次显示的最后一行的下一行开始):

而且,最后还会提示,从共有多少行代码。 


还可以 使用下述命令,来查看 代码当中某一个函数的全部代码:

list/l 函数名 


那么我们在调试的时候,肯定不只是 查看代码,而是要先找到问题所在,对于问题的所在,我们可以看报错位置,然后推测报错位置,然后使用条件断点,或者是在代码当中写入停止的代码语句,比如用 if 判断一下 ,当 程序走到哪一步的时候就停止,这种方法在 程序栈帧迭代较深的 代码当中尤其适用,比如 在 八数码问题当中,我们很有可能会遍历到很深的 状态矩阵当中(在八数码问题当中我们 不管使用 A* 还是sm 启发式算法,都会遍历出很多的 状态矩阵,这些状态矩阵就是 我们在挪动 其中方块,移动不同方块,和方块移动位置不同,都会产生不同的状态矩阵(也就是一种中间过程的情况)),关于八数码问题的介绍具体请看下述博客:八数码问题-c语言_八数码问题c语言代码_chihiro1122的博客-CSDN博客

之所以在上述举出这么多篇幅的例子,就是想说:调试最离不开的就是断点,不管是是在最开始的时候,比如在 VS 当中我们需要打上断点,然后按下 F5 程序就会直接运行到 断点处停止,然后我们进行 进步一调试;还有一种可能是在 调试阶段打上断点,在调试过程当中可能也会遇到程序运行比较麻烦的地方,也可以在调试过程当中打上断点来跳过这一步骤。

那么 gdb 作为一个好用的 调试器,他肯定也是支持断点的,那么接下来,将会对 gdb 当中打断点方式进行说明:


在 gdb 当中 运行程序,打断点 

在 gdb 调试界面下,使用 r 命令就可以直接运行程序:
 

由于此时我们没有在程序当中打上断点,所以此时程序就直接运行到结束了。退出的时候也是正常退出的,就类似在 VS 当中的 F5/ shift F5 开始调试一样。

使用 在 gdb 调试窗口下,使用 b 行号 可以在当前调试文件当中的 指定行打上断点。此时我们在使用 r 命令既可以从程序运行,运行到 指定断点处 停下来了:
 

 在 VS 当中如果我们在某一行打上了断点,是可以直接看到 这个红色的断点在哪一行存在的:

 但是在 gdb 当中,这个断点我们是看不见的,就算我们 打完断点之后再去 使用 l 0 查看整个代码还是看不了断点:

其实使用 info b 就可以查看我们打上的所有所在断点行数了:

我们发现,在使用 info b 命令之后,出现的不只有 断点所在代码行数,还有一些其他信息,这些信息所代表的意思,如下所示:

 我们发现,在gdb 当中的断点是有 编号的当我们像删除某一个断点的时候,不能像之前一样使用 行号来删除断点,而是应该使用 断点的编号来删除断点。在 gdb 当中我们可以使用 d 断点编号

来删除某一个结点:

 而且,需要注意的是,我们设置的断点这些信息,都是在当前gdb 运行进程之内使用的,也就是说,我们在当前 gdb 调试窗口下设置的各个调试信息,如果退出一个 gdb 然后在进去 gdb 调试的话,尽管是同一个文件,在上一次 gdb 进程当中保存的 调试信息都会删除。

 在gbd 当中进行 逐语句 逐过程 调试

在 VS 当中有两种 逐语句的方式 调试,一种是 F10 逐过程,另一种是 F11  逐语句。

逐语句好理解,逐过程其实就是跳过一个过程,一个函数可以被称为一个过程。

使用 n/next 命令就可以进行 逐过程调试

 当我们进行调试运行代码之后,在断点信息当中还有多出一个信息:断点被命中的次数

像上述两个断点,被命中的次数都是 1。 

使用 s 命令 进行 逐语句调试

gdb 当中的监视窗口

 在 VS 当中的监视窗口也是必不可少的,监视可以极大的方便我们查看某变量当前是否合法,或则可以查看很多很多的信息,具体要看自己怎么使用调试:

 在gdb 当中也肯定不能缺少 调试窗口,但是因为 gdb 不是图形化界面,所以要 手动输入某个变量,来让 gdb 知道你当前想要查看哪一个变量的值。

我们使用 p 变量名/变量的某些变形之后的值 这个命令就可以查看 这个变量的值,或者是这个变量变形之后的值了。

此时我们就知道了,a 变量的值 在当前程序执行状态下 就是 10。 

和VS 当中的调试窗口一样,我们还可以通过调试窗口,查看到 a 的地址等等变形信息:

 但是,你有没有发现上述的监视太挫了,VS 当中还可以一遍进行 逐步调试,一般查看 变量的值,而上述 的 p 还有一个一个打出来。

其实 gdb 当中也是有 常显示 监视窗口命令的:display 变量名/变量的某些变形之后的值   ,这样的话,输入的变量 就会一直跟着你调试一起 走:

 如果不想 常显示变量值,可以使用 undisplay 命令,但是这个命令不能再后面直接加 变量名等等信息来删除掉 该变量信息的 监视信息
 

可以发现,是不行的。

 需要注意的是:在常显示的 变量信息 当中,每一个信息是有自己的编号的,和上述 删除断点一样,需要按照编号来进行删除,也就是 使用 undisplay 常显示变量信息编号 删除某一个常显示信息:

可以发现此时就删除成功了。

对于 常显示信息编号,就是显示信息的最左侧数字
 

 until 跳转指令 - finish 结束当前函数执行指令

 假设我们现在在一个函数的循环体当中,现在已经陷入了这个循环体,但是这个我们又想跳出当前这个循环体 ,查看这个循环体结束之后,修改的内容,此时我们就可以使用 until 指定行 来跳转到某一行。

 像上述我们使用 until 跳转出函数的循环体的时候,需要查看我们想要跳转到那一行,如果当前只是想要 跳出这个函数的话,也就是只是把当前函数执行完毕,然后查看这个函数的执行结果,那么我们可以在函数当中运行时,使用 finish 指令来结束当前函数的执行

 finish 的使用场景,举个例子,比如当前写的代码崩掉了,但是在主函数当中有 很多个函数需要我们去判断,此时我们要想知道是哪一个函数当中导致代码奔溃的话,就可以执行具体函数当中,使用 finish 来执行函数体,看看是那个函数导致程序奔溃的。

continue 跳到下一个断点

 VS 当中你肯定使用 F5 来跳到下一个断点处,在gdb 当中使用 countinue 也能达到 直接从当前位置跳到下一个断点的功能。

 修改断点的 Enb 值

VS 当中右键 断点可以选择禁用断点,或者是启用断点,同样的 在gdb 当中有 Enb 值,这个值只有两个值,y or n ,也就代表着这个断点是否被启用。

使用 disable 断点编号 就可以修改 Enb 值:

 此时我们 r 运行程序,直接就运行到 第三个断点处了,第一第二个断点已经被跳过了(上述是21 行是因为 20 行断点处为空行,gdb 自动跳过 了

 gdb 命令总结

gdb 当中还有很多命令,像 b 命令打断点,可以用 b 文件名:行号  给指定可执行文件的行号位置处打上断点。

b 函数名 这种方式打出的断点,本质是就是在函数体的起始位置处,也就是函数体的第一行代码当中打上断点:

 总结:

  • list/l 行号:显示binFile源代码,接着上次的位置往下列,每次列10行。
  • list/l 函数名:列出某个函数的源代码。
  • r或run:运行程序。
  • n 或 next:单条执行。
  • s或step:进入函数调用
  • break(b) 行号:在某一行设置断点
  • break 函数名:在某个函数开头设置断点
  • info break :查看断点信息。
  • finish:执行到当前函数返回,然后挺下来等待命令
  • print(p):打印表达式的值,通过表达式可以修改变量的值或者调用函数
  • p 变量:打印变量值。
  • set var:修改变量的值
  • continue(或c):从当前位置开始连续而非单步执行程序
  • run(或r):从开始连续而非单步执行程序
  • delete breakpoints:删除所有断点
  • delete breakpoints n:删除序号为n的断点
  • disable breakpoints:禁用断点
  • enable breakpoints:启用断点
  • info(或i) breakpoints:参看当前设置了哪些断点
  • display 变量名:跟踪查看一个变量,每次停下来都显示它的值
  • undisplay:取消对先前设置的那些变量的跟踪
  • until X行号:跳至X行
  • breaktrace(或bt):查看各级函数调用及参数
  • info(i) locals:查看当前栈帧局部变量的值(相当于查看 VS 当中本地变量这个对话框)
  • quit:退出gdb
     

相关文章:

Linux - 还不懂 gdb 调试器?(调试软件)

前言 当前,我们可以使用 make/makefile 来程序化执行代码文件;可以使用 gcc/g 等编译器来编译代码;可以使用 vim 编辑器来编写代码;其实在 Linux 当中还有一个工具,可以实现调试工作,这个工具就是 -- gdb。…...

Linux:程序地址空间/虚拟地址等相关概念理解

文章目录 程序地址空间虚拟地址和物理地址地址的转换地址空间是什么? 程序地址空间 在C和C程序中,一直有一个观点是,程序中的各个变量等都会有一定的地址空间,因此才会有诸如取地址,通过地址访问等操作,那…...

Python之爬虫

目录 HTTP请求HTTP响应获得页面响应伪装用户访问打包数据爬取豆瓣top250 HTTP请求 HTTP:HypertextTransferProtcol 超文本传输协议 1、请求行 POST/user/info?new_usertrue HTTP/1.1#资源了路径user/info 查询参数new_usertrue 协议版本HTTP/1.1 2、请求头 Ho…...

打造自己的前端组件库(奶妈版,超详细)

打造自己的前端组件库 demo是开源的,自己上npm 或者 github 上都能搜到 新建vue项目(sass js vue2) vue create yt-ui 修改文件目录(如下) 修改: 1.src 更名 examples; 2. src/components移动到项目最外层;3.vue.config.js更改入口文件 /…...

6.调制阶数相关

1、调制阶数与峰均比的关系 调制阶数(modulation order)对峰均比(有一定的影响。 峰均比是用于衡量调制信号或波形在幅度上的动态范围的指标。它表示信号的最大峰值与平均功率之间的比值。较高的峰均比可能导致信号在传输或放大过程中出现过…...

Maven多模块管理(转载)

注意:父模块需设定打包方式为pom https://cloud.tencent.com/developer/article/1667275 dependencyManagement 统一管理子类依赖版本 在父类maven中加入,不会继承给子类,只能规定子类的依赖版本,子类加入dependence后无需写入 …...

运维学习CentOS 7进行Nightingale二进制部署

.因为Nightingale需要MySQL保存一些数据,所以可以参考《CentOS 7.6使用mysql-8.0.31-1.el7.x86_64.rpm-bundle.tar安装Mysql 8.0》部署MySQL。 https://github.com/ccfos/nightingale/releases是可以github上下载Nightingale二进制安装包。 https://n9e.github.io/…...

安装Docker

本安装教程参考Docker官方文档,地址如下:https://docs.docker.com/engine/install/centos/ 卸载旧版 首先如果系统中已经存在旧的Docker,则先卸载: yum remove docker \ docker-client \ docker-client-latest \ docker-common…...

【uniapp/uView】解决消息提示框悬浮在下拉框之上

需要实现这样的效果&#xff0c;即 toast 消息提示框在 popup 下拉框之上&#xff1a; 解决方法&#xff0c;把 <u-toast ref"uToast" /> 放在 u-popup 里面即可&#xff0c;这样就可以提升 toast 的优先级&#xff1a; <!-- 弹出下拉框 --><u-popu…...

有效管理token,充分发挥ChatGPT的能力

目录 给提供了 Token 的计算工具,来理解一下Token的计算方式,网址如下: 窗口如下: 实际消耗 Token 数量为 59个,换算之后为2.1-2.2的比例,即一个汉字消耗2.12.2个Token, 再测一下英文的Token消耗,包含空格在内,一共52个英文字母,消耗Token 13个,正好对应13个单词,…...

Python —— 验证码的处理执行JavaScript语句

1、验证码的处理 1、概述&绕过验证码的方案 很多的网站都在登录页面加入了识别文字&#xff0c;识别图片&#xff0c;拖动拼图的验证码方式来防止爬虫、恶意注册 等&#xff0c;如果是做自动化&#xff0c;需要绕过验证码才能进入下一步操作&#xff0c;那么有4种方案可以…...

MS12_020 3389远程溢出漏洞

1.search ms12_020 搜索ms12_020 2.use auxiliary/scanner/rdp/ms12_020_check 检查是否存在ms12_020漏洞 show options 查看所需参数 set RHOSTS x.x.x.x 设置目标IP地址 run 执行 检测出来有Ms12_020漏洞 3.use auxiliary/dos/windows/rdp/ms12_020_maxchannelids 选择…...

Pytorch ddp切换forward函数 验证ddp是否生效

DDP及其在pytorch中应用 ddp默认调用forward函数&#xff0c;有些模型无法使用forward函数&#xff0c;可以对模型包装一下。 class modelWraper(nn.Module):def __init__(self, model):super().__init__()self.model modeldef forward(self, *args, **kwargs):return self.…...

C++中按引用向函数传递参数

C中按引用向函数传递参数 在参数传递过程中&#xff0c;如果实参与引用参数不匹配&#xff0c;C将生成临时变量。当前&#xff0c;仅当参数为 const 引用时&#xff0c;C才允许这么做&#xff0c;但以前不 是这样。如果引用参数是 const&#xff0c;则编译器将在下面两种情况…...

【Asp.net】Asp.net core中IIS配置注意事项

1、应用地址池设为无托管代码 一、提示&#xff1a;关于IIS上运行ASP.NET Core 站点的“HTTP 500.19”错误 安装dotnet-hosting-3.1.2-win.exe ASP.NET Core 3.1 Runtime (v3.1.2)下载地址&#xff1a; https://download.visualstudio.microsoft.com/download/pr/dd119832-dc4…...

Redis实现附近商户

GEO数据结构的基本用法 GEO就是Geolocation的简写形式&#xff0c;代表地理坐标。Redis在3.2版本中加入了对GEO的支持&#xff0c;允许存储地理坐标信息&#xff0c;帮助我们根据经纬度来检索数据。常见的命令有&#xff1a; GEOADD&#xff1a;添加一个地理空间信息&#xf…...

【COMP305 LEC 3 LEC 4】

LEC 3 A basic abstract model for a biological neuron 1. Weights of connections Neuron gets fired if it has received from the presynaptic neurons 突触前神经元 a summary impulse 脉冲, which is above a certain threshold. Signal from a single synapse突触 ma…...

国密https访问

前言 现在的SSL的加密算法实际上主要是国际算法&#xff0c;包括JDK&#xff0c;Go等语言也仅支持国际算法加密&#xff08;毕竟是国外开源项目&#xff09;&#xff0c;hash。随着国密算法的普及&#xff0c;比如openssl就支持国密了&#xff0c;还要新版本的Linux内核也开始…...

31二叉树-递归遍历二叉树

目录 LeetCode之路——145. 二叉树的后序遍历 分析 LeetCode之路——94. 二叉树的中序遍历 分析 LeetCode之路——145. 二叉树的后序遍历 给你一棵二叉树的根节点 root &#xff0c;返回其节点值的 后序遍历 。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出…...

【【萌新的FPGA学习之管脚设定xdc文件】】

萌新的FPGA学习之管脚设定xdc文件 xdc文件可以自己设置 也可以匹配 我们根据正点原子的流水灯管脚设定 主要讲述一下 各个英文设计是什么意思 Name&#xff1a;工程中顶层端口的名称。 Direction&#xff1a;说明管脚是输入还是输出。 Neg Diff Pair&#xff1a;负差分对&…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO&#xff1a;支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题&#xff1a;MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者&#xff1a;Yanyuan Chen, Dexuan Xu, Yu Hu…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日&#xff0c;中天合创屋面分布式光伏发电项目顺利并网发电&#xff0c;该项目位于内蒙古自治区鄂尔多斯市乌审旗&#xff0c;项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站&#xff0c;总装机容量为9.96MWp。 项目投运后&#xff0c;每年可节约标煤3670…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

Rapidio门铃消息FIFO溢出机制

关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系&#xff0c;以下是深入解析&#xff1a; 门铃FIFO溢出的本质 在RapidIO系统中&#xff0c;门铃消息FIFO是硬件控制器内部的缓冲区&#xff0c;用于临时存储接收到的门铃消息&#xff08;Doorbell Message&#xff09;。…...

Python ROS2【机器人中间件框架】 简介

销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...

力扣热题100 k个一组反转链表题解

题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...

C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...

redis和redission的区别

Redis 和 Redisson 是两个密切相关但又本质不同的技术&#xff0c;它们扮演着完全不同的角色&#xff1a; Redis: 内存数据库/数据结构存储 本质&#xff1a; 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能&#xff1a; 提供丰…...