简体   繁体   English

gdb - 使用管道调试

[英]gdb - debugging with pipe

Say I have a two programs named blah and ret .假设我有两个名为blahret 的程序。 I want to debug blah program which receives input from ret program via I/O redirection.我想调试通过 I/O 重定向从ret程序接收输入的blah程序。 How do I debug the blah program in the following case using gdb?在以下情况下如何使用 gdb 调试blah程序?

bash> ret | blah 

At first, you may run the program and debug it by pid.首先,您可以运行该程序并通过pid进行调试。 This solution, of course, doesn't cover all cases.当然,此解决方案并未涵盖所有情况。

Another approach is to use Linux capabilities for inter-process communication.另一种方法是使用 Linux 功能进行进程间通信。 In short, you redirect the output of ret to a FIFO special file ("named pipe") and then read from that FIFO via debugger.简而言之,您将ret的输出重定向到一个 FIFO 特殊文件(“命名管道”),然后通过调试器从该 FIFO 中读取。 Here's how it's done.这是它的完成方式。 From bash, run:从 bash 运行:

mkfifo foo

This creates a special file in your directory that will serve as a named pipe .这会在您的目录中创建一个特殊文件,用作命名管道 When you write text to this file (using the same syntax echo "Hello" >foo ), the writing program will block until someone reads the data from the file ( cat <foo , for instance).当您将文本写入此文件时(使用相同的语法echo "Hello" >foo ),写入程序将阻塞,直到有人从文件中读取数据(例如cat <foo )。 In our case, a gdb-controlled process will read from this file.在我们的例子中,一个 gdb 控制的进程将从这个文件中读取。

After you created a fifo, run from bash:创建 fifo 后,从 bash 运行:

ret > foo &   # ampersand because it may block as nobody is reading from foo
gdb blah

Then, in gdb prompt, run然后,在 gdb 提示符下,运行

run <foo

And get the desired effect.并得到想要的效果。 Note that you can't read the data from the fifo (as well as from a usual pipe) twice: when you've read all the data, the blah process dies and you should repeat the command writing to foo (you may do it from the other shell window).请注意,您不能从 fifo(以及从普通管道)读取数据两次:当您读取所有数据后, blah进程就会终止,您应该重复写入 foo 的命令(您可以这样做从另一个外壳窗口)。

When you're done, remove the fifo with rm foo (or place it into the directory where it will automatically be removed upon system restart, such as /tmp ).完成后,使用rm foo删除fifo(或将其放入系统重新启动时将自动删除的目录中,例如/tmp )。

GDB's run command uses bash to perform redirection. GDB 的run命令使用bash来执行重定向。 A simple way to achieve the equivalent of ret | blah一个简单的方法来实现等价于ret | blah ret | blah is to use bash's process substitution feature. ret | blah是使用bash的进程替换功能。

$ gdb blah
...
(gdb) run < <(ret)

Explanation: bash substitutes <(ret) with something like /dev/fd/123 , which is a file descriptor of the stdout of ret .说明:bash 用/dev/fd/123类的东西替换<(ret) ,它是ret的标准输出的文件描述符。 We can use that fd similarly to a named FIFO as described in the other answer, except that we don't have to manually create it ourselves, nor worry about the lifetime of the ret process.我们可以使用该 fd 类似于另一个答案中描述的命名 FIFO,不同之处在于我们不必自己手动创建它,也不必担心ret进程的生命周期。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM