首页 > 系统相关 >在Linux系统中使用gdb调试一个代码

在Linux系统中使用gdb调试一个代码

时间:2023-09-18 19:33:08浏览次数:44  
标签:函数 Linux 命令 gdb 使用 断点 until 调试

首先我们知道在使用vs时,我们时可以通过调式一段代码来找出我们这段代码的逻辑错误在哪里的,但是在Linux中没有对应的图形化界面,我们应该怎么去调试一个代码呢?这里就需要使用道Linux中的一个工具叫做gdb。首先要检测你的操作系统中是否安装了gdb。

检测安装gdb

使用下面的指令

gdb --version

如果出现了你所对应的gdb的版本号,代表已经安装了gdb。

在Linux系统中使用gdb调试一个代码_函数返回

如果没有安装gdb请在已经安装了gcc和g++环境下执行下面的命令

sudo yum install -y gdb

gdb的使用

Linux中的Debug和Release

下面我们就来学习如何使用gdb这个工具。第一步我们肯定要先完成一段简单的易于调式的代码我写了下面的代码

在Linux系统中使用gdb调试一个代码_执行程序_02

这个函数一定是输出30的,但是如果我是用下面的指令来生成的可执行程序能够被调式吗?

g++ -o mybin test.cpp

如果这样写那么当你直接使用./mybin时能够输出30,但是如果你要使用gdb去调试这个代码是不可行的。

在Linux系统中使用gdb调试一个代码_函数返回_03

从上面能够看到当我直接执行这个mybin时是可以出现答案的,但是如果我想使用gdb去调试这个代码的时候,我在gdb中输入l指令就直接给我报错了,那么这是为什么呢?在使用vs的时候我们知道要调试一个代码那就需要我们将编译器的编译模式改成Debug模式,如果你在vs中是使用Release模式也是不可以使用调试的。那么这里也是同理,那么怎么证明这个mybin是在Release模式下生成的呢?最直观的方法就是再生成一个新的Debug模式的可执行程序,Debug模式下生成的可执行程序大小一般是比Release要大的,因为要加入一些调试的信息。而在Linux中如果要生成一个Debug模式下的可执行程序就要使用下面的命令。

g++ -o newmybin -g test.cpp

在Linux系统中使用gdb调试一个代码_执行程序_04

可以很明显的看到newmybin的文件大小是远大于mybin文件的。所以要使用gdb调试文件那么就要在使用g++时加上-g选项。

gdb基本命令

下面我们就拿newmybin文件来演示gdb的使用。

当我们使用

gdb <文件名>

在Linux系统中使用gdb调试一个代码_GDB_05

看到下面的这个界面之后,我们就遇到了第一个问题那就是我们连代码都看不到该怎么调试呢?所以这里就要使用list命令。

list命令

这个命令在gdb中可以直接使用l代替。

在Linux系统中使用gdb调试一个代码_函数返回_06

当执行了这个命令之后可以看到它显示了我所写的代码但是并没有显示完全而且并不是从第0行开始显示的。

那么我们可以想下面这样使用

l <你想要开始显示的行数>

在Linux系统中使用gdb调试一个代码_函数返回_07

可以看到我输入了l 0之后就从第0行开始往下显示了。如果我想要继续往下打印呢?那就不需要输入任何的命令直接回车即可,gdb会记住上次输入的命令

在Linux系统中使用gdb调试一个代码_函数返回_08

可以看到我在按了一个回车之后,就直接继续往下打印了,如果我在打印完成之后还按回车就会显示18行已经全部打印完毕了。

打上断电(b)命令和查看断点信息命令

那么现在我已经能够看到我的代码了,下一步自然就是打印断点了,打印断点的命令为

breakpoints(可以直接简写成b) <你要打的行数>

例如上面我打算在第8行打印上一个断点

就可以直接使用 b 8就可以了,那么如果我已经打上了断点我如何查看我打上断点的信息呢?

这里就要使用下面的命令

info b

在Linux系统中使用gdb调试一个代码_函数返回_09

从上图就可以看到我在第8行设置了一个断点。

开始执行调试命令

现在我已经在代码中加入了断点,现在要运行调试代码了要执行下面的命令

run(可简写成)

这个命令开始执行之后如果没有断点,就会直接出现最后的结果(如果是要打印的话)。

在Linux系统中使用gdb调试一个代码_执行程序_10

在上面的图上,我第一次运行的时候没有任何的断点所以r后直接出现了30,而第二次我在第8行打上了一个断点所以当我再一次run的时候就直接在第八行停下来了。

删除断点命令

既然能够打上断点和查看断点的信息自然也能够删除一个断点。删除断点需要使用下面的命令。

