🌠 作者:@阿亮joy.
🎆专栏:《学会Linux》
🎇 座右铭:每个优秀的人都有一段沉默的时光,那段时光是付出了很多努力却得不到结果的日子,我们把它叫做扎根
目录
- 👉什么是gdb👈
- 👉gdb的使用👈
- 查看代码
- 设置断点
- 查看断点
- 删除断点
- 执行当前被调试的程序
- 逐过程调试代码
- 逐语句调试代码
- 跳转到下一个断点
- 查看函数调用堆栈
- 将函数直接执行完(重点)
- 查看变量的值和地址
- 跳转至某一行
- 设置变量的值
- 查看当前栈帧局部变量的值
- 使能断点
- 👉总结👈
👉什么是gdb👈
在实际开发过程汇总,C / C++ 的代码除了符合最基本的语法规范之外,还必须符合设计者的逻辑意图,如果发现生成的可执行程序的运行结果不对,则可以通过相应的调试环境来跟踪调试,Linux 提供了一个称为 gdb 的调试程序,其是 GNU 开发并发布的 UNIX / Linux 下的程序调试工具,能在运行时观察程序的内部结构和内存的使用情况,主要提供以下一些功能:
- 监视程序中变量的值
- 设置断点以使程序在指定的代买行上停止执行
- 一行一行地执行代码
gdb 是一个功能强大的调试器,其支持的调试命令十分丰富,可以实现不同的功能。这些命令包括从简单的问价装入到允许检查所调用的堆栈内容的复杂命令。
那我想问:gdb 调试器的使用和 在 Visual Studio 上的调试有什么区别呢?其实在调试思路上,没有什么区别;而在调试的操作方法上肯定是有所区别的,Visual Studio 上的调试是通过图形化界面加快捷键来实现的,而 gdb 的调试是纯命令行的。
👉gdb的使用👈
为了介绍 gdb 常用的命令,我们写一份 0 到 100 之和的代码且故意将其写错。
time 函数返回当前时间的时间戳
写好 Makefile,然后开始编译并运行我们的代码。
可以看到,运行结果并不是我们想要的。所以我们需要借助调试器 gdb 来帮我们找出错误。
sudo yum install -y gdb #安装gdb
通过上图可以看到,我们的程序里没有调试信息。因为在 Linux 中,用 gcc / g++ 生成的可执行程序默认是 release 版本的,而 release 版本是没有调试信息的,只有 debug 版本才会有调试信息。那么,我们就需要让 gcc 生成 debug 版本的可执行程序,而我们只需要修改 Makefile 就行了。
注:"-g"选项在可执行程序中加入调试信息,方便进行程序的调试。
为什么软件有 debug 版本和 release 版本呢?debug 版本的软件是让程序员进行调试的,程序员调试完成后才会有 release 版本的软件。release 版本的软件是给用户使用的,该软件不需要加入任何的调试信息,因为用户根本就不会关系这些,用户只关注软件怎么用和好不好用。因为 debug 版本中带有调试信息,所以 debug 版本的软件体积一定是大于 release 版本的。
补充知识:可执行程序是 elf 格式的,我们可以使用 readelf 来查看可执行程序的相关信息。
readelf -S 可执行程序 #查看可执行程序的相关信息
如果用 readelf 工具来查看 debug 版本和 release 版本的软件,我们会发现 debug 版本的软件多了一些调试信息。
注:要用 gdb 调试代码,首先要进行给编译器 gcc 添加 “-g” 选项标识以 debug 的版本进行发布。
查看代码
gdb 可执行程序名 #进入调试
l #显示代码
l 0 #从第一行开始显示代码
list 0 #从第一行开始显示代码
q #退出调试
注:输入l 0
命令显示代码时,不需要再次输入命令,可以直接摁下回车键,就可以显示剩下的代码。因为 gdb 会记住曾经的命令。
设置断点
b 行号 #在该行设置断点
break 行号 #在该行设置断点
查看断点
info b #查看断点
info break #查看断点
删除断点
d 断点编号 #删除该断点
执行当前被调试的程序
r / run #执行当前被调试的程序
逐过程调试代码
n / next #逐过程调试代码(执行一行源代码但不进入函数内部)
逐语句调试代码
s / step #逐语句调试代码(执行一行源代码且进入函数内部)
跳转到下一个断点
为了演示这个指令,我们在原来的代码中增加一些代码。
c / continue #跳转到下一个断点
查看函数调用堆栈
将函数直接执行完(重点)
finish #将整个函数直接执行完,不是逐语句也不是逐过程地执行
注:该命令比较重要,如果将该函数直接跑完且返回结果有误,则错误出现在该函数内。这样,我们就可以快速地将错误定位到该函数了。
查看变量的值和地址
p 变量名 #查看变量的值
p &变量名 #查看变量的地址
display 变量名 #将变量加入显示窗口中
undisplag 编号 #将变量移出显示窗口
跳转至某一行
until 行号 #跳转至指定行
注:如果指定行没有有效的代码,其会跳转到下一句有效代码处。
设置变量的值
set var 变量名=数字 #将变量的值设置为指定值
注:将变量的值设置为指定值后,代码的运行结果可能会不正确。
查看当前栈帧局部变量的值
info locals #查看当前函数栈帧的局部变量的值
使能断点
disable breakpoints 断点编号 #使该断点失效
enable 断点编号 #使该断点生效
👉总结👈
本篇博客主要讲解了什么是 gbd以及 gdb 的常见命令。那么以上就是本篇博客的全部内容了,如果大家觉得有收获的话,可以点个三连支持一下!谢谢大家!💖💝❣️