赞
踩
我们平常调试C/C++代码大多实在Windows平台下的VS中,在LInux中,我们通常使用
gdb
来调试代码,虽然我们很少在LInux上对代码进行调试,gdb在实际的使用中用的较少,但我们必须要懂它,以面对各种环境。本文目的:能够进行基本的掌握单进程程序的调试,即使用VS 2019、VS 2022的基本调试功能,都在Linux上使用gdb实现。
本文会在Linux环境下使用到vim编辑器、make/Makefile、gcc/g++,如果对这三个工具不熟悉,可点击下面的链接,结合本文一起学习。
vim编辑器
make/Makefile
gcc/g++
在学习Linux下使用gdb调试之前,我们需要掌握以下三个有关debug和release模式的铺垫知识
程序的发布方式有两种,debug模式和release模式
debug模式:该模式是程序员编写程序和调试代码的模式,该模式下生成的可执行程序含有调试信息体积要大于release模式生成的可执行程序。
release模式:没有调试信息,对程序做出优化,减小了程序的体积,更适合用户使用。该模式下生成的可执行程序是公司最终要推向市场的,由公司内测试人员测试是否完善,测试通过后推向市场。
下图是VS 2019下,两种模式的选择图,需要那种模式选择那种模式即可
那在Linux下如何进行两个模式的转换呢?
Linux下,gcc/g++出来的二进制可执行程序,默认是release模式
//常规生成
gcc -o 可执行文件名 源代码文件
g++ -o 可执行文件名 源代码文件
要使用gdb调试,必须在使用gcc/g++生成二进制程序时,加上-g
选项
gcc -o 可执行文件名 源代码文件 -g
g++ -o 可执行文件名 源代码文件 -g
下面我们在如下test.c文件下编辑测试代码,进行测试
注意: 第7行代码,在for循环内定义变量i
,这种写法是在c99中开始支持的,我使用的gcc/g++编辑器不支持这种写法,需要在执行命令后添加-std=c99
,
Makefile文件如下:
若不会使用Makefile文件,可直接使用如下两条指令测试
gcc -o MyTest-debug test.c -g -std=c99 //生成debug模式的可执行文件
gcc -o MyTest-release test.c -std=c99 //生成release模式的可执行文件
首先,测试release模式下,是否可以调试
如上图显示,红色框内,表示没有找到调试符号,无法进行调试。
其次,测试debug模式下,是否可以调试
没有显示错误信息,可以正常调试
最后: 观察两个可执行文件的体积,明显debug要大于release
我们可以使用readlef
指令查看两个可执行文件下的信息,如下:
我们可以通过该指令,查看两个文件下的debug信息,如下(grep 指令为查找字符串指令):
MyTest-debug文件下找到了debug信息,MyTest-release什么都没有。
调试器的核心工作:定位问题
接下来简绍在Linux下如何使用gdb进行调试,该段落为分步骤讲解,将gdb下的命令总结放在了下一段落。
如果大家对gdb并不属性,按步骤操作即可
我们使用如下命令来安装gdb:
sudo yum install -y gdb
使用gdb file
指令进入调试模式,如下图
- `l/list 行号`:显示文件源代码,从输入的行号起,向下列出十行。一般我们在开始调试时,从`l 1`开始查看,接着输入`l`或`Enter`键,即可获得上次查找位置往下的代码
注意: 输入gdb的指令后,Enter
键就会记录。即,输入指令后,接着输Enter键会重复上面的动作。下面的指令也遵循这个规则。
- 在刚进入gdb模式后,单独使用l
进行查看,显示的代码为随机的
- `break/b 行号`:在某一行设置断点
如下图,在19行设置断点
break/b 函数名
:在某个函数开头设置断点
如下图,在addTestTop函数处设置断点
5是addTestTop函数内第一行代码的行号。
break/b 文件名:函数名
:多文件时,可使用该方法设置断点
info break/b
:查看断点信息
当程序运行后,会在断点处停下,在次查看断点,会显示在该断点处停下的次数。
注意: 在gdb中断点的序号是增长的,每次使用后会不断增长,直到关闭在开启后,重新从1开始
r/run:运行程序
注意: 一次运行是在全部main函数内全部代码运行完后结束,中途遇到断点停下后,进行其他查看指令不会影响此次调试
s/step
:遇到函数,进入函数内部
注意: 进入其他函数后,会产生调用链,即一个函数调用另一个函数,接着再去调用其他函数。
可通过bt
指令查看
n/next
即遇到函数不进入函数,直接执行下一条指令Enter
键,执行上次执行的指令吗?如果需要调试的的内容过多,按一次s
或n
后接着按Enter
键即可delete/d breakpoints:删除所有断点
delete/d n:删除序号为n的断点
当我们不想使用一个断点,也不想删除该断点时使用
disable breakpoint 断点序号:关闭断点
enable breakpoint 断点序号:打开断点
p 变量名
:这个指令是需要查看的时候输入,不会影响调试,如下我在调试进入addTestTop函数后,执行了几段语句后,查看sum变量的结果,此时sum为6.
这样查看的效率太低,我们在VS中使用调试时,是执行一次相对应的变量随之变化,可以直接查看,该方法需要用户自己调用,不方便,我们可以使用以下的方法
display 变量名
:执行后,该变量在每执行一个语句后,都会显示出来undisplay 序号
:不想跟踪某变量时使用until 行号
:跳转至X行,在我们上面的代码中有一个循环,我们可以使用该指令跳转出循环finash
:进入一个函数后执行,只执行该函数,执行完后停下continue/c
:直接运行到下一个断点处util、finish、continue
结合后,可实现基本的调试功能q/quit
:如果正在调试,会提示是否需要退出gdb binFile
退出: ctrl + d
或 quit/q
调试命令:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。