前言:
编写代码我们使用vim,编译代码我们使用gcc/g++,但是我们,不能保证代码没问题,所以调试是必不可少的。与gcc/vim一样,Linux下的调试功能也是独立的一个工具——gdb 那么我们话不多说,开启今天的话题!
✈️ gdb背景
- 我们知道,程序的发布方式有两种:dubug模式 和 release模式。
- Linux gcc/g++编译出来的 二进制程序,默认是release模式。
- 要使用gdb调试工具,必须在源代码上生成二进制程序的时候,加上 -g 选项。
为了能够控制在源码生成二进制程序的时候加上-g选项,我们可以在makefile文件中进行操作:
我们在windows写代码时,调试工具大家多多少少也都用过,但是为什么还分为debug版本和release版本呢?或者说他们的区别是什么?
区别就是,在debug模式下形成的可执行程序会给我们添加调试信息。在release模式下形成的可执行程序会给我们去掉调试信息。 结论:release模式下的程序体积更小,性能更好,debug模式下可以进行调试,release模式下不能调试!
一般我们应用是面向广大用户的,用户只是需要使用应用即可,总不能让他们用调试工具来调试吧。所以一般我们给用户的发布版本就是release版本。
所以默认情况下,gdb是以release版本发布的,那么我们如何让gdb以debug版本发布呢?使用 readelf命令 可以读取可执行程序的格式
可以看到,debug的调试信息就出来了,我们再将makefile中目标文件的-d删除:
✈️ gdb的使用
通过前面的学习,我们已经知道了gcc/g++的 默认行为:
- 默认是动态链接
- 默认是release版本发布
我们将makefile文件更改之后,再次使用make命令所生成的可执行程序就是 带有调试信息的可执行程序,这个时候就可以对程序进行调试了。
调试方法:
gdb 带有调试信息的可执行程序#进入调试页面
如果你的Linux下没有gdb调试工具可以用以下指令安装对应的调试工具:
yum -y install gdb#安装gdb调试工具
为了能够更好地理解gdb调试工具,我们可以结合着windows下的vs的调试来进行比较。
🔎 开始使用
我们有了带调试信息的可执行程序之后,使用 gdb mybin,进入到调试页面:
当我们看到这样的页面,就说明你已经开始调试了,下面我来一一介绍在gdb中对应指令的功能。我们先准备一个.c的源文件:
- 📓list(或l)命令
作用: 显示指定行之后的代码(gdb自动记录最近一条指令),每次列10行。 用法: l 行号
或 l 函数名
测试用例:
为什么使用list 3不是从第三行开始的?这是因为gdb的list行为是 将要显示的行放在比较靠中间的位置,而不是从所输入的行开始显示。
- 📓run(或r)命令
作用: 运行程序。
用法: 直接输入r
再回车即可。
测试用例:
我们在vs下,打断点只需要在左侧边框按一下鼠标左键,取消也仅仅只需要按一下鼠标左键:
而我们Linux的gdb只有使用对应的指令才能打断点。
- 📓breakpoint(或b)命令
作用: 在某一行或者某个函数设置断点。
用法: b 行号
或b 函数名
或b 文件名:行号
- 📓info 命令
作用: 查看断点信息。
用法: info b
测试用例:
- 📓d命令
作用: 删除断点。
用法: d 断点编号
测试用例:
断点删除 不能根据行号来删除,只能根据断点编号来删除。
在vs中,我们也可以禁用断点:
禁用断点之后,调试就不会从这里停下来了,在gdb中,我们也有禁用断点的指令。
- 📓disable/enable命令
作用: 使能(禁用/开启)断点。
用法: disable/enable 断点编号
测试用例:
断点禁用之后运行是不会从被禁止断点处停下的。
如果运行时经过断点,那么在info b的时候,就会显示命中次数:
在vs中,我们有单步调试逐语句和逐过程的快捷键:
那么在Linux下gdb调试工具的单步调试就是:
- 📓next(或n)命令
作用: 逐过程进行单步调试
用法: 程序在运行时直接输入n回车即可。
测试用例:
- 📓step(或s)命令
作用: 逐语句进行单步调试。
用法: 程序在运行时直接输入s回车即可。
测试用例:
在vs中,我们可以在调试里的监视窗口对变量的内容或者地址进行显示。
而在Linux下的gdb中,我们使用如下命令来显示变量内容和地址。
- 📓p命令
作用: 显示变量的内容和地址
用法: p 变量名
测试用例:
- 📓display/undisplay命令
作用: 常显示 变量的内容和地址。
用法: display 变量名/取地址
和undisplay 编号
测试用例:
📓continue(或c)命令
作用: 从一个断点运行到下一个断点。
用法: 程序运行时直接输入c回车,从这个断点运行到下个断点。
测试用例:
- 📓finish命令
作用: 将一个函数运行结束,就停下来。
用法: 程序运行时直接使用finish命令即可。
测试用例:
- 📓until命令
作用: 在一个范围内直接运行到指定行。
用法: until 行号
测试用例:
在vs下,我们要想修改变量的值,需要打开源文件,再进行修改,修改完之后再调试,而在Linux下的gdb工具,可以实现 不用退出调试更改变量,使用set var命令即可。
- 📓set var命令
作用: 修改一个变量的内容。
用法: set var 变量名=修改的值
测试用例:
- 📓bt命令
作用: 查看调用堆栈信息。
用法: 直接输入bt回车。
测试用例:
以上就是gdb调试的一些常用指令操作了,如果要退出gdb模式只需要 输入q再回车 即可退出gdb模式。
✈️ 总结
- 想要进行调试,需要再makefile文件里生成目标文件时加上-g选项,生成的可执行程序可以使用readelf指令查看是否具有调试信息。
- 操作理念是具有迁移性的,在windows的os下,我们使用vs进行调试,只不过在Linux下使用命令行的形式来进行调试,但是调试都是一样的。
- 常用调试指令不用记,只要多使用使用,这些都会接触到。
如果这篇文章对你有帮助的话,还望三连支持一下博主~~