C++ 如何传递参数并将标准输入从文件重定向到在 gdb 中运行的程序?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4521015/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 15:38:24  来源:igfitidea点击:

How to pass arguments and redirect stdin from a file to program run in gdb?

c++debugginggdb

提问by rubenvb

I usually run a program as :

我通常运行一个程序:

./a.out arg1 arg2 <file

I would like to debug it using gdb.

我想使用 gdb 调试它。

I am aware of the set argsfunctionality, but that only works from the gdb prompt.

我知道该set args功能,但只能在 gdb 提示符下使用。

采纳答案by moinudin

Pass the arguments to the runcommand from within gdb.

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

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

回答by rubenvb

You can do this:

你可以这样做:

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

The magic bit being --args.

神奇的一点是--args

Just type runin the gdb command console to start debugging.

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

回答by unkulunkulu

If you want to have bare runcommand in gdbto execute your program with redirections and arguments, you can use set args:

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

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

I was unable to achieve the same behaviour with --argsparameter, gdbfiercely escapes the redirections, i.e.

我无法用--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
...

This one actually redirects the input of gdb itself, not what we really want here

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

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

回答by Ehsan

Start GDB on your project.

在您的项目上启动 GDB。

  1. Go to project directory, where you've already compiled the project executable. Issue the command gdb and the name of the executable as below:

    gdb projectExecutablename

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

    gdb 项目可执行文件名

This starts up gdb, prints the following: GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.04) 7.11.1 Copyright (C) 2016 Free Software Foundation, Inc. ................................................. Type "apropos word" to search for commands related to "word"... Reading symbols from projectExecutablename...done. (gdb)

这将启动 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. Before you start your program running, you want to set up your breakpoints. The break command allows you to do so. To set a breakpoint at the beginning of the function named main:

    (gdb) b main

  2. Once you've have the (gdb) prompt, the run command starts the executable running. If the program you are debugging requires any command-line arguments, you specify them to the run command. If you wanted to run my program on the "xfiles" file (which is in a folder "mulder" in the project directory), you'd do the following:

    (gdb) r mulder/xfiles

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

    (gdb) b 主

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

    (gdb) r mulder/xfiles

Hope this helps.

希望这可以帮助。

Disclaimer: This solution is not mine, it is adapted from https://web.stanford.edu/class/cs107/guide_gdb.htmlThis short guide to gdb was, most probably, developed at Stanford University.

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

回答by Tino

Wouldn't it be nice to just type debugin front of any command to be able to debug it with gdbon shell level?

debug在任何命令前面输入以便能够gdb在 shell 级别调试它不是很好吗?

Below it this function. It even works with following:

在它下面这个函数。它甚至适用于以下内容:

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

This is a call where you cannot control anything, everything is variable, can contain spaces, linefeeds and shell metacharacters. In this example, in, out, two, and threeare arbitrary other commands which consume or produce data which must not be harmed.

这是一个你无法控制任何东西的调用,一切都是可变的,可以包含空格、换行符和 shell 元字符。在此示例中inouttwo、 和three是任意其他命令,它们使用或生成不得损坏的数据。

Following bashfunction invokes gdbnearly cleanly in such an environment [Gist]:

以下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 "$@";
}

Example on how to apply this: Just type debugin front:

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

Before:

前:

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

After:

后:

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

That's it. Now it's an absolute no-brainer to debug with gdb. Except for a few details or more:

就是这样。现在使用gdb. 除了一些细节或更多:

  • gdbdoes not quit automatically and hence keeps the IO redirection open until you exit gdb. But I call this a feature.

  • You cannot easily pass argv0to the program like with exec -a arg0 command args. Following should do this trick: After exec-wrapperchange "execto "exec -a \"\${DEBUG_ARG0:-\$1}\".

  • There are FDs above 1000 open, which are normally closed. If this is a problem, change 0<&1000 1>&1001 2>&1002to read 0<&1000 1>&1001 2>&1002 1000<&- 1001>&- 1002>&-

  • You cannot run two debuggers in parallel. There also might be issues, if some other command consumes /dev/tty(or STDIN). To fix that, replace /dev/ttywith "${DEBUGTTY:-/dev/tty}". In some other TTY type tty; sleep infand then use the printed TTY (i. E. /dev/pts/60) for debugging, as in DEBUGTTY=/dev/pts/60 debug command arg... That's the Power of Shell, get used to it!

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

  • 您不能argv0exec -a arg0 command args. 以下应该执行此技巧:exec-wrapper更改"exec"exec -a \"\${DEBUG_ARG0:-\$1}\".

  • 有1000以上开的FD,常闭。如果这是一个问题,请更改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... 这就是壳牌的力量,习惯它!

Function explained:

功能说明:

  • 1000<&0 1001>&1 1002>&2moves away the first 3 FDs
    • This assumes, that FDs 1000, 1001 and 1002 are free
  • 0</dev/tty 1>/dev/tty 2>&0restores the first 3 FDs to point to your current TTY. So you can control gdb.
  • /usr/bin/gdb -q -nx -nwruns gdbinvokes gdbon shell
  • -ex 'set exec-wrapper /bin/bash -c "exec 0<&1000 1>&1001 2>&1002 \"\$@\""creates a startup wrapper, which restores the first 3 FDs which were saved to 1000 and above
  • -ex rstarts the program using the exec-wrapper
  • --args "$@"passes the arguments as given
  • 1000<&0 1001>&1 1002>&2移开前 3 个 FD
    • 这假设 FD 1000、1001 和 1002 是免费的
  • 0</dev/tty 1>/dev/tty 2>&0恢复前 3 个 FD 以指向您当前的 TTY。所以你可以控制gdb
  • /usr/bin/gdb -q -nx -nw在 shell 上运行gdb调用gdb
  • -ex 'set exec-wrapper /bin/bash -c "exec 0<&1000 1>&1001 2>&1002 \"\$@\""创建一个启动包装器,它恢复保存到 1000 及以上的前 3 个 FD
  • -ex r使用 exec-wrapper
  • --args "$@"传递给定的参数

Wasn't that easy?

那不是很容易吗?