strace 中的系统调用

发布于 2025-01-08 21:39:28 字数 567 浏览 1 评论 0原文

我在某个程序 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。在这种情况下,我真的从来没有真正拥有过我想知道这些文件描述符 3456 代表什么?有没有办法找出它们是什么?我知道 3 代表 stderr

I called strace on some program A which forks two child programs: B and C.

In strace, I have the following 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

I am trying to rewrite the program A in C. In that case, I really never really have to know what those file descriptors 3,4,5 and 6 stand for, do I? Is there a way to find out what they are? I know 3 is for stderr.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

深居我梦 2025-01-15 21:39:28

您应该尝试使用 -f 标志再次运行 strace,以便它遵循分叉。目前您只能看到顶级进程在做什么,而无法看到子进程在做什么。

顶层进程创建两个管道。管道被程序用来相互通信。第一个管道的读取端位于 fd 3 上,写入端位于 fd 4 上。第二个管道的读取端位于 fd 5 上,写入端位于 fd 6 上。

由于顶层程序在调用两个 fd 后关闭了所有四个 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()

You should try running strace again with the -f flag so that it follows forks. At the moment you can only see what your top-level process does, you can't see what your child processes do.

The top-level process creates two pipes. Pipes are used by programs to communicate with each other. The first pipe has the read end on fd 3 and the write end on fd 4. The second pipe has the read end on fd 5 and the write end on fd 6.

Since the top-level program closes all four fds after calling the two child programs, it looks like they are just used internally by the child programs (who both get copies of the fds). This is unusually becuase normally I would expect to see the parent process keep one en open in orfer to communicate with the child. It looks like your trace is missing some important information about what happened to the fds after each fork.

This is what I would expect to see if a progcess was opening pipes inorder to capture stdout from a child, for example:

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()
听,心雨的声音 2025-01-15 21:39:28

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

0 ist STDIN, 1 is STDOUT and 2 is STDERR. All higher numbers are up to the application. In this case I suspect they are used to capture stdout/stderr of the freshly forked programs. This would mean that "wc" probably runs with its stdout connected to fd 3 and stderr to fd 4, so the main application can could the output of wc.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文