Linux基础环境开发工具的使用(三):gdb调试器

Linux基础环境开发工具的使用[三]:gdb调试器

  • 一.调试命令的应用场景
    • 1.为什么要介绍调试命令的应用场景呢?
    • 2.调试命令的应用场景
      • 1.找到问题
        • 1.不借助调试
        • 2.调试
      • 2.解决问题
        • 1.不借助调试
        • 2.借助调试
  • 二.调试命令
    • 1.gdb使用的前置说明
    • 2.基础指令
    • 3.断点相关指令
    • 4.范围查找相关操作
    • 5.局部逐行查找
    • 6.监视变量
    • 7.其他命令

在C语言的学习过程中,我们学习过VS这个集成开发环境下的调试功能
对于我们排查代码中的问题发挥了非常重要的作用
那么在Linux环境下有没有一种调试器能让我们去调试代码呢?
是有的,就是我们今天要介绍的gdb

一.调试命令的应用场景

1.为什么要介绍调试命令的应用场景呢?

Linux基础环境开发工具的使用(三):gdb调试器_第1张图片

2.调试命令的应用场景

Linux基础环境开发工具的使用(三):gdb调试器_第2张图片

1.找到问题

1.不借助调试

Linux基础环境开发工具的使用(三):gdb调试器_第3张图片

2.调试

Linux基础环境开发工具的使用(三):gdb调试器_第4张图片

2.解决问题

1.不借助调试

一部分人选择走读代码/看上下文的方式来发现该位置出现这个问题的原因
然后更有针对性地去解决这个问题

2.借助调试

在这里插入图片描述

二.调试命令

首先先给大家看一下gdb的调试命令:
Linux基础环境开发工具的使用(三):gdb调试器_第5张图片
下面会给大家一一介绍
但是现在首先要说明的是:

1.gdb使用的前置说明

1.安装gdb

sudo yum install -y gdb

Linux基础环境开发工具的使用(三):gdb调试器_第6张图片

gcc -o 想要生成的可执行程序 依赖的源文件 -g
或者:
gcc 依赖的源文件 -o 想要生成的可执行程序 -g

我们对待gdb的态度是:
gdb就是一个调试工具,跟VS这种调试工具的唯一区别就是使用方式不同而已,但是调试命令的应用场景是完全相同的

我们以这份代码为例:
Linux基础环境开发工具的使用(三):gdb调试器_第7张图片
下面是makefile
Linux基础环境开发工具的使用(三):gdb调试器_第8张图片
Linux基础环境开发工具的使用(三):gdb调试器_第9张图片
编译成功
然后我们gdb mytest_debug开始调试
Linux基础环境开发工具的使用(三):gdb调试器_第10张图片
刚进入调试之后是这样的

2.基础指令

Linux基础环境开发工具的使用(三):gdb调试器_第11张图片

l 行号:显示指定行之后的代码(注意:每次只显示10行,想要继续显示回车即可)

一开始这个gdb可能不会从第一行开始显示
Linux基础环境开发工具的使用(三):gdb调试器_第12张图片
所以我们可以l 1从第一行开始显示
Linux基础环境开发工具的使用(三):gdb调试器_第13张图片
一次只显示10行,我们可以回车继续再显示10行
周而复始直到显示完所有行
Linux基础环境开发工具的使用(三):gdb调试器_第14张图片

r: 从开始连续而非单步执行程序

也就是说如果我们此时没有设置断点,那么我们执行r就会直接运行到程序结束才停
Linux基础环境开发工具的使用(三):gdb调试器_第15张图片

quit:退出gdb

在这里插入图片描述

3.断点相关指令

Linux基础环境开发工具的使用(三):gdb调试器_第16张图片

b 行号/函数名/文件名:行号 :在某一行设置断点
(这个文件名:行号就意味着可以指定具体文件设置断点,
这个函数名就是对该函数内部的第一条语句位置设置断点)
info b :查看目前所设置的所有的断点信息。

我们在第15行,17行和19行都设置一个断点
然后info b来查看所有的断点信息
Linux基础环境开发工具的使用(三):gdb调试器_第17张图片
然后我们给Sum函数设置一个断点
Linux基础环境开发工具的使用(三):gdb调试器_第18张图片
然后我们指定test.c这个文件来给第10行设置断点
在这里插入图片描述
Linux基础环境开发工具的使用(三):gdb调试器_第19张图片

d n:删除编号为n的断点

然后我们删除3号断点
Linux基础环境开发工具的使用(三):gdb调试器_第20张图片

disable n:  禁用编号为n的断点
enable n:启用编号为n的断点

然后我们禁用4号断点和2号断点,接着启用2号断点
Linux基础环境开发工具的使用(三):gdb调试器_第21张图片

4.范围查找相关操作

Linux基础环境开发工具的使用(三):gdb调试器_第22张图片
目前我们程序还未运行,然后我们执行r,会运行的1号断点的位置(第15行)
Linux基础环境开发工具的使用(三):gdb调试器_第23张图片

c:从一个断点运行到下一个断点(范围查找)

