如何在Bash脚本中使用GDB运行一个带命令行参数的程序?

656

在使用GDB运行程序时,通常需要在run命令中输入程序的参数。是否有一种方法可以在shell脚本中同时使用GDB运行程序并提供参数呢?

我在相关问题的答案中看到一个说法,提到我们可以在脚本开始执行后将GDB附加到程序上。但这样我就必须“等待”程序。

还有其他方法吗?


3
可能是重复的问题:如何在GDB中将参数传递并将标准输入重定向到文件中运行的程序? - Ciro Santilli OurBigBook.com
9个回答

938

您可以使用--args参数运行gdb:

gdb --args executablename arg1 arg2 arg3

如果你经常这样做(例如从脚本中运行GDB),你可以考虑以下参数以进一步自动化。首先,你可以将GDB命令(如“run”)放在文本文件中,并将文件名提供给-x参数。其次,你可以通过提供--batch参数使GDB在运行完你的命令后退出。一个完整的例子:

gdb -x commands.txt --batch --args executablename arg1 arg2 arg3

88
啊,我没在 man gdb 中找到 --args 选项,所以找不到它。但是在 gdb --help 中有提到。 - Ciro Santilli OurBigBook.com
@Apteryx 当我按下 'i' 键时,屏幕底部显示 "未找到索引"。 - Wawrzyniec Pruski
@WawrzyniecPruski,这是哪个GNU/Linux发行版?我怀疑他们GDB软件包中的信息手册有问题。使用GNU Guix,您可以guix shell gdb info-reader -- info gdb,然后从那里开始使用i RET --args序列。 - Apteryx
@Apteryx Centos 7.9.2009 - Wawrzyniec Pruski

225
gdb -ex=r --args myprogram arg1 arg2

-ex=r-ex=run的缩写,告诉gdb立即运行您的程序,而不是等待您在提示符处键入"run"。然后--args表示接下来的所有内容都是命令和参数,就像您通常在命令行提示符下键入的那样。


6
不知道-exe=r这个选项,非常有用! - Jeef
我明白了,你不能执行 gdb --args -ex=r myprogram arg1 arg2 - x-yuri

92

另一种方法,我个人认为更加方便和直观(不需要记住--args参数),是正常编译,然后在gdb中直接使用r arg1 arg2 arg3,如下所示:

$ gcc -g *.c *.h
$ gdb ./a.out
(gdb) r arg1 arg2 arg3

34
这正是原帖作者所希望避免做的事情。 - KarateSnowMachine
12
嗯,是的,谢谢,很公正。我不确定为什么我这么长时间都没有注意到这一点。不过我想我会保留答案在这里,因为我记得当时我在搜索类似“如何使用gdb传递命令行参数”的问题时偶然遇到了这个问题,发现答案缺失,于是添加了我的答案,但近一年来没有意识到我的答案并没有解决实际问题。 - aspiring_sarge
11
作为来自谷歌的人,我认为@KarateSnowMachine的回答更符合我的期望。也许我们应该修改问题,使其更加通用,因为它的标题过于笼统,或者我们应该缩小标题范围。让它变得不那么限制性可能对更多读者更有用。 - jpmc26

21

你可以创建一个带有上下文的文件:

run arg1 arg2 arg3 etc

program input

并且像这样调用 gdb:

gdb prog < file

7
除了Hugo Ideler的答案之外,如果使用带有前缀的参数---,我不确定是否会与gdb发生冲突。
看起来,gdb将args选项后面的所有内容都视为程序的参数。
起初,我想确认一下,所以我在您的args周围加上引号,但这在启动时被删除了。
这也可以工作,但是可选的:
gdb --args executablename "--arg1" "--arg2" "--arg3"

这个不起作用:

gdb --args executablename "--arg1" "--arg2" "--arg3" -tui

在这种情况下,-tui 作为我的程序参数而不是 gdb 的参数被使用。

7

虽然有点晚了,但这里提供一种在会话期间有效的方法。

gdb <可执行文件>

然后输入

(gdb) apropos argument

这将返回大量匹配项,其中有用的是set args

set args -- Set argument list to give program being debugged when it is started.

set args arg1 arg2 ...

然后

r

这将运行程序,并将参数和参数计数传递给main(argc, argv)。


6
如果您的机器上(比如Solaris 8),--args参数无法使用,您可以这样启动gdb:
gdb -ex "set args <arg 1> <arg 2> ... <arg n>"

你还可以将其与将文件输入到 stdin 和 "立即运行" 相结合:

gdb -ex "set args <arg 1> <arg 2> ... <arg n> < <input file>" -ex "r"

4

gdb有一个--init-command <somefile>选项,可以指定一个包含一系列gdb命令的文本文件来运行。我使用它将//GDB注释添加到我的代码中,然后

echo "file ./a.out" > run
grep -nrIH "//GDB"|
    sed "s/\(^[^:]\+:[^:]\+\):.*$/\1/g" |
    awk '{print "b" " " $1}'|
    grep -v $(echo $0|sed "s/.*\///g") >> run
gdb --init-command ./run -ex=r

作为一个脚本,它先放置命令来加载调试符号,然后生成一系列断点命令,为每个 //GDB 注释设置断点,并启动它运行。


1
如果您想从文件中传递参数,例如从文件中作为输入读取scanf,请尝试以下操作。
(gdb) run < the_file_contains_data

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接