调用gdb以自动将参数传递给正在调试的程序

时间:2008-11-26 20:54:53

标签: shell gdb

我想编写一个脚本(在某些条件下)将执行gdb并自动运行一些带有一些参数Y的程序X.一旦程序执行完毕,用户应保持在gdb的提示符下直到他/她明确退出。

执行此操作的一种方法是让脚本将run命令加参数Y输出到某个文件F,然后让脚本像这样调用gdb:

gdb X < F

但有没有办法在不引入临时文件的情况下执行此操作?

感谢。

8 个答案:

答案 0 :(得分:85)

根据计划X和参数列表a b c,最简单的方法:

X a b c

是使用gdb的{​​{1}}选项,如下所示:

--args

gdb --args X a b c 可以说gdb --help

  
    

--args

  

这意味着--args Arguments after executable-file are passed to inferior之后的第一个参数是要调试的可执行文件,之后的所有参数都将传递给到该可执行文件。

答案 1 :(得分:28)

如果你想通过GDB运行一些命令,然后让它退出或运行完成,只需执行

echo commands | gdb X

如果要在运行这些命令后将其保留在命令提示符下,则可以执行

(echo commands; cat) | gdb X

这导致将命令回显到GDB,然后键入cat进程,该进程将其stdin复制到stdout,后者通过管道传输到GDB。

答案 2 :(得分:8)

有选项 -x ,例如

gdb -x gdb_commands exe_file

其中 gdb_commands 可以是例如(在android模拟器的情况下):

target remote :5039

答案 3 :(得分:6)

在这里尝试了所有答案后,

  1. echo / cat hack虽然很聪明,却打破了gdb的一些重要功能。最值得注意的是,所有用户提示都会自动回答(因此您没有机会确认可能存在危险的操作),而Ctrl + C(停止正在调试的进程)最终会杀死cat,所以实际上你不能之后跟gdb交谈。
  2. -x选项应该可以工作,但我无法使用我的gdb版本,它需要一个临时文件。
  3. 然而,事实证明你可以使用-ex,就像这样:

    gdb -ex "target remote localhost:1234"
    

    您还可以指定-ex多次以运行多个命令!

答案 4 :(得分:1)

gdb target -e "my-automation-commands"

my-automation-commands包含您通常要运行的任何内容,

break 0x123
set args "foo" bar 2
r

如果您有一些标准的init脚本,则不是严格意义上的临时文件;)

答案 5 :(得分:1)

嗯,这只是一个评论,而不是一个真正的答案 - 只是想包含一些代码片段。我在bash / Ubuntu Lucid - 对我而言,我遇到的问题几乎与:“GDB has problems with getting commands piped to STDIN - Unix Linux Forum - Fixunix.com”。

基本上,我想实现与以下代码段相同的内容:

$ gdb
GNU gdb (GDB) 7.1-ubuntu
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
(gdb) pwd
Working directory /media/work/dir.
(gdb) 

...除了,我想以某种方式“管道”pwd命令,然后保持gdb打开(如上例所示)。

我在这里尝试了一些建议,唯一适合我的是(echo commands; cat) | gdb语法 - 以及(有点工作)Here Strings - 这是我的结果:

$ echo "pwd" | gdb
(gdb) Hangup detected on fd 0
error detected on stdin


$ echo "pwd" | gdb -x /dev/stdin
GNU gdb (GDB) 7.1-ubuntu
...
/dev/stdin: Invalid argument.
(gdb) Hangup detected on fd 0
error detected on stdin


$ gdb -x <(echo "pwd")
GNU gdb (GDB) 7.1-ubuntu
...
/dev/fd/63: No such file or directory.
(gdb) q


$ gdb -e "pwd"
GNU gdb (GDB) 7.1-ubuntu
...
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
(gdb) q   # nothing happens


$ gdb <<<"pwd"
GNU gdb (GDB) 7.1-ubuntu
...
(gdb) Working directory /media/work/dir.
(gdb) quit    # OK, but autoexits


$ gdb <<<"pwd
> "
GNU gdb (GDB) 7.1-ubuntu
...
(gdb) Working directory /media/work/dir.
(gdb) Working directory /media/work/dir.
(gdb) quit    # with a line break at end, it execs twice, then exits


# the only one OK for my needs - 
# except locks after quit, and needs Ctrl-C
$ (echo "pwd"; cat) | gdb 
GNU gdb (GDB) 7.1-ubuntu
...
(gdb) Working directory /media/work/dir.
(gdb) q
^C 

嗯,希望这有助于某人,
干杯!


编辑:现在至少我知道为什么进程替换不起作用 - 它将使用临时文件描述符,ls无法将其识别为文件(因此gdb肯定无法读取它;此外,引用几乎立即消失,除非进程以某种方式被阻止,如cat 所示 - 请参阅终端日志片段:

$ echo -e "***\n" <(echo "pwd") "\n***\n`cat <(ls -C /dev/fd ; echo; for ix in /dev/fd/*; do irl=$(readlink -f $ix); echo $ix -\> $irl; ls -la $ix 2>&1; ls -la $irl 2>&1; echo '______'; done ; ls -C /dev/fd )`"

***
 /dev/fd/63 
***
0  1  2  3  63

/dev/fd/0 -> /dev/pts/0
lrwx------ 1 user user 64 2010-11-07 21:18 /dev/fd/0 -> /dev/pts/0
crw--w---- 1 user tty 136, 0 2010-11-07 21:18 /dev/pts/0
______
/dev/fd/1 -> /proc/10713/fd/pipe:[236191]
l-wx------ 1 user user 64 2010-11-07 21:18 /dev/fd/1 -> pipe:[236151]
ls: cannot access /proc/10713/fd/pipe:[236191]: No such file or directory
______
/dev/fd/2 -> /dev/pts/0
l-wx------ 1 user user 64 2010-11-07 21:18 /dev/fd/2 -> pipe:[236151]
crw--w---- 1 user tty 136, 0 2010-11-07 21:18 /dev/pts/0
______
/dev/fd/255 -> /proc/10721/fd/255
ls: cannot access /dev/fd/255: No such file or directory
ls: cannot access /proc/10721/fd/255: No such file or directory
______
/dev/fd/3 -> /proc/10725/fd/3
ls: cannot access /dev/fd/3: No such file or directory
ls: cannot access /proc/10725/fd/3: No such file or directory
______
0  1  2  3

此外,向上/向下键无法与(echo commands; cat) | gdb一起使用,因为这就是猫的行为方式;如果我们只运行cat所以它将stdin复制到stdout,我们得到:

$ cat # or `cat -`: and start pressing up/down keys - and get:
^[[A^[[B^[[A^[[B^[[A^[[B^C

您可以尝试使用stty -cooked打开原始字符模式(或关闭缓冲/熟化模式),然后cat将字符写为{{1移动光标 - 遗憾的是,在这种模式下,Ctrl-C不再起作用,因此您将无法以这种方式关闭^[[A ...

答案 6 :(得分:1)

使用bash,您可以创建一个脚本,为用户提供对您正在执行的任何可执行文件的输入:

#!/bin/sh
gdb X <<GDB_INPUT
pwd
run X a b c
quit
GDB_INPUT

答案 7 :(得分:0)

cat F | gdb X应该完全相同。所以你可以使用生成输出和管道的任何东西到gdb而不是cat命令。

我假设你是正确的,gdb从stdin读取。