GDB调试


1.什么是GDB

在这里插入图片描述

2. 准备工作

  • 通常,在为调试而编译时,我们会关掉编译器的优化选项"-o",并打开调试选选项“-g”,另外,“-wall” 在尽量不影响程序行为的情况下选项打开所有warning,也可以发现许多问题,避免一些不必要的bug
  • gcc -g -wall program.cpp -o paogram
  • “-g” 选项的作用是在可执行文件中加入源码的信息,比如可执行文件中第几条机器指令对影院吗中的第几行,但并不是把整个源文件嵌入到可执行文件中,所以在调试时必须保证gdb可以找到源文件。

3.GDB命令-启动、退出、查看代码

  • 启动和退出
gdb 可执行程序
quit
  • 给程序设置参数/获取设置参数
set args 10 20
show args
  • GDB使用帮助
help
  • 查看当前文件代码
list/l         #从默认位置显示
list/l 行号     #从指定的行号显示
lsit/l 函数名   #从指定的函数显示
  • 查看非当前文件代码
lsit/l 文件名:行号
list/l 文件名:函数名
  • 设置显示的行数
show list/listsize
set list/listsize 行数

示例

#include <stdio.h>
#include <stdlib.h>

int test(int a);

int main(int argc, char* argv[])
{
	int a, b;
	printf("argc = %d\n", argc);

	if (argc < 3)
	{
		a = 10;
		b = 30;
	}
	else
	{
		a = atoi(argv[1]);
		b = atoi(argv[2]);
	}
	printf("a = %d,b = %d\n", a, b);
	printf("a + b = %d\n", a + b);

	for (int i = 0; i < a; i++)
	{
		printf("i = %d\n",i);
		//函数调用
		int res = test(i);
		printf("res value:%d\n", res);

	}

	printf("THE END!!!\n");
	return 0;
}

int test(int a)
{
	int num = 0;
	for (int i = 0; i < a; i++)
	{
		num += i;
	}
	return num;
}

在这里插入图片描述

[mytest@redhat7g gdbtest]$ ll
total 4
-rw-rw-r-- 1 mytest mytest 601 Dec  7 18:33 1207-gdb_test_mian.cpp
[mytest@redhat7g gdbtest]$ gcc 1207-gdb_test_mian.cpp -o test -g
[mytest@redhat7g gdbtest]$ ll
total 16
-rw-rw-r-- 1 mytest mytest  601 Dec  7 18:33 1207-gdb_test_mian.cpp
-rwxrwxr-x 1 mytest mytest 9976 Dec  7 18:34 test
[mytest@redhat7g gdbtest]$ gcc 1207-gdb_test_mian.cpp -o test1
[mytest@redhat7g gdbtest]$ ll -h test test1
-rwxrwxr-x 1 mytest mytest 9.8K Dec  7 18:34 test
-rwxrwxr-x 1 mytest mytest 8.4K Dec  7 18:34 test1
[mytest@redhat7g gdbtest]$ rm test1 
[mytest@redhat7g gdbtest]$ ll
total 16
-rw-rw-r-- 1 mytest mytest  601 Dec  7 18:33 1207-gdb_test_mian.cpp
-rwxrwxr-x 1 mytest mytest 9976 Dec  7 18:34 test
[mytest@redhat7g gdbtest]$ gdb test 
GNU 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/mytest/gdbtest/test...done.
(gdb) set args 34 34
(gdb) show args 
Argument list to give program being debugged when it is started is "34 34".
(gdb) help
List of classes of commands:

aliases -- Aliases of other commands
breakpoints -- Making program stop at certain points
data -- Examining data
files -- Specifying and examining files
internals -- Maintenance commands
obscure -- Obscure features
running -- Running the program
stack -- Examining the stack
status -- Status inquiries
support -- Support facilities
tracepoints -- Tracing of program execution without stopping the program
user-defined -- User-defined commands

