一下面的代码为例介绍一下linux中,gdb调试的基本指令
创建一个文件myfile.c,文件代码内容如下
1 #include <stdio.h>
2
3 int Add(int x, int y)
4 {
5
6 return x+y;
7 }
8
9 int main()
10 {
11 int a = 10;
12 int b = 20;
13
14 int ret = Add(a, b);
15 printf("%d\n", ret);
16
17 return 0;
18 }
gcc myfile.c编译过后的文件是不支持调试的(release版本)
所以
我们要带上-g选项 gcc -g myfile.c 让gcc以debug的方式编译程序
此时成功了!
l (行号/函数名):显示源代码
默认每次列10行
r (run) :运行程序(开始调试)
因为我们还没有为这段代码设置断点,所以在我们开始调试的时候程序就直接结束并输出结果了。
b(break) 行号/函数:在某一行/函数处设置断点
下面我们在11行设置一个断点:
- Breakpoint 1表示这个断点的序号为1号,后面的是地址(不用管)
- file mytest.c表示在哪个文件当中
- line 11表示的是代码中的行号
此时我们再 r 一下,程序就会停在11行处:
c(continue) :跳到下一个断点处
我们在14行处再设置一个断点,然后利用c直接的跳到第二个断点处
n(next) 逐过程 :(不进入函数体内部)
注意,调试结束的时候,断点是不会自动删除的,我们再次按下r,还是会跳到第一个断点处
d(delete breakpoints) 断点的序号 :删除断点
d不加断点序号时,是删除所有的断点,加上序号,只删除改序号的断点
info b :查看断点信息
其中Enb这一列表示的是,该断点是否是被启用,y表示启用,n表示禁用,在某些场景下,我们希望某个断点失去它的作用(忽略该断点的存在),但希望留下它的位置,就可以使该断点禁用,但不删除它。
现在我们来删除第二个断点:
s(step) :逐语句(进入函数体内部)
p :显示变量
但是这个显示并不会一直保留在屏幕上,如下:
当我们再执行n的时候,a b ret的值就会不再显示,如果想要一直显示,就需要用到下面一个命令
diplay :常显示
左边的序号作用和断点的序号一样,在我们需要取消常显示的时候,就要根据序号来取消,而不是名称
undisplay :取消常显示
接下来介绍几个比较特殊的命令
finish :执行到当前函数返回, 然后停下来
我们进入Add函数之后,输入finish,就会执行完这个函数,不论函数有多长,都会执行完,然后停在返回处。
最后一行的Value returned is $7 = 30表示的是返回的有效值是30。
我们看到此时的ret还没有被赋值,是随机值
完成赋值!
disable breakpoints :禁用断点
enable breakpoints :启用断点
我们再在15行设置一个断点,但是禁用该断点
此时我们进行c,调试就会直接结束,而不会停在15行!
我们开启15断点的启用
就会停在15行的断点处
info locals :查看当前栈帧的局部变量的值
有了这个,我们就可以直接查看当前所有的局部变量的值
但是不会常显示。
bt(breatracek) :查看各级函数调用和参数(各个函数调用之前的关系)
我们进入Add函数之后,输入bt:
until 行号:直接跳到某一行
最后就是q(quit) :退出调试
当我们的调试还没结束的时候,它会提示我们是否确认要退出,输入y是,n不。
当我们一次调试结束的时候,再退出调试,就不会询问我们了:
本文章介绍的仅仅是一些基本的gdb使用命令,并没有包含全部!