假设我有一个名为 blah 和 ret 的两个程序 . 我想调试 blah 程序,它通过I / O重定向从 ret 程序接收输入 . 在以下情况下如何使用gdb调试 blah 程序?
bash> ret | blah
首先,您可以运行该程序并通过pid进行调试 . 当然,该解决方案并未涵盖所有情况 .
另一种方法是使用Linux功能进行进程间通信 . 简而言之,您将 ret 的输出重定向到FIFO特殊文件("named pipe"),然后通过调试器从该FIFO读取 . 这里完成了's how it' . 从bash运行:
ret
mkfifo foo
这将在您的目录中创建一个特殊文件,用作命名管道 . 当您将文本写入此文件时(使用相同的语法 echo "Hello" >foo ),写入程序将阻塞,直到有人从文件中读取数据(例如 cat <foo ) . 在我们的例子中,gdb控制的进程将从该文件中读取 .
echo "Hello" >foo
cat <foo
创建fifo后,从bash运行:
ret > foo & # ampersand because it may block as nobody is reading from foo gdb blah
然后,在gdb提示符下运行
run <foo
并获得预期的效果 . 请注意,您可以't read the data from the fifo (as well as from a usual pipe) twice: when you'读取所有数据, blah 进程死亡,您应该重复写入foo的命令(您可以从其他shell窗口执行此操作) .
blah
完成后,使用 rm foo 删除fifo(或将其放入系统重启时自动删除的目录,例如 /tmp ) .
rm foo
/tmp
GDB的 run 命令使用 bash 来执行重定向 . 实现 ret | blah 等效的简单方法是使用bash的process substitution功能 .
run
bash
ret | blah
$ gdb blah ... (gdb) run < <(ret)
说明:bash用 /dev/fd/123 替换 <(ret) ,这是 ret 标准输出的文件描述符 . 我们可以使用与其他答案中描述的命名FIFO类似的fd,除了我们不必自己手动创建它,也不用担心 ret 进程的生命周期 .
/dev/fd/123
<(ret)
2 回答
首先,您可以运行该程序并通过pid进行调试 . 当然,该解决方案并未涵盖所有情况 .
另一种方法是使用Linux功能进行进程间通信 . 简而言之,您将
ret
的输出重定向到FIFO特殊文件("named pipe"),然后通过调试器从该FIFO读取 . 这里完成了's how it' . 从bash运行:这将在您的目录中创建一个特殊文件,用作命名管道 . 当您将文本写入此文件时(使用相同的语法
echo "Hello" >foo
),写入程序将阻塞,直到有人从文件中读取数据(例如cat <foo
) . 在我们的例子中,gdb控制的进程将从该文件中读取 .创建fifo后,从bash运行:
然后,在gdb提示符下运行
并获得预期的效果 . 请注意,您可以't read the data from the fifo (as well as from a usual pipe) twice: when you'读取所有数据,
blah
进程死亡,您应该重复写入foo的命令(您可以从其他shell窗口执行此操作) .完成后,使用
rm foo
删除fifo(或将其放入系统重启时自动删除的目录,例如/tmp
) .GDB的
run
命令使用bash
来执行重定向 . 实现ret | blah
等效的简单方法是使用bash的process substitution功能 .说明:bash用
/dev/fd/123
替换<(ret)
,这是ret
标准输出的文件描述符 . 我们可以使用与其他答案中描述的命名FIFO类似的fd,除了我们不必自己手动创建它,也不用担心ret
进程的生命周期 .