目录
前言:
一、debug模式与release模式的区别
1、区别
2、证明
二、gdb调试工具的使用
1、启动gdb
2、运行代码
3、gdb命令的使用
1、查看代码
2、 打断点
3、查看断点
4、删除断点
5、关闭断点
6、打开断点
7、逐过程调试
8、逐语句调试
9、单次查看变量值和变量地址
10、删除常显示变量
11、区域运行
12、改变变量的值
总结
前言:
程序的发布方式有两种,debug和release模式,这两种模式中debug模式是可供我们调试代码的,release模式一般是来测试代码的
我们经常用的vs编译器,通常情况下我们都是在debug模式下写代码的,这也方便我们随时可以调试我们的代码,找到bug
在我们下面使用gdb调试代码的时候,我们与vs调试功能做对比来讲解
一、debug模式与release模式的区别
1、区别
为什么debug模式下可以调试,而release模式下不行
因为在debug模式下编译器在生成可执行程序时,会给可执行程序添加调试信息
口说无凭,如何证明
2、证明
我们已经知道,debug模式的文件会有额外的调试信息,如果我们能证明debug模式下的文件比release模式下的文件体积要大,那就证明debug模式下确实会新增调试信息
Linux gcc/g++出来的二进制程序,默认是release模式,要使用gdb调试,必须在源代码生成二进制程序的时候, 加上 -g 选项
我们在Linux环境下创建myprocess.c文件,写下一些简单代码
我们先编译生成relase模式下的可执行程序,命名为myprocess,再生成debug模式下的可执行程序,命名为myprocess_g
对比我们可以发现,我们想得没错,debug模式下确实生成了一些东西
那这些东西是不是调试信息呢?还有待验证
我们读取一下debug模式下生成的可执行程序
命令:readelf -S myprocess_g
我们会读取出来可执行程序里面的信息
其中有这么几行内容,代表着是debug模式生成的调试信息
我们读取一下在release模式下生成的可执行文件有没有这些调试信息:
我们可以看到release中是没有的
二、gdb调试工具的使用
1、启动gdb
注意启动时,文件必须是在debug模式下生成的可执行文件
命令:gdb <可执行文件名>
如果没有该命令,那么请
sudo yum install gdb
启动成功:
2、运行代码
输入命令 run 简写为r
没有断点的情况下run会直接运行完成输出结果
3、gdb命令的使用
1、查看代码
在vs中我们调试时也是可以看到代码的
在gdb想要看到代码需要输入命令:list 可简写为 l
直接l默认从中间看起,也就是十行的中间,我们可以 list + 行号 表示从第几行开始看起
每次查看代码默认只能查看十行,所以我们继续输入命令l才能再看十行
但gdb可以默认记忆最近的一次命令,我们可以直接按回车继续查看
list+函数名,查看该函数的上下文
2、 打断点
命令:Breakpoint + 行号 简写为 b+行号
注意:每次只能打一个
这时候我们run就会直接在10行停下来,不会直接运行完成
再run一下,直接到下一个断点
3、查看断点
对比vs,我们在vs中打完断点我们可以看到到红色的标志点
我们可以使用命令:info b 查看断点 简写为 i b
字母表示含义:
- Num:表示断点号,删除断点时需要用到
- Type:表示断点
- Enb:使能,表示该断点是否被打开,y是打开,n是关闭
- Address:断点所在位置的地址
- What:断点所在位置
4、删除断点
我们可以使用命令 delete + Num删除断点,简写为d+Num
最后查看断点已经删完了
5、关闭断点
在vs中我们不想用该断点时可以暂时将他禁用
我们gdb中也有这个操作
使用命令:disable+Num 这里不能简写了 因为delete已经简写成d了
我们可以看到,它的使能已经变成了n,表示不可使用该断点
6、打开断点
同样,我们可以使用命令:enable+Num打开断点
使能变成了y
7、逐过程调试
逐过程会跳过函数
使用命令next 简写为n
我们先r启动,再n逐过程调试,我们发现,它到函数这里时,并没有进去,而是直接执行完跳过,与vs逐过程相同
8、逐语句调试
逐语句会进入函数
我们可以使用命令step,简写s
r启动后s逐语句调试,确实进入了函数
当我们进入函数,进入一个很长的循环时,我们总不能一直手动,效率太慢,我们可以用
命令:finish:直接运行完所在函数
我们也可以跳出循环,不跳出函数,跳到循环结束的那一行
使用命令:until + 行数 跳转到某一行,中间代码都会执行
我们可以看到,这里并没有跳出循环,而是到了函数内部的一行
我们虽然输的是11行,但是跳到了13行,因为12行是空格,自动跳过到了13行
9、单次查看变量值和变量地址
我们在逐语句调试时,我们进入了一个for循环,我们想知道某时某个变量的值应该怎么看呢?
查看变量的值
可以使用命令:print+变量名 简写 p+变量名
查看变量的地址
可以使用命令:print+&变量名 简写 p+&变量名
10、常显示变量值和地址
在vs中我们可以打开监视窗口,去观察我们想要观察的值
gdb中使用命令:display+变量值/&变量
添加变量
再逐语句调试:
这时候就自动显示出来我们想要查看的变量了
10、删除常显示变量
如果有些变量我们不想看了,我们想要删除,应该怎么做
使用命令:undisplay+Num(常变量前的编号)
删除成功
11、区域运行
我们在调试时为了提高效率,找bug我们通常会在一块区域上下打上断点,再去调试,就会很快发现问题,那在gdb中如何从一个断点直接到下一个断点呢?
使用命令:continue 简写c
我们再打上两个断点
运行之后自动跳到17行,再continue跳到19行
12、改变变量的值
使用命令:set var+变量=设定值
i=100后循环跳出,但是最后打印结果并不是5050,因为这个不会执行中间代码
总结
gdb调试工具只是帮助我们找到bug所在,真正要去解决bug的还是我们