前言
一般情况下,Linux系统中对所写代码调试工具基本都是gdb
Linux中gdb的安装:
yum install gdb
而代码的调试只能在debug模式下调试,不能在release模式下调试
gcc/g++默认使release模式
因此在编译c/c++代码的时候需要在gcc后面加上 -g 使之编译成为debug模式
gcc -0 test.c -g
makefile 写法:
在Linux 中形成的可执行程序的格式为ELF格式
使用readelf 即可查看elf格式的文件内容
gdb的使用
在使用gdb调试代码的时候先要进入gdb模式
进入和退出
gdb的调试一定调试的是可执行程序,开始调试即: gdb + 可执行程序
r 表示开始调试
r
结束调试直接: quit
list/l
list 命令 可以简写为 l 命令
此命令使用来查看需要调试代码的源码的
l 0 即从第0行开始查看,因为每次只显示部分代码,因此在第一次l之后继续按回车键即可继续显示
l + 函数名: 直接显示函数内内容:
l main
回车
直接回显示main函数附近的内容
断点
打断点:
打断点的指令是 b
例如,在第10行打上断点:
b 10
当有多个源文件的时候,在 b 后可带上文件名和 : 再打断点,
例如,我有两个文件stack.c 和 main.c,我要在stack.c文件的第20行打断点:
b stack.c:20
根据函数名打断点:
例如,我要在main函数处打断点:
b main
在stack.c文件的 push_back函数处打断点:
b stack:push_back
查看断点:
info b
此操作会显示出断点的信息,包括断点序号,断点所在文件和行号等
删除断点
因为每个添加的断点都有一个序号,因此删除断点只有用 d 加 断点序号的方式
例如,我现在有以下断点 :
我想要删除3号断点:
d 3
可见:在一个gdb的调试周期中删除断点并不会使断点的序号发生变化
只有quit会清除断点
断点的关闭和开启
在断点信息中的 Enb 就表示断点状态 y表示开启 n 表示关闭
关闭断点 : disable + 序号
例如,我想要关闭2号断点:
disable 2
此时2号断点已经关闭,在调试的时候就不会在2号断点处执行
要开启断点则使用 enable + 序号
enable 2
此时断点已经重新开启
断点逐步调试
逐过程(一个函数一个函数的): n
逐语句(一行一行的)😒
查看具体参数
当调试进行到某个程度的时候,此时我们想查看某个参数的值,可以使用 p 命令 然后回车
例如:
查看a的值:
p a
然后回车
此时可以看到a 的值为10;
查看c的地址:
p &c
然后回车:
但是每次查看都要输入的话太麻烦了,因此可以使用常显示某些值:
display 加 参数
例如,我想在每执行一步都要看到a和c的变化
display a
回车继续:
display c
这样的话每调试一步就会显示我们需要查看的信息
而常显示的每个信息前面都有一个序号,这就是给删除这个信息做准备的
例如,我想在常显示中删掉c的显示:
undisplay 2
这样的话再执行一步常显示的内容就只是剩下a啦
调式到指定行数
until + 行号
跳转到指定位置
finish :运行到当前函数的结尾
c:从一个断点跳转到下一个断点处
查看堆栈
bt:查看栈内信息
基本的gdb调试也就这些了,不得不说可视化界面真的是人类的一个伟大发明…