d <断点的编号>

需要注意的是,如果我想删除我当前的这个带吧在第八行的这个断点,使用b 8是不行的,那么什么是断点的编号呢?断点的编号就是我们在info b时看到的第一行的那个编号。

在Linux系统中使用gdb调试一个代码_函数返回_11

例如我这个在第八行的断点的编号就是2

那么如果我想要删除这个断点那就直接使用d 8就可以删除这个断点了。

在Linux系统中使用gdb调试一个代码_GDB_12

需要注意的是如果我现在依旧是在第8行重新打上断点,这个新断点的编号也不是2而是3。

暂时关闭和打开断点功能命令

那么当我在调试一段代码的时候,我已经不需要使用某一个断点了,但是我并不想删除这个断点有没有什么办法呢?这个办法就是暂时的关闭这个断点的功能。使用下面的命令

enable <断点的编号>

在Linux系统中使用gdb调试一个代码_函数返回_13

从上图可以看到我在第13行和第15行都设置了一个断点,但是当我将第13行的断点disable之后,再运行run就直接跳到15行了,但是我并没有删除第13行的断点。

如果我想再次启用这个断点则使用enable

enable <断点编号>

在Linux系统中使用gdb调试一个代码_GDB_14

可以看到当我使用enable将这个断点的功能重新打开之后再次使用r,就停到了第13行。

逐过程和逐语句命令

在使用vs调试的时候,在进入调试界面后如果遇到一个函数你不想进入函数那么你会选择f10(逐过程),而当你找到你所出错的函数处然后要进入到这个函数中时你会选择f11(逐语句)。那么在Linux中如何实现呢?

n(逐过程,类似于vs中的f10)
s(逐语句类似于vs中的f11)

显示变量的细节(监视功能)

在vs中我们只用打开监视窗口,然后输入我们想要查看的变量的名字即可以查看到这个变量的细节,而在Linux中我们若想要查看一个变量的细节可以使用下面的命令。

display <变量名和变量的地址可以看到变量的细节>

就以上面得那个代码为例子如果我想查看left得值,就可以直接使用display left即可。

在Linux系统中使用gdb调试一个代码_GDB_15

可以看到当我使用s进入到这个函数之后,就可以直接使用display left显示left的值了,但是如果此时你在输入n/s那么显示就会消失,那么有没有什么命令能让它一直显示在那里呢?

当然是存在的那就是使用undisplay

undisplay <变量名和变量的地址可以看到变量的细节>

使用这个命令之后,即使你在使用n/s命令,那么你所要查看的变量也不会消失。

until指令

until <行号>

在GDB中,until(简写为u)指令用于继续执行程序直到达到指定行号或函数返回。以下是until指令的使用方法:

在GDB命令提示符下,输入until或u,然后按回车键,程序将继续执行直到下一个断点或程序结束。

  1. 若要指定行号来执行程序,可以使用until <行号>u <行号>。例如,until 20表示程序将继续执行直到达到第20行。
  2. 若要指定函数来执行程序,可以使用until <函数名>u <函数名>。例如,until main表示程序将继续执行直到进入main函数。
  3. 可以使用until <行号> if <条件>u <行号> if <条件>来在达到指定行号时执行条件判断。例如,until 20 if i == 10表示程序将继续执行直到达到第20行,并且只有在变量i等于10时才停止。
  4. 若要在循环中使用until指令,可以使用until <行号> while <条件>u <行号> while <条件>。例如,until 20 while i < 10表示程序将继续执行直到达到第20行,并且只有在变量i小于10时才停止。

需要注意的是,行号可以是源代码中的行号,也可以是汇编代码中的指令地址。使用until指令时,建议在设置断点或单步执行程序后再使用,以确保在正确的位置使用until指令。

finish指令

finish

在gdb中,finish(简写为fin)指令用于连续执行程序,直到当前函数返回为止。以下是finish指令的使用方法:

  1. 在GDB命令提示符下,输入finishfin,然后按Enter键,程序将继续执行直到当前函数返回。如果当前函数是顶层函数(如main函数),则程序将执行完毕并停止。
  2. 可以使用finish if <条件>来在函数返回之前执行条件判断。例如,finish if i == 10表示程序将继续执行直到当前函数返回,并且只有在变量i等于10时才停止。

使用finish指令时,GDB会自动跳过当前函数内部的代码,并在函数返回之前停止执行。这对于跳过复杂的函数调用链以及快速返回到上一层调用函数很有用。需要注意的是,如果当前函数内部还有其他断点,GDB会在到达下一个断点之前停止执行。

c命令

