GDB调试命令

GDB调试命令:

一、多线程调试

多线程调试可能是问得最多的。其实,重要就是下面几个命令:

1
2
3
4
5
6
7
info thread 查看当前进程的线程。
thread <ID> 切换调试的线程为指定ID的线程。
break file.c:100 thread all  在file.c文件第100行处为所有经过这里的线程设置断点。
set scheduler-locking off|on|step,这个是问得最多的。在使用step或者continue命令调试当前被调试线程的时候,其他线程也是同时执行的,怎么只让被调试程序执行呢?通过这个命令就可以实现这个需求。
off 不锁定任何线程,也就是所有线程都执行,这是默认值。
on 只有当前被调试程序会执行。
step 在单步的时候,除了next过一个函数的情况(熟悉情况的人可能知道,这其实是一个设置断点然后continue的行为)以外,只有当前线程会执行。

二、调试宏

这个问题超多。在GDB下,我们无法print宏定义,因为宏是预编译的。但是我们还是有办法来调试宏,这个需要GCC的配合。

在GCC编译程序的时候,加上-ggdb3参数,这样,你就可以调试宏了。

另外,你可以使用下述的GDB的宏调试命令 来查看相关的宏。

1
2
info macro - 你可以查看这个宏在哪些文件里被引用了,以及宏定义是什么样的。
macro - 你可以查看宏展开的样子。

三、源文件

这个问题问的也是很多的,太多的朋友都说找不到源文件。在这里我想提醒大家做下面的检查:

编译程序员是否加上了-g参数以包含debug信息。 路径是否设置正确了。使用GDB的directory命令来设置源文件的目录。 下面给一个调试/bin/ls的示例(ubuntu下)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ apt-get source coreutils
$ sudo apt-get install coreutils-dbgsym
$ gdb /bin/ls
GNU gdb (GDB) 7.1-ubuntu
(gdb) list main
1192    ls.c: No such file or directory.
in ls.c
(gdb) directory ~/src/coreutils-7.4/src/
Source directories searched: /home/hchen/src/coreutils-7.4:$cdir:$cwd
(gdb) list main
1192        }
1193    }
1194
1195    int
1196    main (int argc, char **argv)
1197    {
1198      int i;
1199      struct pending *thispend;
1200      int n_files;
1201

四、条件断点

条件断点是语法是:break [where] if [condition],这种断点真是非常管用。尤其是在一个循环或递归中,或是要监视某个变量。注意,这个设置是在GDB中的,只不过每经过那个断点时GDB会帮你检查一下条件是否满足。

五、命令行参数

有时候,我们需要调试的程序需要有命令行参数,很多朋友都不知道怎么设置调试的程序的命令行参数。其实,有两种方法:

1
2
gdb命令行的 -args 参数
gdb环境中 set args命令。

六、gdb的变量

有时候,在调试程序时,我们不单单只是查看运行时的变量,我们还可以直接设置程序中的变量,以模拟一些很难在测试中出现的情况,比较一些出错,或是switch的分支语句。使用set命令可以修改程序中的变量。

另外,你知道gdb中也可以有变量吗?就像shell一样,gdb中的变量以$开头,比如你想打印一个数组中的个个元素,你可以这样:

1
2
3
4
5
(gdb) set $i = 0
  
(gdb) p a[$i++]

...  #然后就一路回车下去了

当然,这里只是给一个示例,表示程序的变量和gdb的变量是可以交互的。

七、x命令

也许,你很喜欢用p命令。所以,当你不知道变量名的时候,你可能会手足无措,因为p命令总是需要一个变量名的。x命令是用来查看内存的,在gdb中 “help x” 你可以查看其帮助。

1
2
3
4
5
x/x 以十六进制输出
x/d 以十进制输出
x/c 以单字符输出
x/i  反汇编 - 通常,我们会使用 x/10i $ip-20 来查看当前的汇编($ip是指令寄存器)
x/s 以字符串输出

八、command命令

有一些朋友问我如何自动化调试。这里向大家介绍command命令,简单的理解一下,其就是把一组gdb的命令打包,有点像字处理软件的“宏”。下面是一个示例:

1
2
3
4
5
6
7
8
9
10
(gdb) break func
Breakpoint 1 at 0x3475678: file test.c, line 12.
(gdb) command 1
Type commands for when breakpoint 1 is hit, one per line.
End with a line saying just "end".
>print arg1
>print arg2
>print arg3
>end
(gdb)

当我们的断点到达时,自动执行command中的三个命令,把func的三个参数值打出来。

gdb基本命令

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
命令描述backtrace(或bt)查看各级函数调用及参数
finish连续运行到当前函数返回为止,然后停下来等待命令
frame(或f) 帧编号选择栈帧
info(或i) locals查看当前栈帧局部变量的值
list(或l)列出源代码,接着上次的位置往下列,每次列10行
list 行号 列出从第几行开始的源代码
list函数名 列出某个函数的源代码
next(或n)执行下一行语句
print(或p)打印表达式的值,通过表达式可以修改变量的值或者调用函数
quit(或q)退出gdb调试环境
set var修改变量的值
start开始执行程序,停在main函数第一行语句前面等待命令
step(或s)执行下一行语句,如果有函数调用则进入到函数中

break(或b) 行号在某一行设置断点
break 函数名在某个函数开头设置断点
break ... if ...设置条件断点
continue(或c)从当前位置开始连续运行程序
delete breakpoints 断点号删除断点
display 变量名跟踪查看某个变量,每次停下来都显示它的值
disable breakpoints 断点号禁用断点
enable 断点号启用断点
info(或i) breakpoints查看当前设置了哪些断点
run(或r)从头开始连续运行程序
undisplay 跟踪显示号取消跟踪显示

Comments