✨个人主页:****Yohifo
🎉所属专栏:****Linux学习之旅
🎊每篇一句:****图片来源
🎃操作环境:****CentOS 7.6 阿里云远程服务器
- Whatever is worth doing is worth doing well.- 任何值得去做的事情,都值得把它做好。
文章目录
📘前言
**
vim
可以编写代码,
gcc/g++
可以编译代码,此时只最后一件神器,就能进行完整的开发工作,那就是通过
gdb
调试代码,毕竟谁都不敢保证自己的代码没有问题,所以就有调试器这种东西帮助我们定位问题,进而解决问题**
📘正文
**现在让我们一起进入
gdb
的世界,体验纯命令行调试代码的妙处**
注意:**需要提前下载好
gdb
**
$ sudo yum install -y gdb
📖生成可调试文件
**可能有的同学一安装好
gdb
就迫不及待地开始了调试,通过
gdb 最终生成文件
进入
gdb
后,会发现什么指令都用不了,除了
q
退出
gdb
和
r
运行程序**
原因很简单:**
gcc/g++
默认生成的程序为
realse
发行版,也就是说不含调试信息,所以我们首先要解决这个问题**
📃realse 与 debug
程序分为
realse
与
debug
两个版本,其中前者是给测试工程师找毛病的,而后者则是我们开发使用的版本,
debug
内置很多调试信息,因此它能很好的进行调试
而
gcc/g++
默认不会生成
debug
版的可执行程序,我们可以通过指令来搜索默认生成的程序中是否含有调试信息
$ readelf -S myfile | grep -i debug //在默认生成的可执行程序 myfile 中查找调试信息
想要解决问题也很简单:**在编译时,指定编译器生成
debug
版的程序就行了**
注意:**因为已经学习了
Makefile
,我们直接在文件中更改就行了**
//Makefile 文件中
$ gcc test.c -o myfile -g -std=c99
//注意:其中 -g 就是指定其生成 debug 版的程序;-std=c99 是让其支持C99标准
**我们先通过
make clean
指令清理原来的解决方案,然后再通过
make myfile
指令编译程序**
得到可执行程序后,用同样的方法对其进行查找
接下来就可以愉快的进入
gdb
进行调试了
📖调试打开与关闭
**首先要学习如何打开和关闭
gdb
**
📃启动调试
我们调试的对象是已经生成的可执行程序,并非最开始的源文件
这很好理解,因为在VS中也是先编译、再调试
通过
Makefile
的自动化任务生成
myfile
可执行程序
然后通过指令
gdb myfile
即可进入调试
$ gdb myfile //进入 gdb 调试
注意:**调试的是最终生成的可执行程序;要确保生成的程序为
debug
版,不然后续无法调试**
📃l 查看代码
**只要进入了
gdb
,我们可以通过
l
指令随时随地查看我们的代码,且查看代码时不会干扰其他调试命令**
**
l
命令一般是配合数字进行查看,每次只可查看十行,如
l 1
就表示从代码第一行开始查看其前后十行,按回车后可接着往下展示,直到代码展示完毕**
(gdb) l 1//从代码第一行开始查看其前后十行(gdb) l //默认查看代码最中间的十行内容
注意:**经过测试发现,
l
的查看策略是每次展示十行,然后想要查看的第n行位于中间,
l 1
能直接能从第一行开始的原因是前面已经没有代码了,因此如果默认只输入
l
就会展示当前代码的最中间位置前后十行**
📃退出调试
**
gdb
退出不像
vim
那样麻烦,指令
q
就表示退出
gdb
调试**
(gdb) q //退出 gdb 调试
📖运行与断点
调试最重要的目的是帮助我们快速定位到问题,然后分析解决,此时断点就显得很重要了,如果没有断点,那只能一步步的调试,效率很低,下面就来看看如何让程序在
gdb
中跑起来及断点相关操作
📃r 运行程序
gdb
中能直接快速运行程序,假设没有断点,那么程序会直接运行出结果
(gdb) r //运行程序
**其实此时可以直接把这个看作VS中的黑框框,
r
就相当于
F5
,在没有断点的情况下,程序会直接出结果的,而最终的结果值也会紧跟着输出**
📃b 断点操作
断点在
gdb
中意为
breakpoint
,其中首字母
b
就表示断点的意思,因为是纯命令行操作,所以刚开始调试麻烦点是必然的
🖋️设置断点
**指令
b
需要配合行号或函数名进行断点设置**
(gdb) b 行号 //在指定行号打断点(gdb) b 函数名 //在指定函数处打断点
注意:纯命令打的断点不如图形化界面直观,但我们也可以通过指令查看断点信息
🖋️查看断点信息
指令
info b
可以搜索所有断点,并展示其详细信息
(info) b //查看所有断点信息
🖋️编号含义
查看断点信息时,会发现有一栏
num
,这表示每个断点的编号,**因为我们不能直接对断点进行区分,于是就需要引入编号这个概念,这个概念在
gdb
很多地方都有体现**
注意:**除非
gdb
关闭,否则它的编号是一直累计的,比如我们把断点1、2都删了,然后再新打一个断点,断点编号就为3**
🖋️取消断点
**有时候想取消断点,就可以通过
d 断点编号
,取消指定断点**
(gdb) d 断点编号 //由此可见断点编号的重要性
**有了断点之后,我们就可以配合
r
指令,运行至断点处**
注意:**不同于VS中的
F5
,
r
指令要么运行至最近一个断点处,要么将程序运行完,也就是说,
r
是无法实现两个断点间移动的,再次按
r
会提示是否重新运行程序**
📖单行与单步
调试这个东西总得一步一步来,不然问题就不好找到了
📃n 单行调试
单行调试即逐过程调试,对应着VS中的
F10
,即遇到函数不会进入,指令为
n
(gdb) n //单行调试,不会进入函数内部
单行:一行一行的来,每次运行完一行内容即可
📃s 单步调试
单步调试对应着VS中的
F11
,不同于单行调试,单步调试能进入函数内部,指令为
s
(gdb) s //单步运行,会进入函数内部
单步:即一步一步的来,如果遇到函数,就会进入函数内部,确保程序的每一步都被执行
📖查看变量
调试过程中还有一个很重要的工作:**查看变量信息,如VS中的监视窗口,假设没有监视功能,那么我们可能连变量的变化情况都无法捕捉到,庆幸的是
gdb
支持监视功能**
📃bt 查看调用堆栈
**程序运行时,会先为
main
函数建立栈帧,然后运行程序,如果遇到函数,就会为函数建立栈帧,执行函数,因此程序的运行本质上就是栈帧的创建与销毁**
**我们可以通过指令
bt
查看当前程序的堆栈调用情况**
(gdb) bt //查看调用堆栈情况
📃p 临时查看变量
指令
p 变量
可以查看指定变量的信息
(gdb) p 变量 //查看变量的信息
注意:**指令
p
只能做到临时监视,当执行下一条指令后,原来监视的变量就看不到了;可以看出,
p
监视出的值也是有编号的,每调用一次指令,编号就会累加一次**
📃display 常显示变量
**
gdb
当然也支持一直监视变量,使用指令
display
即可**
(gdb) display 变量 //常显示变量信息,不会随着指令的执行而消失
注意:**如果我们忘记了程序中有哪些变量,可以随时随地通过
l
指令查看,像这种查看式的指令,是不会影响其他指令运行的;不难发现,常显示的变量也有属于自己的编号,这个编号运行机制跟断点的一样,只要
gdb
不退出,它是会一直累加的**
编号存在的主要意义就是方便我们进行监视变量删除
(gdb) undisplay 变量编号 //取消监视指定变量
📖快速跳转
**
gdb
提供了一些快速跳转的指令,赋予了我们在不打断点的情况下进行跳转的权力(注:先要打断点将程序运行起来),这是VS做不到的**
📃until 指定行
程序运行后,我们可以直接通过
until 行号
的方式跳转至指定行,这个指令通常用来跳过循环
(gdb) until 行号 //跳转至指定行
📃finish 函数
这个指令主要是针对函数的,直接
finish
就可以在不打断点的情况下,跑完当前函数
(gdb) finish //在不打断点的情况下跑完当前函数
📃c 断点
这个指令就是针对断点的了,前面说过
r
无法实现两个断点间的跳转,因此有一个专门的命令
c
进行断点跳转(注:依然需要先通过
r
指令把程序跑起来)
(gdb) c //进行断点间的跳转
📖其他命令
接下来再列举一些其他命令
📃disable 断点使能
使能 的意思就是开关,比如电灯的开与关,我们的断点也能设置开关状态,在不取消断点的情况下让断点失效
(gdb) disable 断点编号 //关闭断点
能关闭当然也能打开
(gdb) enable 断点编号 //打开断点
📃set var 设置条件
给变量设置条件,使程序运行至设定值那一步,比如
set var i=5
后,程序就运行至
i=5
的那一步了
(gdb) set var 变量值 //设置变量值
这个功能就像VS中的给断点设置条件,然后跳转
📃ptype 查看变量类型
**本文只是介绍了部分常用指令,关于
gdb
还有很多很多指令,一时半会是学不完的,感兴趣的同学可以去这篇文章里看看《GDB使用详解》**
📘总结
**以上就是关于
Linux
工具:
gdb
的全部介绍了,
gdb
是一款功能丰富的调试器,它赋予了我们在纯命令行环境下调试代码的能力,虽然它的使用门槛高,但用熟后就会很顺手,配合我们之前学习过的
vim
、
gcc
,能做到像VS那样的开发环境,让我们的
Linux
使用场景更加丰富**
如果你觉得本文写的还不错的话,期待留下一个小小的赞👍,你的支持是我分享的最大动力!
如果本文有不足或错误的地方,随时欢迎指出,我会在第一时间改正
…
相关文章推荐
Linux工具学习之【git】(版本管理神器)
Linux工具学习之【gcc/g++】(实用的编译器)
Linux工具学习之【vim】(强大的编辑工具)
Linux 权限理解和学习(热榜文章,阅读量5k+)
听说Linux基础指令很多?这里都帮你总结好了
版权归原作者 Yohifo 所有, 如有侵权,请联系我们删除。