Syscalls in strace

时间:2012-02-22 23:10:56

标签: process pipe system-calls strace

我在某个程序strace上调用了A,该程序生成了两个子程序:BC

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。在这种情况下,我真的不必知道那些文件描述符3456代表,是吗?有没有办法找出它们是什么?我知道3适用于stderr

2 个答案:

答案 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。