GDB(GNU调试器)是一个功能强大的调试工具,提供了很多命令用于调试程序。下面我们来看一下如何使用gdb调试。
我们要知道我们的程序有两种,一种是release 还有一种是 debug 版本的,我们的调试只有咋 debug 版本下才可以调试,我们只需要在编译的时候在后面加 -g 选项就是添加调试信息,也就是debug 版本。
下面我们就来看一下我们的 gdb 的指令
测试程序:
#include<stdio.h>
int addToToop(int top)
{
int ret = 0;
for(int i = 1; i <= top; ++i)
ret += i;
return ret;
}
int main()
{
printf("开始调试\n");
int sum = 20;
int ret = addToToop(sum);
printf("%d\n", ret);
printf("结束调试\n");
return 0;
}
指令:gdb + 可执行程序文件名
如果变成上面这样那么就以及成功了
指令:quit / q
(gdb) quit
[lxy@hecs-165234 test9]$
(gdb) q
[lxy@hecs-165234 test9]$
指令:list / l (后面也可以加 数字 表示查看该行和上下行的部分代码)
(gdb) l
10
11 return ret;
12 }
13
14
15
16
17 int main()
18 {
19 printf("开始调试\n");
(gdb) l 0
1 #include<stdio.h>
2
3
4
5 int addToToop(int top)
6 {
7 int ret = 0;
8 for(int i = 1; i <= top; ++i)
9 ret += i;
10
(gdb)
gdb 会记住上一次的指令,所以我们在查看的时候我们可以 l 0 然后之一回车
指令: l + 函数名(显示函数代码)
(gdb) l addToToop
1 #include<stdio.h>
2
3
4
5 int addToToop(int top)
6 {
7 int ret = 0;
8 for(int i = 1; i <= top; ++i)
9 ret += i;
10
(gdb)
11 return ret;
12 }
13
14
15
16
17 int main()
18 {
19 printf("开始调试\n");
20 int sum = 20;
(gdb)
指令:run / r
(gdb) r
Starting program: /home/lxy/test/test9/test_debug
开始调试
210
结束调试
[Inferior 1 (process 7520) exited normally]
Missing separate debuginfos, use: debuginfo-install glibc-2.17-326.el7_9.x86_
(gdb)
指令:break / b 后面 + 行号
(gdb) break 21
Breakpoint 1 at 0x4005c4: file test.c, line 21.
(gdb) b 22
Breakpoint 2 at 0x4005d1: file test.c, line 22.
(gdb)
指令:info breakpoints / info b / i b
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000004005c4 in main at test.c:21
2 breakpoint keep y 0x00000000004005d1 in main at test.c:22
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000004005c4 in main at test.c:21
2 breakpoint keep y 0x00000000004005d1 in main at test.c:22
(gdb) i b
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000004005c4 in main at test.c:21
2 breakpoint keep y 0x00000000004005d1 in main at test.c:22
(gdb)
断点信息查看介绍:
指令:delete / d + 断点编号
(gdb) i b
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000004005c4 in main at test.c:21
2 breakpoint keep y 0x00000000004005d1 in main at test.c:22
(gdb) delete 1
(gdb) i b
Num Type Disp Enb Address What
2 breakpoint keep y 0x00000000004005d1 in main at test.c:22
(gdb) d 2
(gdb) i b
No breakpoints or watchpoints.
(gdb)
指令:next / n
我们先将断点打到 20 行的位置,然后我们开始逐语句调试
(gdb) b 20
Breakpoint 3 at 0x4005bd: file test.c, line 20.
(gdb) r
Starting program: /home/lxy/test/test9/test_debug
开始调试Breakpoint 3, main () at test.c:20
20 int sum = 20;
(gdb) n
21 int ret = addToToop(sum);
(gdb) n
22 printf("%d\n", ret);
(gdb) n
210
23 printf("结束调试\n");
(gdb) n
结束调试
24 return 0;
(gdb) n
25 }
(gdb) n
0x00007ffff7a2f555 in __libc_start_main () from /lib/libc.so.6
(gdb) n
指令:step / s
我们还是在 20 行的位置打断点,然后我们逐语句调试,我们会进入到函数里面
(gdb) r
Starting program: /home/lxy/test/test9/test_debug
开始调试Breakpoint 3, main () at test.c:20
20 int sum = 20;
(gdb) s
21 int ret = addToToop(sum);
(gdb) s
addToToop (top=20) at test.c:7
7 int ret = 0;
(gdb) s
8 for(int i = 1; i <= top; ++i)
(gdb) s
9 ret += i;
(gdb)
指令:print / p + 变量名
Starting program: /home/lxy/test/test9/test_debug
开始调试Breakpoint 3, main () at test.c:20
20 int sum = 20;
(gdb) print sum
$4 = 0
(gdb) n
21 int ret = addToToop(sum);
(gdb) print sum
$5 = 20
(gdb) p sum
$6 = 20
(gdb)
指令:display + 变量名
我们将断点打到 21 行(函数所在行),然后我们 s 进入函数, 我们 display 查看变量 i
Starting program: /home/lxy/test/test9/test_debug
开始调试Breakpoint 4, main () at test.c:21
21 int ret = addToToop(sum);
(gdb) s
addToToop (top=20) at test.c:7
7 int ret = 0;
(gdb) n
8 for(int i = 1; i <= top; ++i)
(gdb) display i
1: i = 41972
(gdb) n
9 ret += i;
1: i = 1
(gdb) n
8 for(int i = 1; i <= top; ++i)
1: i = 1
(gdb) n
9 ret += i;
1: i = 2
(gdb)
我们的常显示变量的前面还有一个数字,这个就是常显示变量的 编号
指令:undisplay + 常显示变量的编号
还是根据上面的 显示 i 变量,然后我们取消显示 i 变量
1: i = 2
(gdb) undisplay 1
(gdb)
这次我们在进入到 函数中去 然后我们使用指令到指定行
指令:until + 行号
开始调试
Breakpoint 4, main () at test.c:21
21 int ret = addToToop(sum);
(gdb) s
addToToop (top=20) at test.c:7
7 int ret = 0;
(gdb) s
8 for(int i = 1; i <= top; ++i)
(gdb) until 11
addToToop (top=20) at test.c:11
11 return ret;
(gdb)
我们继续到 该函数中去
指令:finish(执行完当前函数剩余的所有代码,并且在下一个函数执行前一行停止)
(gdb) run
Starting program: /home/lxy/test/test9/test_debug
开始调试Breakpoint 4, main () at test.c:21
21 int ret = addToToop(sum);
(gdb) s
addToToop (top=20) at test.c:7
7 int ret = 0;
(gdb) s
8 for(int i = 1; i <= top; ++i)
(gdb) finish
Run till exit from #0 addToToop (top=20) at test.c:8
0x00000000004005ce in main () at test.c:21
21 int ret = addToToop(sum);
Value returned is $8 = 210
(gdb)
我们多打几个断点 20 21 22 ,然后我们 continue
指令:continue
(gdb) i b
Num Type Disp Enb Address What
4 breakpoint keep y 0x00000000004005c4 in main at test.c:21
breakpoint already hit 1 time
(gdb) b 20
Breakpoint 5 at 0x4005bd: file test.c, line 20.
(gdb) b 22
Breakpoint 6 at 0x4005d1: file test.c, line 22.
(gdb) i b
Num Type Disp Enb Address What
4 breakpoint keep y 0x00000000004005c4 in main at test.c:21
breakpoint already hit 1 time
5 breakpoint keep y 0x00000000004005bd in main at test.c:20
6 breakpoint keep y 0x00000000004005d1 in main at test.c:22断点打好了
(gdb) run
Starting program: /home/lxy/test/test9/test_debug
开始调试Breakpoint 5, main () at test.c:20
20 int sum = 20;
(gdb) continue
Continuing.Breakpoint 4, main () at test.c:21
21 int ret = addToToop(sum);
(gdb) continue
Continuing.Breakpoint 6, main () at test.c:22
22 printf("%d\n", ret);
(gdb) continue
Continuing.
210
结束调试
[Inferior 1 (process 7634) exited normally]
(gdb)
指令:disable + 断点编号
我们现在有 20 21 22 三个断点,我们现在关闭掉 21 我们 i b 查看一下
(gdb) i b
Num Type Disp Enb Address What
4 breakpoint keep y 0x00000000004005c4 in main at test.c:21
breakpoint already hit 1 time
5 breakpoint keep y 0x00000000004005bd in main at test.c:20
breakpoint already hit 1 time
6 breakpoint keep y 0x00000000004005d1 in main at test.c:22
breakpoint already hit 1 time
(gdb) disable 4
(gdb) i b
Num Type Disp Enb Address What
4 breakpoint keep n 0x00000000004005c4 in main at test.c:21
breakpoint already hit 1 time
5 breakpoint keep y 0x00000000004005bd in main at test.c:20
breakpoint already hit 1 time
6 breakpoint keep y 0x00000000004005d1 in main at test.c:22
breakpoint already hit 1 time
(gdb)
指令:enable + 断点编号
(gdb) i b
Num Type Disp Enb Address What
4 breakpoint keep n 0x00000000004005c4 in main at test.c:21
breakpoint already hit 1 time
5 breakpoint keep y 0x00000000004005bd in main at test.c:20
breakpoint already hit 1 time
6 breakpoint keep y 0x00000000004005d1 in main at test.c:22
breakpoint already hit 1 time
(gdb) enable 4
(gdb) i b
Num Type Disp Enb Address What
4 breakpoint keep y 0x00000000004005c4 in main at test.c:21
breakpoint already hit 1 time
5 breakpoint keep y 0x00000000004005bd in main at test.c:20
breakpoint already hit 1 time
6 breakpoint keep y 0x00000000004005d1 in main at test.c:22
breakpoint already hit 1 time
(gdb)
指令:break / b + 文件名 + :+ 行号
这里就不做演示了....(没有多个文件)
指令:info locals / i locals
我们打断点到 22 行,然后我们查看主函数里面的变量
(gdb) run
Starting program: /home/lxy/test/test9/test_debug
开始调试Breakpoint 7, main () at test.c:22
22 printf("%d\n", ret);
(gdb) info locals
sum = 20
ret = 210
(gdb) i locals
sum = 20
ret = 210
(gdb)
指令:set var + (变量名 = 值)
我们到 21 行里面的函数里面,然后直接修改i的值为200,然后查看 i 的值
(gdb) run
Starting program: /home/lxy/test/test9/test_debug
开始调试Breakpoint 8, main () at test.c:21
21 int ret = addToToop(sum);
(gdb) s
addToToop (top=20) at test.c:7
7 int ret = 0;
(gdb) s
8 for(int i = 1; i <= top; ++i)
(gdb) p i
$13 = 41972
(gdb) set var i = 200
(gdb) p i
$14 = 200
(gdb)
指令:bt
我们先到 mian 函数里面查看调用堆栈,然后在进入到我们自己写的函数的里面继续查看调用堆栈,然后我们在 finish 结束掉我们自己的函数,然后查看调用堆栈
(gdb) run
Starting program: /home/lxy/test/test9/test_debugBreakpoint 9, main () at test.c:19
19 printf("开始调试\n");
(gdb) bt
#0 main () at test.c:19
(gdb) s
开始调试
20 int sum = 20;
(gdb) s
21 int ret = addToToop(sum);
(gdb) s
addToToop (top=20) at test.c:7
7 int ret = 0;
(gdb) s
8 for(int i = 1; i <= top; ++i)
(gdb) bt
#0 addToToop (top=20) at test.c:8
#1 0x00000000004005ce in main () at test.c:21
(gdb) s
9 ret += i;
(gdb) finish
Run till exit from #0 addToToop (top=20) at test.c:9
0x00000000004005ce in main () at test.c:21
21 int ret = addToToop(sum);
Value returned is $15 = 210
(gdb) bt
#0 0x00000000004005ce in main () at test.c:21
(gdb)
上面的就是 gdb 里面常用的命令,我们下期见~
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- bangwoyixia.com 版权所有 湘ICP备2023022004号-2
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务