引言
在追寻光的路上不断前行,详细介绍Linux下gdb/cgdb的使用。
一、准备
• 程序的发布方式有两种,默认是 debug 模式和 release 模式。Linux gcc/g++编译出来的二进制程序默认是release模式
• 要使用gdb调试,必须在源代码生成⼆进制程序的时候加上-g 选项,如果没有添加,程序无法被 编译
二、调试
1.进入调试界面
进入调试命令:gdb/cgdb 可执行文件
例如:
[zhangsan@hcss-ecs-f571 learn_25_9_12]$ cgdb code5x int Sum(int s, int e)6x {7x int result = 0;8x int i = 0;9x for(i = s; i <= e; i++)
10x {
11x result += i;
12x }
13x return result*flag;
14x }
15x
16x int main()
17x {
18t> int start = 1;
19x int end = 100;
20x printf("I will begin\n");
21x int n = Sum(start, end);
22x printf("running done, result is: [%d-%d]=%d\n", start, end, n);
23x return 0;
24x }
? [?1034h[?1034hGNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-120.el7
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/zhangsan/learn_25_9_12/code...done.
(gdb)
Temporary breakpoint 1 at 0x4005c3: file code.c, line 18.
(gdb)
2.退出调试界面
命令:quit/q 退出调试界面
3.开始调试
输入r/run开始调试,默认会直接将代码跑完,所以就需要打断点
4.打断点
输入 b/break [文件名]:行号 或
输入 b/break 行号
来打断点
命令:info/i b/break 可以查看有哪些断点
然后输入r/run,程序运行时会从第一个断点开始运行。
[zhangsan@hcss-ecs-f571 learn_25_9_12]$ cgdb code5x int Sum(int s, int e)6x {7x int result = 0;8x int i = 0;9x for(i = s; i <= e; i++)
10x {
11x result += i;
12x }
13x return result*flag;
14x }
15x
16x int main()
17x {
18x int start = 1;
19x int end = 100;
20t> printf("I will begin\n");
21x int n = Sum(start, end);
22x printf("running done, result is: [%d-%d]=%d\n", start, end, n);
23x return 0;
24x }
/home/zhangsan/learn_25_9_12/code.c
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/zhangsan/learn_25_9_12/code...done.
(gdb) b 20
Breakpoint 1 at 0x4005d1: file code.c, line 20.
(gdb) b 22
Breakpoint 2 at 0x4005ed: file code.c, line 22.
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000004005d1 in main at code.c:20
2 breakpoint keep y 0x00000000004005ed in main at code.c:22
(gdb) r
Starting program: /home/zhangsan/learn_25_9_12/code Breakpoint 1, main () at code.c:20
Missing separate debuginfos, use: debuginfo-install glibc-2.17-326.el7_9.3.x86_64
(gdb)
4.1打条件断点
命令:b/break 行号 if 条件
如:b 11 if i == 10
(gdb) b 11 if i==10
Breakpoint 3 at 0x40059d: file code.c, line 11.
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000004005d1 in main at code.c:20breakpoint already hit 1 time
2 breakpoint keep y 0x00000000004005ed in main at code.c:22
3 breakpoint keep y 0x000000000040059d in Sum at code.c:11stop only if i==10
(gdb)
4.2给已存在的断点新增条件
命令:condition [条件序号] [条件]
如:condition 11 i == 10
解释:条件序号就是info b命令后,Num对应的数子。
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x000000000040059d in Sum at code.c:11
(gdb) condition 1 i == 10
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x000000000040059d in Sum at code.c:11stop only if i == 10
(gdb)
5.逐过程调试,逐语句调试
命令:n/next 单步执行,不进入函数内部,逐过程(F10)
命令:s/step 单步执行,进入函数内部,逐语句(F11)
6.跳到下一个断点调试
命令:c/continue 从当前位置开始连续执行程序(一个断点跳到下一个断点)
7.查看调试变量信息
命令:p [变量名] 打印指定变量的值
命令:display [变量名] 跟踪显示变量的值
命令:undisplay [编号] 取消对指定编号的变量的跟踪显示
(gdb) display i
1: i = 4195472
(gdb) n
1: i = 4195472
(gdb)
1: i = 0
(gdb)
1: i = 1
(gdb)
1: i = 1
(gdb)
1: i = 2
(gdb)
1: i = 2
(gdb)
1: i = 2
(gdb) undisplay 1
(gdb) n
(gdb)
8.禁用断点,启用断点
命令:disable [编号] 禁用[编号]断点
命令:disable breakpoints 禁用所有断点
命令:enable [编号] 启用[编号]断点
命令:enable breakpoints 启用所有断点
(gdb) i b
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000004005db in main at code.c:21breakpoint already hit 1 time
2 breakpoint keep n 0x000000000040059d in Sum at code.c:10
(gdb) disable breakpoints
(gdb) i b
Num Type Disp Enb Address What
1 breakpoint keep n 0x00000000004005db in main at code.c:21breakpoint already hit 1 time
2 breakpoint keep n 0x000000000040059d in Sum at code.c:10
(gdb) enable breakpoints
(gdb) i b
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000004005db in main at code.c:21breakpoint already hit 1 time
2 breakpoint keep y 0x000000000040059d in Sum at code.c:10
(gdb)
9.删除断点
命令:delete/d [编号] 删除[编号]断点
命令:delete/d breakpoints 删除所以断点
三、一些调试小技巧
命令:list/l 显示源代码,从上次位置开始,每次列出 10行
命令:list/l 函数名 列出指定函数的源代码 如:l main
命令:list/l 文件名:行号 列出指定文件位置的源代码 如:l code.c main
命令:finish 执行到当前函数返回,然后停止
如:在sum函数中执行时,输入finish可以直接将sum函数执行完并返回,
若sum函数中有断点,则执行到断点位置处停止。
命令:p/print [表达式] 打印表达式的值 如:print x+y
命令:until 行号 执行到指定行号 如:until 20
命令:backtrace/bt 查看当前执行栈的各级函数调用及参数
命令:info/i locals 查看当前栈帧的局部变量值
(gdb) s
Sum (s=1, e=100) at code.c:7
(gdb) bt
#0 Sum (s=1, e=100) at code.c:7
#1 0x00000000004005ea in main () at code.c:21
(gdb) i locals
result = 0
i = 4195472
(gdb)
命令:watch
执行时监视⼀个表达式(如变量)的值。如果监视的表达式在程序运行期间的值发生变化,GDB会暂停程序的执行,并通知使用者
Sum (s=1, e=100) at code.c:9
(gdb)
(gdb)
Hardware watchpoint 3: resultOld value = 1
New value = 3
Sum (s=1, e=100) at code.c:9
(gdb)
(gdb)
Hardware watchpoint 3: resultOld value = 3
New value = 6
Sum (s=1, e=100) at code.c:9
(gdb)
Breakpoint 4 at 0x400595: file code.c, line 9.
(gdb) Quit
(gdb)
命令:set var [修改的条件]
可以在调试的时候暂时修改变量的值,方便确定问题在哪块。