【Linux】gdb调试器
文章目录
- 【Linux】gdb调试器
- 1、调试器的意义
- 2、gdb调试器介绍
- 2.1 gdb的作用
- 2.2 gdb的配置
- 3、gdb调试器的使用
- 3.1 常用调试命令
- 3.2 调试前准备
- 3.3 指令演示
- 3.3.1 断点
- 3.3.2 逐过程、逐语句
- 3.3.3 查询变量
- 3.3.4 跳转
- 3.3.5 结束函数、跳出执行
- 3.3.4 跳转
- 3.3.5 结束函数、跳出执行
1、调试器的意义
编写程序中出现的语法错误可以由编译器发现并纠正
如果只是出现了逻辑错误呢?我们也能借助调试器去调试程序。
所谓的调试(Debug),是让代码一步一步慢慢执行,跟踪程序的运行过程。比如,可以让程序停在某个地方,查看当前所有变量的值,或者内存中的数
据;也可以让程序一次只执行一条或者几条语句,看看程序到底执行了哪些代码。
通过调试程序,我们可以监控程序执行的每一个细节,包括变量的值、函数的调用过程、内存中数据、线程的调度等,从而发现隐藏的错误或者低效的代码。
程序的发布方式有两种,debug 模式和 release 模式 ,分别是调试版本和发布版本。
debug 模式是程序员在自主编写代码时的模式,在 debug 模式下是 含有调试信息 的;而 release 模式下是 不含调试信息 的 ,且 release 进行了各种优化,方便用户使用。
在 Linux 的 gcc/g++ 编译器下编译的代码往往都是 release 版本 。其实对于这点也很容易想通,我们平常的开发一般是在 ide 上进行,当产品发布时再到 Linux 上进行线上发布,且测试人员测的也是 release 版本的代码。
2、gdb调试器介绍
2.1 gdb的作用
Linux系统中常用的调试器就是GDB
调试器(GNU symbolic debugger)了
从名称上不难看出,它诞生于
GNU
计划(同时诞生的还有 GCC、Emacs 等),是Linux
下常用的程序调试器。至今GDB
已经迭代了诸多个版本当下的
GDB
支持调试多种编程语言编写的程序,包括C、C++、Go、Objective-C、OpenCL、Ada
等。实际场景中,GDB
更常用来调试C
和C++
程序。
借助 GDB
调试器可以实现以下几个功能:
- 程序启动时,可以按照我们自定义的要求运行程序,例如设置参数和环境变量;
- 可使被调试程序在指定代码处暂停运行,并查看当前程序的运行状态(例如当前变量的值,函数的执行结果等),即支持断点调试;
- 程序执行过程中,可以改变某个变量的值,还可以改变代码的执行顺序,从而尝试修改程序中出现的逻辑错误。
2.2 gdb的配置
我们可以通过yum
进行gdb的安装
yum -y install gdb
安装完成之后我们可以通过gdb -v
来查看当前gdb的版本
当版本信息显示出来时,也就说明了gdb的成功安装
3、gdb调试器的使用
3.1 常用调试命令
GDB
的主要功能就是监控程序的执行流程。这也就意味着,只有当源程序文件编译为可执行文件并执行时,并且该文件中必须包含必要的调试信息(比如各行代码所在的行号、包含程序中所有变量名称的列表(符号表)等),
GDB
才会派上用场。
在编译时需要使用 gcc/g++ -g
选项编译源文件,才可生成满足 GDB
要求的可执行文件
命令 | 全称 | 解释 |
---|---|---|
l | list | 显示源程序代码的内容,包括各行代码所在的行号 |
b | break | 在源代码指定的某一行设置断点,其中xxx用于指定具体打断点位置 |
r | run | 执行被调试的程序,其会自动在第一个断点处暂停执行 |
n | next | 令程序一行代码一行代码的执行 |
c | continue | 当程序在某一断点处停止后,用该指令可以继续执行,直至遇到断点或者程序结束 |
p | 打印指定变量的值,其中 xxx 指的就是某一变量名 | |
q | quit | 终止调试 |
s | step | 如果有调用函数,进入调用的函数内部;否则,和 next 命令的功能一样 |
fi | finish | 结束当前正在执行的函数,并在跳出函数后暂停程序的执行 |
j | jump | 使程序从当前要执行的代码处,直接跳转到指定位置处继续执行后续的代码 |
3.2 调试前准备
我们都知道,程序调试面对的对象是经过翻译的二进制文件,那么在我们进行调试之前需要先通过gcc
编译器来编译源文件成二进制文件
既然先前讲过了通过make,makefile
实现了自动化编译,我就不直接使用命令来使用gcc
,而是通过makefile
文件来实现自动化编译
(注:在循环内定义变量为c99标准,所以编译时需要加上 -std=c99
)
makefile
完成后,再进行make
,就生成了相应的二进制文件
gdb
启动时会默认打印一堆免责条款(如下图),通过添加 --silent
(或者 -q
、--quiet
)选项,可将这部分信息屏蔽掉。
避免问题后的界面:
3.3 指令演示
这里简单演示下一些调试命令
3.3.1 断点
打断点格式:
b
+ 行号b
+ 函数名
查看断点信息:
- **
info breakpoints/break/b
**
对应含义:
num
:断点编号,从 1 开始enb
:断点使能,y代表打开,n代表关闭what
:断点在哪个函数中,在哪个文件,第几行
删除功能:
d
+ 断点编号:删除断点(是编号不是行号)d break
:删除所有断点
断点使能:
disable b num
:关闭断点使能enable b num
:打开断点使能
关闭断点使能相当于设置空断点
断点跳跃:
continue / c
:从一个断点处,直接运行至下一个断点
3.3.2 逐过程、逐语句
-
next/n
:逐过程,一步可以走掉一个函数,相当于 vs 中的 f10一次走过了函数,函数中打印的内容也会显示出来
还会显示当前行数,以及当前行的内容
-
s
:逐语句,一次走一条代码,可进入函数,同样的库函数也会进入
3.3.3 查询变量
p
变量名/地址:暂时查询变量
display
变量名:常显示变量的数据
undisplay
编号 :取消变量的显示
3.3.4 跳转
until
行号:不打断点,执行完区间代码,指定位置跳转
3.3.5 结束函数、跳出执行
finish
:执行到当前函数返回,然后停下来等待命令
display
变量名:常显示变量的数据
undisplay
编号 :取消变量的显示
3.3.4 跳转
until
行号:不打断点,执行完区间代码,指定位置跳转
3.3.5 结束函数、跳出执行
finish
:执行到当前函数返回,然后停下来等待命令