我在某个程序strace
上调用了A
,该程序生成了两个子程序:B
和C
。
在strace
中,我有以下syscalls
:
pipe[([3,4]) = 0
pipe([5,6]) = 0
fork(wc) = 7135
fork (gnetcat) = 7136
close(3) = 0
close(5) = 0
close(4) = 0
close(6) = 0
wait4(-1, NULL, 0, NULL) = 7136
wait4(-1, NUKLL, 0, NULL) = 7135
我正在尝试重写C中的程序A
。在这种情况下,我真的不必知道那些文件描述符3
,4
,5
和6
代表,是吗?有没有办法找出它们是什么?我知道3
适用于stderr
。
答案 0 :(得分:1)
你应该尝试使用-f标志再次运行strace,以便它跟随分叉。目前,您只能看到您的顶级流程所做的事情,您无法看到您的子流程执行的操作。
顶级流程会创建两个管道。程序使用管道相互通信。第一个管道的读取端在fd 3上,写入端在fd 4上。第二个管道的读取端在fd 5上,写入端在fd 6上。
由于顶层程序在调用两个子程序后关闭了所有四个fds,看起来它们只是由子程序在内部使用(两者都获得了fds的副本)。这通常是不正常的,因为我希望看到父进程保持一个开放状态,或者与孩子沟通。看起来你的踪迹缺少一些关于每个分支后fds发生了什么的重要信息。
这是我期望看到如果一个进程打开管道以便从一个孩子捕获stdout,例如:
parent_pid: pipe[3,4]
parent_pid: clone() = child_pid
parent_pid: close(4)
child_pid: dup(4,1)
child_pid: close(4)
child_pid: close(3)
child_pid: execve(some program)
child_pid: write(1)
parent_pid: read(3)
parent_pid: wait(child_pid)
child_pid: exit()
答案 1 :(得分:0)
0是STDIN,1是STDOUT,2是STDERR。所有更高的数字都取决于应用程序。在这种情况下,我怀疑他们习惯于捕获新分叉程序的stdout / stderr。这意味着“wc”可能在其stdout连接到fd 3和stderr到fd 4的情况下运行,因此主应用程序可以输出wc。