Type "help" followed by a class name for a list of commands in that class.
Type "help all" for the list of all commands.
Type "help" followed by command name for full documentation.
Type "apropos word" to search for commands related to "word".
Command name abbreviations are allowed if unambiguous.
(gdb) l
1	#include <stdio.h>
2	#include <stdlib.h>
3	
4	int test(int a);
5	
6	int main(int argc, char* argv[])
7	{
8		int a, b;
9		printf("argc = %d\n", argc);
10	
(gdb) l 24
19			b = atoi(argv[2]);
20		}
21		printf("a = %d,b = %d\n", a, b);
22		printf("a + b = %d\n", a + b);
23	
24		for (int i = 0; i < a; i++)
25		{
26			printf("i = %d\n",i);
27			//º¯˽µ
28			int res = test(i);
(gdb) show list test
Number of source lines gdb will list by default is 10.
(gdb) help set
Evaluate expression EXP and assign result to variable VAR, using assignment
syntax appropriate for the current language (VAR = EXP or VAR := EXP for
example).  VAR may be a debugger "convenience" variable (names starting
with $), a register (a few standard names starting with $), or an actual
variable in the program being debugged.  EXP is any valid expression.
Use "set variable" for variables with names identical to set subcommands.

With a subcommand, this command modifies parts of the gdb environment.
You can see these environment settings with the "show" command.

List of set subcommands:

set ada -- Prefix command for changing Ada-specfic settings
set agent -- Set debugger's willingness to use agent as a helper
set annotate -- Set annotation_level
set architecture -- Set architecture of target
set args -- Set argument list to give program being debugged when it is started
set auto-load -- Auto-loading specific settings
set auto-load-scripts -- Set the debugger's behaviour regarding auto-loaded Python scripts
set auto-solib-add -- Set autoloading of shared library symbols
set backtrace -- Set backtrace specific variables
set basenames-may-differ -- Set whether a source file may have multiple base names
set breakpoint -- Breakpoint specific settings
set build-id-core-loads -- Set whether CORE-FILE loads the build-id associated files automatically
set build-id-verbose -- Set debugging level of the build-id locator
set can-use-hw-watchpoints -- Set debugger's willingness to use watchpoint hardware
set case-sensitive -- Set case sensitivity in name search
set charset -- Set the host and target character sets

4.设置断点

  • 设置断点
b/break 行号
b/break 函数名
b/break 文件名:行号
b/break 文件名:函数
  • 查看断点
i/info b/break
  • 删除断点
d/del/delete b/break
  • 设置断点无效
dis.disbale 断点编号
  • 设置断点生效
ena 、enable 断点编号
  • 设置条件断点
b/break 10 if i == 6
(gdb) b 18
Breakpoint 1 at 0x4005d6: file 1207-gdb_test_mian.cpp, line 18.
(gdb) b 42
Breakpoint 2 at 0x4006a4: file 1207-gdb_test_mian.cpp, line 42.
(gdb) info b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x00000000004005d6 in main(int, char**) at 1207-gdb_test_mian.cpp:18
2       breakpoint     keep y   0x00000000004006a4 in test(int) at 1207-gdb_test_mian.cpp:42
(gdb) b 39
Breakpoint 3 at 0x400694: file 1207-gdb_test_mian.cpp, line 39.
(gdb) info b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x00000000004005d6 in main(int, char**) at 1207-gdb_test_mian.cpp:18
2       breakpoint     keep y   0x00000000004006a4 in test(int) at 1207-gdb_test_mian.cpp:42
3       breakpoint     keep y   0x0000000000400694 in test(int) at 1207-gdb_test_mian.cpp:39
(gdb) b test
Note: breakpoint 3 also set at pc 0x400694.
Breakpoint 4 at 0x400694: file 1207-gdb_test_mian.cpp, line 39.
(gdb) info b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x00000000004005d6 in main(int, char**) at 1207-gdb_test_mian.cpp:18
2       breakpoint     keep y   0x00000000004006a4 in test(int) at 1207-gdb_test_mian.cpp:42
3       breakpoint     keep y   0x0000000000400694 in test(int) at 1207-gdb_test_mian.cpp:39
4       breakpoint     keep y   0x0000000000400694 in test(int) at 1207-gdb_test_mian.cpp:39
(gdb) del 3
(gdb) info b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x00000000004005d6 in main(int, char**) at 1207-gdb_test_mian.cpp:18
2       breakpoint     keep y   0x00000000004006a4 in test(int) at 1207-gdb_test_mian.cpp:42
4       breakpoint     keep y   0x0000000000400694 in test(int) at 1207-gdb_test_mian.cpp:39
(gdb) dis 2
(gdb) info b 
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x00000000004005d6 in main(int, char**) at 1207-gdb_test_mian.cpp:18
2       breakpoint     keep n   0x00000000004006a4 in test(int) at 1207-gdb_test_mian.cpp:42
4       breakpoint     keep y   0x0000000000400694 in test(int) at 1207-gdb_test_mian.cpp:39
(gdb) enable 2
(gdb) info b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x00000000004005d6 in main(int, char**) at 1207-gdb_test_mian.cpp:18
2       breakpoint     keep y   0x00000000004006a4 in test(int) at 1207-gdb_test_mian.cpp:42
4       breakpoint     keep y   0x0000000000400694 in test(int) at 1207-gdb_test_mian.cpp:39
(gdb) 

5.GDB命令-调试命令

  • 运行GDB程序
start 		#程序停在第一行
run			#程序遇到断点才停
  • 继续运行,到下一个断点
c/continue
  • 向下执行一行代码(不会进入函数体)
n/next
  • 变量操作
p/print 变量名		#打印变量值
ptype 变量名			#打印变量类型
  • 向下单步调试(遇到函数进入函数体)
s/step
finish		#跳出函数体
  • 自动变量操作
display num		#自动打印指定变量的值
i/info display
undisplay 编号
  • 其他操作
set vat 变量名 = 变量值
until 		#跳出循环
[mytest@redhat7g gdbtest]$ gdb test 
GNU 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/mytest/gdbtest/test...done.
(gdb) lsit
Undefined command: "lsit".  Try "help".
(gdb) list
1	#include <stdio.h>
2	#include <stdlib.h>
3	
4	int test(int a);
5	
6	int main(int argc, char* argv[])
7	{
8		int a, b;
9		printf("argc = %d\n", argc);
10	
(gdb) list main
2	#include <stdlib.h>
3	
4	int test(int a);
5	
6	int main(int argc, char* argv[])
7	{
8		int a, b;
9		printf("argc = %d\n", argc);
10	
11		if (argc < 3)
(gdb) b 9
Breakpoint 1 at 0x4005ac: file 1207-gdb_test_mian.cpp, line 9.
(gdb) list test
33		printf("THE END!!!\n");
34		return 0;
35	}
36	
37	int test(int a)
38	{
39		int num = 0;
40		for (int i = 0; i < a; i++)
41		{
42			num += i;
(gdb) b 42
Breakpoint 2 at 0x4006a4: file 1207-gdb_test_mian.cpp, line 42.
(gdb) info b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x00000000004005ac in main(int, char**) at 1207-gdb_test_mian.cpp:9
2       breakpoint     keep y   0x00000000004006a4 in test(int) at 1207-gdb_test_mian.cpp:42
(gdb) start
Temporary breakpoint 3 at 0x4005ac: file 1207-gdb_test_mian.cpp, line 9.
Starting program: /home/mytest/gdbtest/test 

Breakpoint 1, main (argc=1, argv=0x7fffffffe4b8) at 1207-gdb_test_mian.cpp:9
9		printf("argc = %d\n", argc);
Missing separate debuginfos, use: debuginfo-install glibc-2.17-325.el7_9.x86_64
(gdb) n
argc = 1
11		if (argc < 3)
(gdb) n
13			a = 10;
(gdb) n
14			b = 30;
(gdb) n
21		printf("a = %d,b = %d\n", a, b);
(gdb) n
a = 10,b = 30
22		printf("a + b = %d\n", a + b);
(gdb) pa
Ambiguous command "pa": pahole, passcount, path.
(gdb) p a
$1 = 10
(gdb) p b
$2 = 30
(gdb) p argc
$3 = 1
(gdb) s
a + b = 40
24		for (int i = 0; i < a; i++)
(gdb) s
26			printf("i = %d\n",i);
(gdb) s
i = 0
28			int res = test(i);
(gdb) s
test (a=0) at 1207-gdb_test_mian.cpp:39
39		int num = 0;
(gdb) s
40		for (int i = 0; i < a; i++)
(gdb) s
44		return num;
(gdb) s
45	}(gdb) finish 
Run till exit from #0  test (a=0) at 1207-gdb_test_mian.cpp:45
0x0000000000400659 in main (argc=1, argv=0x7fffffffe4b8) at 1207-gdb_test_mian.cpp:28
28			int res = test(i);
Value returned is $4 = 0
(gdb) s
29			printf("res value:%d\n", res);
(gdb) n
res value:0
24		for (int i = 0; i < a; i++)
(gdb) n
26			printf("i = %d\n",i);
(gdb) set i = 990
Ambiguous set command "i = 990": inferior-tty, input-radix, interactive-mode.
(gdb) n
i = 1
28			int res = test(i);
(gdb) n

Breakpoint 2, test (a=1) at 1207-gdb_test_mian.cpp:42
42			num += i;
(gdb) n
40		for (int i = 0; i < a; i++)
(gdb) n
44		return num;
(gdb) n
45	}(gdb) n
main (argc=1, argv=0x7fffffffe4b8) at 1207-gdb_test_mian.cpp:29
29			printf("res value:%d\n", res);
(gdb) n
res value:0
24		for (int i = 0; i < a; i++)
(gdb) n
26			printf("i = %d\n",i);
(gdb) n
i = 2
28			int res = test(i);
(gdb) n

Breakpoint 2, test (a=2) at 1207-gdb_test_mian.cpp:42
42			num += i;
(gdb) n
40		for (int i = 0; i < a; i++)
(gdb) p i 
$5 = 0
(gdb) c
Continuing.

Breakpoint 2, test (a=2) at 1207-gdb_test_mian.cpp:42
42			num += i;
(gdb) c
Continuing.
res value:1
i = 3
(gdb) display a
1: a = 8
(gdb) display b
No symbol "b" in current context.
(gdb) n
Breakpoint 2, test (a=8) at 1207-gdb_test_mian.cpp:42
42			num += i;
1: a = 8
(gdb) n
40		for (int i = 0; i < a; i++)
1: a = 8
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

良缘白马

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值