(gdb) set args ./ ==> 传参数调试
(gdb) break main ==> 在函数main处插入断点
Breakpoint 1, main (argc=2, argv=0xbffff684) at ls1.c:10
10 if (argc != 2)
(gdb) p argc ==> 打印变量
$2 = 2
GDB的主要功能如下:
- 设置断点
- 显示变量的值
- 单步执行
- 运行时修改变量的值
- 路径跟踪,方便跟踪代码
- 线程切换
- 其他的。。。
使用GDB的前提是,在编译程序的时候需要加入-g选项,即 gcc -g xxx.c。当设置这个选项的时候,GCC会向程序中加入“楔子”,GDB能够利用这些楔子与程序交互。
输入gcc -o test gdb-01.c -g,使其加入“楔子”。下面进入调试:
其中test是可执行文件的名字。
GDB常用的命令( 命令(命令简写):格式及含义 ):
file:加载(可执行)文件,使用在gdb命令后没有接文件名的时候。
1
2
3
4
5
|
(
gdb
)
file
gdb
-01.c
"/home/tyruschin/ClionProjects/gdb_learning/gdb-01.c"
: not
in
executable
format
: 不可识别的文件格式
(
gdb
)
file
test
Load new symbol table from
"test"
? (y or n) y
Reading symbols from
test
...
done
.
|
set args:设置输入参数(可以在run命令中设置,如果不设置的话,run的时候默认使用前一条run命令的参数),set args 参数1 参数2 ...
1
2
3
4
|
(
gdb
)
set
args 2
(
gdb
) run
Starting program:
/home/tyruschin/ClionProjects/gdb_learning/test
2
你输入的值为:2,计算结果为:3
|
show:显示变量,show args
1
2
3
|
(
gdb
)
set
args 2 3
(
gdb
) show args
Argument list to give program being debugged when it is started is
"2 3"
.
|
list(l):表示列出文件的代码内容。list 1表示从第一行开始,默认显示10行,按下回车键可以继续打印10行;list 1,4表示显示1到4行,此时再次按下回车则继续打印下面的10行。
break(b):设置断点,b 行号或函数名。程序运行到断点的位置会终端,等待用户的下一步操作指令。
具体的使用(如果有多个文件共同生成一个目标执行文件的时候,要指定文件名,如 b gdb-01.c:38 ):
- break 行号:程序停止在设定的行之前
- break 函数名称:程序停止在设定的函数之前
- break 行数或者函数if条件:条件为真的情况下,到达指定行或函数时停止
查看断点信息,info break
// 没有写编号就表示全部编号了
删除指定的某个断点:delete breakpoints 断点编号(在info break 中找到)
禁止断点:disable b 断点编号(此时info break中的Enb列中,显示的是n而不是y)
允许断点(禁止的反操作):enable b 断点编号
清除断点:clear 断点行号
run(r):运行程序,run args,这里的args和set args中的是一致的。运行到遇到断点会暂停下来。
1
2
3
4
5
|
(
gdb
) run 3
Starting program:
/home/tyruschin/ClionProjects/gdb_learning/test
3
Breakpoint 1,
sum
(value=3) at
gdb
-01.c:39
39 int result = 0;
|
print(p):打印变量内容,功能强大,可以打印任何有效表达式的值。
设置断点在28行,以上是p打印变量的例子,其中io是一个结构体数组,argv是一个字符串数组,@后面的数字表示打印的个数,超过个数之后打印处的结果是随机的。。
whatis:变量类型检测,打印数组或者变量的类型,whatis 变量名
ptype:变量类型检测,结构的详细定义
set:修改变量的值,set xx=val
(gdb) p i ===> i的值为1
$10 = 1
(gdb) set var i=2 ===> 设置变量i的值为2
(gdb) p i ===> i的值成功设置为2
$11 = 2
display:display 变量,每次在调试到暂停的时候都会显示该值。
1
2
3
4
5
6
7
8
9
|
(
gdb
) run 3
Starting program:
/home/tyruschin/ClionProjects/gdb_learning/test
3
Breakpoint 8, main (argc=2, argv=0x7fffffffde18) at
gdb
-01.c:33
33
printf
(
"你输入的值为:%d,计算结果为:%d\n"
, io -> value, io -> result);
4: argc = 2
3: *argv = 0x7fffffffe1c6
"/home/tyruschin/ClionProjects/gdb_learning/test"
2: argv = (char **) 0x7fffffffde18
1: argc = 2
|
单步调试:next(n)单步跟踪,step(s)进入某个函数,finish返回调用的函数中,continue(c)表示继续执行知道遇到断点或结束。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
(
gdb
) run 3
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program:
/home/tyruschin/ClionProjects/gdb_learning/test
3
Breakpoint 1, main (argc=2, argv=0x7fffffffde18) at
gdb
-01.c:19
19
if
(NULL == io) {
(
gdb
) s
25
if
(argc != 2) {
(
gdb
) s
30 io -> value = *argv[1] -
'0'
;
(
gdb
) s
32 io -> result =
sum
(io -> value);
(
gdb
) s
sum
(value=3) at
gdb
-01.c:39
39 int result = 0;
(
gdb
) s
40 int i = 0;
(
gdb
) finish
Run till
exit
from
#0 sum (value=3) at gdb-01.c:40
0x0000000000400639
in
main (argc=2, argv=0x7fffffffde18) at
gdb
-01.c:32
32 io -> result =
sum
(io -> value);
Value returned is $1 = 6
(
gdb
) s
33
printf
(
"你输入的值为:%d,计算结果为:%d\n"
, io -> value, io -> result);
(
gdb
) c
Continuing.
你输入的值为:3,计算结果为:6
[Inferior 1 (process 27047) exited normally]
|
q表示退出GDB。。
gdb打印地址的值:
x 按十六进制格式显示变量。
d 按十进制格式显示变量。
u 按十六进制格式显示无符号整型。
o 按八进制格式显示变量。
t 按二进制格式显示变量。
a 按十六进制格式显示变量。
c 按字符格式显示变量。
f 按浮点数格式显示变量。
如: 数组的首地址是 0xffbffaf4
(gdb) p/d *((int *)0xffbffaf4)
$12 = 1 ==> 1 是数组的第0个索引的值