💭 前言
本章我们将带着大家高雅的学一学令众多习惯图形化页面的朋友难受的 gdb 调试,这部分知识可以选择性学习学习,以后倘若遇到一些问题时能在 Linux 内简单调试,还是很香的。然后在讲讲 gcc 和 g++,系统讲解程序运行时的各个过程。
GDB 调试
调试前的准备
我们先来创建一个用来演示 GCD 调试功能的目录:
既然要调试,我们就必须要有个代码,我们这里写一个数字累加的代码:
运行结果:
结果是5050,没有问题。如果我们代码出现了一些问题需要我们调试,我们就可以使用 gdb。
如果此时你出现了报错,说什么不支持 for 循环里面定义变量,你可以输入:
$ gcc hello.c -o hello -std=c99
Linux 默认集成环境
在你当前的代码目录下直接执行 gcb + 形成的可执行程序:
$ gdb [可执行程序]
我们需要安装一下:
yum install gdb //切换到root
回到刚才的位置,再输入:gdb hello
此时就进入了 gdb 的调试命令行中:
(如果想退出,直接按 quit 就可以退出了)
gcb 读取我们的 hello 程序时出现了 "没有调试符号被发现" 的警告。
这是什么意思呢?
我们的 gdb 中有一条命令叫做 list(简写成 l),但是我们输入后出现以下提示:
因为 —— 默认形成的可执行程序无法调试!!!
相信大家都知道,C语言的发布方式有两种,一种是 debug 一种是 release。
我们在 VS 里面可以直接调的原因是,VS2019 的默认集成环境是 debug。
而在我们的 Linux 中的默认集成环境是 release,换言之,
在我们 Linux 中如果你想发布一个程序,可以直接发布,无需加任何选项。
但是如果你想调试,以 debug 形式发布,那么你就需要在编译时在后面添加一个 -g 选项:
$ gcc hello.c -o hello.g -g
总结:Linux 默认形成的可执行程序是动态链接且是 release 方式发布。
- 如果想静态链接,加 -static
- 如果想动态链接,加 -g
readelf 读取 ELF 文件信息
release 和 debug 的区别:你的可执行程序里本来就有调试信息, 只是 debug 中才有。
首先,这两个版本也都是可以运行的:
并且我要告诉你的是:debug 版本比 release 版本多几千个字节,这是什么?
毫无疑问,这些就是一个可执行程序的调试信息,它在 debug 版本中有所显现。
如果你想看调试信息,你可以输入:
$ readelf -S [可执行程序] # 以段的形式读取可执行程序,用于显示读取ELF文件中信息
我们再来读一读 debug 版的:
因为 debug 版本是能给你的可执行程序添加调试信息的,所以体积自然比 release 版本要大些。
所以我们调试的得是 debug 版本的可执行程序,预备工作全部做好,下面我们来正式学习 gdb。
显示代码 gcb(list)
现在我们是 debug 版本了,我们也顺理成章地能够使用前面我们说的 list 了。
(gdb) list [n] # 显示代码,可带行号
(gdb) list [function] # 显示带某函数的代码块
(gdb) list [begin, end] # 显示区间内的代码
...
我们输入:gdb hello.g ,然后演示