【问题标题】:Syscalls in stracestrace 中的系统调用
【发布时间】:2012-02-22 23:10:55
【问题描述】:

我在某个程序 A 上调用了 strace,它分叉了两个子程序: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。在这种情况下,我真的不需要知道那些文件描述符 3,4,56 代表什么,做一世?有没有办法找出它们是什么?我知道3 代表stderr

【问题讨论】:

    标签: process pipe system-calls strace


    【解决方案1】:

    您应该尝试使用 -f 标志再次运行 strace,以便它跟随分叉。目前你只能看到你的顶级进程做了什么,你看不到你的子进程做了什么。

    顶级进程创建两个管道。管道被程序用来相互通信。第一个管道在 fd 3 上有读端,在 fd 4 上有写端。第二个管道在 fd 5 上有读端,在 fd 6 上有写端。

    由于顶级程序在调用两个子程序后关闭了所有四个 fd,看起来它们只是由子程序内部使用(它们都获得 fd 的副本)。这是不寻常的,因为通常我希望看到父进程保持打开状态以与子进程进行通信。看起来您的跟踪缺少一些关于每次分叉后 fds 发生了什么的重要信息。

    如果进程打开管道以便从子级捕获标准输出,我希望看到这种情况,例如:

    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()
    

    【讨论】:

      【解决方案2】:

      0 是 STDIN,1 是 STDOUT,2 是 STDERR。所有更高的数字都取决于应用程序。在这种情况下,我怀疑它们用于捕获新分叉程序的标准输出/标准错误。这意味着“wc”可能在其 stdout 连接到 fd 3 和 stderr 到 fd 4 的情况下运行,因此主应用程序可以输出 wc。

      【讨论】:

      • 为什么文件描述符是空文件呢?他们将如何处理数据?为了能够在 C 中实现它,4 和所有更高的文件描述符的含义真的无关紧要,不是吗?我可以将它们传递到管道中,对吗?
      • 文件描述符是(打开的)管道的表示。您需要一个 fd 才能识别您正在写入的位置。 - 由于您的 strace 不包含 read() 或 write() ,因此似乎没有通过这些管道发送任何内容,这有点奇怪。 -- 但是“fork(program)”建议你编辑它:-)
      猜你喜欢
      • 2020-05-18
      • 1970-01-01
      • 2016-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-01
      相关资源
      最近更新 更多