前言: gdb是linux的调试器,gdb一般用的少,大部分人还是喜欢在vs上调试,但是像做嵌入式的,就必须掌握gdb了。
1. gdb 调试的程序
gdb可以调试任何程序吗?当然不是,gdb可以调试的程序必须要有可调试信息。程序的发行有两个版本分别是realse版本,debug版本。Linux下,默认生成的可执行是realse版本(优化的版本),如果想要编译形成的程序为debug版本,必须加上-g
。
gcc 文件 -g
2.gdb调试具体实例
同一个程序,我们在vs下调试以及在gdb下调试,对比着学习:
这是一个累加程序,太简单了,不写注释了、
#include<stdio.h>
int accumulate(int n)
{
int ret = 0;
int i=0;
for (i = 1; i <= n; i++)
{
ret += i;
}
return ret;
}
int main()
{
int x = 0;
scanf("%d", &x);
int ret = accumulate(x);
printf("%d\n", ret);
return 0;
}
可以看到在Linux中,我编译了ww.c的可执行程序ww,并且它是debug版本的
(1)进入vs和gdb和调试
vs:按F5开始调试 (也需断点)/F10,F11也可进入调试
gdb:run/r开始调试,必须有断点,无断点的话,就相当于直接运行不调试
gdb ww
在gdb下调试,先输入list +行号,可以列出代码行号,list+函数名 会直接列出函数
(2)设置一个断点,运行到断点处
vs下是F9打断点,F5运行到断点处
gdb是,break+行号打断点,或者是b+行号;continue运行到断点出,或者是简写c。和vs保持一致,在15行打断点。
info break 查看断点:
(3)运行到断点处,
vs按F5,
gdb输入run,让程序运行起来,直接运行到这个断点处,如果还有断点,那么再输入c运行到下一个断点。
(4)继续往下调试
gdb是按n或next,这类似于vs的F10,逐过程的运行,如果要进入函数需要输入s或step。
现在输入n,由于scanf,所以输入100(随便输入一个数,这是x的值),如果想要进入accumulate函数直接输入s。
可以看到现在进入了accumulate函数,行号为4。
vs就比较简单了,完成上面的操作只需要按F11就好了。同样黄箭头也来到第四行。
(5)查看accumulate函数中ret的值。
vs下打开监视窗口即可
gdb可以选择每次停下来都看ret的值,也可以只看一次,下次停下来就不会跟踪查看;
- display +变量名 :跟踪查看
- undisplay +标号:取消查看
- p+变量名:查看一次
取消查看:
查看一次:
画红圈的是标号,undisplay+标号可以具体的取消查看某个变量
(5)令断点失效,但是不消失
vs下就是禁用断点
gdb用的是disable+标号,具体禁用某个断点
Enb就代表的是断点是否启用,前面的Num是标号。
(6)删除断点
delete+标号就可以删除断点。
3.gdb的常用指令
list/l 行号:显示binFile源代码,接着上次的位置往下列,每次列10行。
list/l 函数名:列出某个函数的源代码。
r或run:运行程序。
n 或 next:单条执行。
s或step:进入函数调用
break(b) 行号:在某一行设置断点
break 函数名:在某个函数开头设置断点
info break :查看断点信息。
finish:执行到当前函数返回,然后挺下来等待命令
print§:打印表达式的值,通过表达式可以修改变量的值或者调用函数
p 变量:打印变量值。
set var:修改变量的值
continue(或c):从当前位置开始连续而非单步执行程序
run(或r):从开始连续而非单步执行程序
delete breakpoints:删除所有断点
delete breakpoints n:删除序号为n的断点
disable breakpoints:禁用断点
enable breakpoints:启用断点
info(或i) breakpoints:参看当前设置了哪些断点
display 变量名:跟踪查看一个变量,每次停下来都显示它的值
undisplay:取消对先前设置的那些变量的跟踪
until X行号:跳至X行
breaktrace(或bt):查看各级函数调用及参数
info(i) locals:查看当前栈帧局部变量的值
quit:退出gdb
结尾语: gdb调试器,你学费了嘛?掌握上文所讲基本上就可以调试程序了,在vs下最长用的调试在上面都有讲。