然后我们c,程序会运行到2号断点位置(第17行)
Linux基础环境开发工具的使用(三):gdb调试器_第24张图片
因为我们的3号断点被删除了,4号断点被禁用了
所以我们接着c会运行到5号断点位置(第10行)
Linux基础环境开发工具的使用(三):gdb调试器_第25张图片
第5号断点已经是我们最后一个断点了,接着c,程序会运行到最后才停下
Linux基础环境开发工具的使用(三):gdb调试器_第26张图片
然后我们再info b
会发现:
Linux基础环境开发工具的使用(三):gdb调试器_第27张图片
那么我下一次调试的时候这些断点信息还会在吗?
答案是:不会,这些断点信息会自动清空
我quit退出gdb
然后在进入
Linux基础环境开发工具的使用(三):gdb调试器_第28张图片
然后我重新设置断点
Linux基础环境开发工具的使用(三):gdb调试器_第29张图片
然后我r运行到第4行

finish:将一个函数运行结束就停止下来(范围查找)

Linux基础环境开发工具的使用(三):gdb调试器_第30张图片
然后finish,程序会运行到该函数(Sum)结束为止
Linux基础环境开发工具的使用(三):gdb调试器_第31张图片
然后我想直接运行到第20行
执行until 20

until 行号:在一个范围内,直接运行到指定行(范围查找)

Linux基础环境开发工具的使用(三):gdb调试器_第32张图片

5.局部逐行查找

Linux基础环境开发工具的使用(三):gdb调试器_第33张图片

n:逐过程调试,不会进入函数体内部(就是VS中的F10)

我们重新开始进入gdb,开始下面的操作
Linux基础环境开发工具的使用(三):gdb调试器_第34张图片
然后r运行到第17行
Linux基础环境开发工具的使用(三):gdb调试器_第35张图片
接着我n
程序会运行到第19行(因为第18行是空行,没有语句)
并不会进入Sum函数当中
Linux基础环境开发工具的使用(三):gdb调试器_第36张图片
然后我们继续c,因为我们只设置了一个断点,所以继续c会直接运行到程序结束
Linux基础环境开发工具的使用(三):gdb调试器_第37张图片

s:逐语句调试,会进入函数体内部进行调试(就是VS中的F11)

然后我们依然是先r运行到第17行,
然后s
Linux基础环境开发工具的使用(三):gdb调试器_第38张图片
因为在这里插入图片描述
所以我们可以直接回车单步执行
Linux基础环境开发工具的使用(三):gdb调试器_第39张图片
这个单步执行的方式,n也一样
n和s的区别只有进不进入函数的区别

6.监视变量

Linux基础环境开发工具的使用(三):gdb调试器_第40张图片
这个时候我想看一下i,n,sum的值,i和n的地址

p 变量:显示变量的内容或地址

Linux基础环境开发工具的使用(三):gdb调试器_第41张图片
那么怎么常显示呢?

display 变量名/变量的地址:跟踪查看一个变量,常显示该变量的内容或地址(就是VS中的监视窗口)

undisplay 该变量的编号:取消对该变量的监视

我们可以display
Linux基础环境开发工具的使用(三):gdb调试器_第42张图片
我现在不想常显示sum和&i了,可以使用undisplay
Linux基础环境开发工具的使用(三):gdb调试器_第43张图片

7.其他命令

Linux基础环境开发工具的使用(三):gdb调试器_第44张图片
我现在想知道我在哪个函数里面,我是从哪个函数当中过来的
可以使用bt

bt:查看调用堆栈

Linux基础环境开发工具的使用(三):gdb调试器_第45张图片
我就可以看出我现在是在Sum函数当中,我是从main函数的第17行过来的

set var name=value:在接下来的调试过程中修改name这个变量的值为value
(没有修改文件中该变量的值,用于进行多分支(if else switch case....)测试)

下面我们来看一下这个set var的用处
我重新写一份代码
Linux基础环境开发工具的使用(三):gdb调试器_第46张图片
Linux基础环境开发工具的使用(三):gdb调试器_第47张图片
Linux基础环境开发工具的使用(三):gdb调试器_第48张图片
然后r运行到第5行
Linux基础环境开发工具的使用(三):gdb调试器_第49张图片
现在我想测试一下a2的情况,看看我a2的那个分支是否会按我预期的一样执行
Linux基础环境开发工具的使用(三):gdb调试器_第50张图片
我们发现这样就能够在调试的过程当中可以一次性成功测试所有分支,避免了我想要去测试其他分支时还需要再去修改源代码中相应的值
在这里插入图片描述
我们新建了一个文件test1.c
然后在里面写了一个死循环
Linux基础环境开发工具的使用(三):gdb调试器_第51张图片
下面我们测试一下:
1.直接r运行->程序卡住
Linux基础环境开发工具的使用(三):gdb调试器_第52张图片
然后我们ctrl+c退出此次r运行
2.借助断点进入Sum函数执行finish
Linux基础环境开发工具的使用(三):gdb调试器_第53张图片
然后我们ctrl+c退出,然后重新r运行到18行
3.接着until运行到20行
Linux基础环境开发工具的使用(三):gdb调试器_第54张图片

以上就是Linux基础环境开发工具的使用(三):gdb调试器的全部内容,希望能对大家有所帮助!

你可能感兴趣的:(Linux学习之路,linux,gdb,Linux基础开发工具的使用,调试器)