如何传递参数并将stdin从文件重定向到gdb中运行的程序?


Answers:


136

run从gdb内部将参数传递给命令。

$ gdb ./a.out
(gdb) r < t
Starting program: /dir/a.out < t

3
r是缩写run,您可以使用任何参数跟随它。像这个问题一样,可能是:r arg1 arg2 <file或可能是run arg1 arg2 <file
phyatt

对我来说,这是行不通的。然后我尝试了,$ gdb ./a.out(gdb) r < t arg1 arg2对我来说很好。在我的情况a.out = nft arg1 = import arg2 = jsont = file containing json rules
mystictot

410

你可以这样做:

gdb --args path/to/executable -every -arg you can=think < of

魔力正在--args

只需run在gdb命令控制台中键入即可开始调试。


24
我以为刚开始我读错了;--args位于可执行文件之前是很奇怪的。但是就是这样!
高岭土大火

8
@Kaolin --args必须在可执行文件之前,因为它是gdb的开关。如果出现这种情况,gdb将如何与您希望传递到正在调试的可执行文件中的参数区分开来?
codehippo

9
@codehippo:好吧,如果您没有指定,--args那么没有任何参数传递给可执行文件,因此几乎没有歧义。
Lightness Races in Orbit

14
我猜是因为按惯例argv[0]是可执行文件的名称
Claudiu 2014年

3
这会将gdb自身输入重定向到of文件,并导致gdb尝试从文件执行命令
unkulunkulu

4

如果您想使用裸run命令gdb执行带有重定向和参数的程序,则可以使用set args

% gdb ./a.out
(gdb) set args arg1 arg2 <file
(gdb) run

我无法通过--args参数实现相同的行为,因此无法进行gdb重定向,即

% gdb --args echo 1 2 "<file"
(gdb) show args
Argument list to give program being debugged when it is started is "1 2 \<file".
(gdb) run
...
1 2 <file
...

实际上这是重定向gdb本身的输入,而不是我们在这里真正想要的

% gdb --args echo 1 2 <file
zsh: no such file or directory: file

1

在您的项目上启动GDB。

  1. 转到项目目录,您已经在其中编译了项目可执行文件。发出命令gdb和可执行文件的名称,如下所示:

    gdb projectExecutablename

这会启动gdb,并打印以下内容:GNU gdb(Ubuntu 7.11.1-0ubuntu1〜16.04)7.11.1版权所有(C)2016 Free Software Foundation,Inc. .....................键入“ apropos word”以搜索与“ word”相关的命令。 。从projectExecutablename ...中读取符号。(gdb)

  1. 在开始运行程序之前,您想要设置断点。break命令允许您这样做。要在名为main的函数的开头设置一个断点:

    (gdb)b主

  2. 出现(gdb)提示符后,运行命令将开始运行可执行文件。如果要调试的程序需要任何命令行参数,则可以在run命令中指定它们。如果要在“ xfiles”文件(位于项目目录中的“ mulder”文件夹中)上运行程序,请执行以下操作:

    (gdb)r mulder / xfiles

希望这可以帮助。

免责声明:此解决方案不是我的,它改编自https://web.stanford.edu/class/cs107/guide_gdb.html 这个gdb简短指南很可能是由斯坦福大学开发的。


0

只需debug在命令行之前键入任何命令就可以gdb在shell级别进行调试,这会很好吗?

在它下面的这个功能。它甚至可以与以下内容一起使用:

"$program" "$@" < <(in) 1> >(out) 2> >(two) 3> >(three)

这是一个您无法控制任何内容的调用,所有内容都是可变的,可以包含空格,换行符和shell元字符。在这个例子中,inouttwo,和three是必须不会受到伤害,其消耗的任意其它命令或产生数据。

在这样的环境中,以下bash函数gdb几乎干净地调用[ Gist ]:

debug()
{
  1000<&0 1001>&1 1002>&2 \
  0</dev/tty 1>/dev/tty 2>&0 \
  /usr/bin/gdb -q -nx -nw \
  -ex 'set exec-wrapper /bin/bash -c "exec 0<&1000 1>&1001 2>&1002 \"\$@\"" exec' \
  -ex r \
  --args "$@";
}

有关如何应用此示例:只需debug在前面输入:

之前:

p=($'\n' $'I\'am\'evil' "  yay  ")
"b u g" "${p[@]}" < <(in) 1> >(out) 2> >(two) 3> >(three)

后:

p=($'\n' $'I\'am\'evil' "  yay  ")
debug "b u g" "${p[@]}" < <(in) 1> >(out) 2> >(two) 3> >(three)

而已。现在,使用进行调试绝对是轻而易举gdb。除了一些细节或更多:

  • gdb不会自动退出,因此在退出之前保持IO重定向打开gdb。但是我将此称为功能。

  • 您不能argv0像和一样轻松地传递给程序exec -a arg0 command args。请执行以下操作:exec-wrapper更改"exec"exec -a \"\${DEBUG_ARG0:-\$1}\"

  • FD大于1000,通常处于关闭状态。如果有问题,请0<&1000 1>&1001 2>&1002改为阅读0<&1000 1>&1001 2>&1002 1000<&- 1001>&- 1002>&-

  • 您不能并行运行两个调试器。如果使用其他一些命令/dev/tty(或STDIN),也可能会出现问题。要解决此问题,请替换/dev/tty"${DEBUGTTY:-/dev/tty}"。在其他一些TTY类型中tty; sleep inf,然后使用打印的TTY(即E. /dev/pts/60)进行调试,如中所示DEBUGTTY=/dev/pts/60 debug command arg..。这就是壳牌的力量,请习惯它!

功能说明:

  • 1000<&0 1001>&1 1002>&2 移走前3个FD
    • 假设FD 1000、1001和1002是免费的
  • 0</dev/tty 1>/dev/tty 2>&0恢复前三个FD指向您当前的TTY。这样就可以控制了gdb
  • /usr/bin/gdb -q -nx -nw在外壳上运行gdb调用gdb
  • -ex 'set exec-wrapper /bin/bash -c "exec 0<&1000 1>&1001 2>&1002 \"\$@\"" 创建一个启动包装程序,该程序将还原保存到1000及更高版本的前3个FD
  • -ex r 使用启动程序 exec-wrapper
  • --args "$@" 传递给定的参数

那不是那么容易吗?

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.