在gdb中,c(简写为continue)命令用于继续执行程序,直到下一个断点或程序结束。以下是c命令的使用方法:

  1. 在GDB命令提示符下,输入ccontinue,然后按Enter键,程序将继续执行直到下一个断点或程序结束。
  2. 如果程序在运行时遇到断点,可以使用c命令来继续执行程序,跳过当前断点。
  3. 如果程序没有设置断点,使用c命令将使程序一直执行直到程序结束。
  4. 在程序执行期间,可以使用c命令来暂停程序的执行。这在你想在特定位置设置断点或观察程序状态时非常有用


希望这篇博客能对你有所帮助,如果有任何错误,请指出感激不尽。



标签:函数,Linux,命令,gdb,使用,断点,until,调试
From: https://blog.51cto.com/u_15838996/7514615

相关文章

  • spring boot 在Linux下服务启动报错Unable to find Java
    前言:最近在开发项目的过程中遇到了一些坑(也可能不是坑,是自己没弄过导致折腾了很久),我们项目中遇到有用到一些第三方的库,有些第三方库可能不支持openjdk,只支出jdk,所以就要更换一下jdk,然后服务器又是之前的前同事配置的,这时候我把服务器的jdk版本从原来的openjdk1.7换成了官方的......
  • 每天一个linux命令(32):gzip命令
    减少文件大小有两个明显的好处,一是可以减少存储空间,二是通过网络传输文件时,可以减少传输的时间。gzip是在Linux系统中经常使用的一个对文件进行压缩和解压缩的命令,既方便又好用。gzip不仅可以用来压缩大的、较少使用的文件以节省磁盘空间,还可以和tar命令一起构成Linux操作系统中......
  • Win32编程之debugview调试(十一)
    一、debugview本地调试代码中通过OutputDebugString()函数打印印象:for(inti=0;i<10;i++){OutputDebugString(TEXT("helloword"));}程序编程成功后,先打开DebugViewInclude:默认是*,打印所有通过OutputDebugString()的信息,可以自定义为指定的信息去查找Exc......
  • pytest+allure+jenkins+python+git,实现Linux服务器看测试报告,并发送邮件通知
    1、简介pytest:一种单元测试框架,与python自带的unittest测试框架类似,但是比unittest框架使用起来更简洁,效率更高。allure:是开源测试报告框架。jenkins:持续集成工具python:测试脚本语言git:开源的分布式版本控制系统2、Windows端我们需要开发测试代码,使用git上传到云端仓库2.1......
  • linux系统docker容器部署项目字体问题-Graphics2D在容器里面不显示字体
    继上一个博客中生成签章图片后,今日遇到一个问题,本地不管如何改代码,都会将签名文字显示出来。但是...........一旦部署在linux系统后,一直打印不出来,,纠结的呀。。完全没想到,原来是linux系统里面不兼容本地的字体,也就是没有那么多中文字体,除非安装。可以惊醒安装字体:参考文档:http:......
  • 基于Linux+宝塔面板+LNMP+Wordpress搭建的网站主页的网站漏洞修补的解决方案 (1)
    基于Linux+宝塔面板+LNMP+Wordpress搭建的网站主页1.网站漏洞修补的解决方案@目录基于Linux+宝塔面板+LNMP+Wordpress搭建的网站主页前言为什么要做网站漏洞扫描降低资产所面临的风险满足法律合规要求满足业界安全最佳实践及认证需求其他参考信息等级保护网络安全法安全建议漏......
  • Linux安装字体 java生成pdf中文乱码或提示未安装字体错误
    当使用java在生成pdf或者图片时,如生成的文档包含有中文在inux上运行,会出现未安装字体的错误活字体乱码,此时需要我们在服务器上安装中文字体:1、首先先看是否安装中文字体:fc-list:lang=zh-bash:list-fc:commandnotfound如出现上边提示,还未安装相关字体的软件包请按如下安......
  • Goland 断点调试Debug的操作
    第一步:进入编辑模式第二步:开始进行编辑第三步:就可以进行调式了......
  • TV音频调试
    在TV系统中,音频的输出功率一般由三部分控制:1.PRE(预分频器):设置预输入的强度,一般体现为gain值;2.AVC (自动增益控制):avcon后的效果取决于如何设置参数(就是降低功率~),avc的参数由攻击时间、释放时间、门限值等组成; [audioavc]AvcAttackTime=20;AvcReleaseTim......
  • linux 搭建NAS服务,实现window访问Linux的nas共享数据目录
    1、部署sudoyuminstall-ysambasamba-client2、创建用户sudouseradd-m<username>sudosmbpasswd-a<username>3、配置共享目录:举例共享目录为data目录[data]path=/home/datawritable=yesguestok=yesvalidusers=<username>readonly=nocreate......