GDB中应该知道的几个调试方法
七、八年前写过一篇《用GDB调试程序》,于是,从那以后,很多朋友在MSN上以及给我发邮件询问我关于GDB的问题,一直到今天,还有人在问GDB的相关问题。这么多年来,有一些问题是大家反复在问的,一方面,我觉得我以前的文章可能没有说清楚,另一方面,我觉得大家常问的问题正是最有用的,所以,在这里罗列出来。希望大家补充。
目录
一、多线程调试
多线程调试可能是问得最多的。其实,重要就是下面几个命令:
- 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的宏调试命令 来查看相关的宏。
- info macro – 你可以查看这个宏在哪些文件里被引用了,以及宏定义是什么样的。
- macro – 你可以查看宏展开的样子。
三、源文件
这个问题问的也是很多的,太多的朋友都说找不到源文件。在这里我想提醒大家做下面的检查:
- 编译程序员是否加上了-g参数以包含debug信息。
- 路径是否设置正确了。使用GDB的directory命令来设置源文件的目录。
下面给一个调试/bin/ls的示例(ubuntu下)
$ 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会帮你检查一下条件是否满足。
五、命令行参数
有时候,我们需要调试的程序需要有命令行参数,很多朋友都不知道怎么设置调试的程序的命令行参数。其实,有两种方法:
- gdb命令行的 –args 参数
- gdb环境中 set args命令。
六、gdb的变量
有时候,在调试程序时,我们不单单只是查看运行时的变量,我们还可以直接设置程序中的变量,以模拟一些很难在测试中出现的情况,比较一些出错,或是switch的分支语句。使用set命令可以修改程序中的变量。
另外,你知道gdb中也可以有变量吗?就像shell一样,gdb中的变量以$开头,比如你想打印一个数组中的个个元素,你可以这样:
(gdb) set $i = 0 (gdb) p a[$i++] ... #然后就一路回车下去了
当然,这里只是给一个示例,表示程序的变量和gdb的变量是可以交互的。
七、x命令
也许,你很喜欢用p命令。所以,当你不知道变量名的时候,你可能会手足无措,因为p命令总是需要一个变量名的。x命令是用来查看内存的,在gdb中 “help x” 你可以查看其帮助。
- x/x 以十六进制输出
- x/d 以十进制输出
- x/c 以单字符输出
- x/i 反汇编 – 通常,我们会使用
x/10i $ip-20 来查看当前的汇编($ip是指令寄存器)
- x/s 以字符串输出
八、command命令
有一些朋友问我如何自动化调试。这里向大家介绍command命令,简单的理解一下,其就是把一组gdb的命令打包,有点像字处理软件的“宏”。下面是一个示例:
(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的三个参数值打出来。
(全文完)
(转载本站文章请注明作者和出处 酷 壳 – CoolShell ,请勿用于任何商业用途)
《GDB中应该知道的几个调试方法》的相关评论
some more (on 8. command命令):
http://www.chemie.fu-berlin.de/chemnet/use/info/gdb/gdb_16.html
Canned Sequences of Commands:
A user-defined command is a sequence of GDB commands to which you assign a new name as a command. This is done with the define command. User commands may accept up to 10 arguments separated by whitespace. Arguments are accessed within the user command via $arg0…$arg9. A trivial example:
define adder
print $arg0 + $arg1 + $arg2
…
To execute the command use:
adder 1 2 3
…
When you start GDB, it automatically executes commands from its init files. These are files named `.gdbinit’.
You can also request the execution of a command file with the source command:
source filename
…
谢了,比文档说的清楚多了.
非常好,谢谢分享。
补充一个,如果要打印一个序列化过的结构体,这个序列太长的话,往往会被gdb省略掉,如:
gdb>p string
“xxxx”,…”” //会有省略号出现,无法看到完整的字符串
此时可以设置:
gdb>set print elements 0
再次:
gdb>p string
“xxxx”,”yyyy”, “”//显示完整的字符串
路过,瞧瞧不错,特意支持一下。
不错呢。新年愉快么?
兄弟们哪,gdb工具很强大,一定要好好用哇
五、命令行参数
有时候,我们需要调试的程序需要有命令行参数,很多朋友都不知道怎么设置调试的程序的命令行参数。其实,有两种方法:
1.gdb命令行的 –args 参数
2.gdb环境中 set args命令。
3.gdb中,run后加参数,run 1 2(r 1 2)
你好,
我用gdb,在windows eclipse & MinGW下调试c++时,提示No source available for “__mingw_CRTStartup() at 0x4010db” 。不知道什么原因,理论上MinGW的入口函数已经编译进去?请问有可能是什么原因呢?
陈老师好:
有个小问题,发现commands里面如果包含了step命令却是无效的。我把断点1设置在调用某一自定义函数func1的地方,想在step进入func1之前打印一个参数:
commands 1:
>p something
>step
>end
这样的commands会step进func1,但是会在func1的第一行停住,需要继续输入命令;
我再在func1的首行设断点2,并编写2的commands:
commands 2:
>c
>end
发现这样仍然需要敲回车确认是否continue……不想一直敲回车怎么办?
期待回复,谢啦!
陈老师你好:
我去CSDN翻阅了你以前的技术文档,但是好像第二页老是404页面,你的排名靠前的技术文章能抽闲暇时间搬过来吗?
都是很好的学习资料,还有,鄙视一下TSU PRESS
能把这篇重要的《用GDB调试程序》先搬过来吗?@OpenASM
感谢
感谢分享,附上我的博客:http://reborncodinglife.com/
《用GDB调试程序》也是系列文章啊,要不也给搬运到这里来?
还是那句话,csdn将来不知道会成什么样,未雨绸缪吧。
GDB 调试系列文章应该帮助了很多初学者,讲的非常详细和全面。闲来无事,把文章总结(搬运)整理到了自己的小站点上了。
https://www.linuxblogs.cn/articles/15041200.html