gdb - 使用管道进行调试

Posted

技术标签:

【中文标题】gdb - 使用管道进行调试【英文标题】:gdb - debugging with pipe 【发布时间】:2010-11-30 04:28:18 【问题描述】:

假设我有一个名为 blahret 的程序。我想调试通过 I/O 重定向从 ret 程序接收输入的 blah 程序。以下情况下如何使用gdb调试blah程序?

bash> ret | blah 

【问题讨论】:

这是否不同于:***.com/questions/4521015/… 【参考方案1】:

首先,您可以运行程序并通过 pid 对其进行调试。当然,此解决方案并不涵盖所有情况。

另一种方法是使用 Linux 功能进行进程间通信。简而言之,您将ret 的输出重定向到一个FIFO 特殊文件(“命名管道”),然后通过调试器从该FIFO 中读取。这是它是如何完成的。从 bash 运行:

mkfifo foo

这会在您的目录中创建一个特殊文件,用作命名管道。当您将文本写入此文件时(使用相同的语法echo "Hello" >foo),写入程序将阻塞,直到有人从文件中读取数据(例如cat <foo)。在我们的例子中,一个 gdb 控制的进程将从这个文件中读取。

创建 fifo 后,从 bash 运行:

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

然后,在 gdb 提示符下,运行

run <foo

并得到想要的效果。请注意,您不能从 fifo(以及通常的管道)读取数据两次:当您读取所有数据时,blah 进程将终止,您应该重复写入 foo 的命令(您可以从另一个 shell 窗口执行)。

完成后,使用rm foo 删除fifo(或将其放入系统重启后会自动删除的目录,例如/tmp)。

【讨论】:

如果您能负担得起磁盘空间,您也可以将其通过管道传输到常规文件 foo,而不是 FIFO foo(为您节省一个命令:)。 常规文件和 FIFO/管道对于 read() 有不同的语义。如果您在常规文件中达到 EOF,则 read() 返回的读取字节数可能少于指定的字节数。如果从 FIFO/管道读取,read() 会阻塞,直到指定的字节数到达,或者写入管道的进程已经退出。【参考方案2】:

GDB 的run 命令使用bash 执行重定向。实现ret | blah 等效的一种简单方法是使用bash 的process substitution 功能。

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

解释:bash 将&lt;(ret) 替换为/dev/fd/123,这是ret 的标准输出的文件描述符。我们可以使用该 fd 类似于另一个答案中描述的命名 FIFO,除了我们不必自己手动创建它,也不必担心 ret 进程的生命周期。

【讨论】:

以上是关于gdb - 使用管道进行调试的主要内容,如果未能解决你的问题,请参考以下文章

使用gdb调试

如何用gdb调试erlang运行期

使用GDB进行嵌入式远程调试

在vscode中使用gdb调试

linux 下面怎么用gdb调试多个.c文件?

使用GDB和GEF进行调试