为什么 strace 不报告在 execve() 命令之前父 shell fork() 是一个子进程?

为什么 strace 不报告在 execve() 命令之前父 shell fork() 是一个子进程?

strace运行指定的命令直到退出。它拦截并记录进程调用的系统调用以及进程接收的信号。

当在 bash shell 中运行外部命令时,shell 首先fork()是子进程,然后是execve()子进程中的命令。所以我想这strace会报告fork()或类似的东西,例如clone()

但下面的例子表明事实并非如此。为什么在命令之前不strace报告父 shell 是fork()子进程?execve()谢谢。

$ strace -f time
execve("/usr/bin/time", ["time"], [/* 66 vars */]) = 0
brk(0)                                  = 0x84c000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7efe9b2a5000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=141491, ...}) = 0
mmap(NULL, 141491, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7efe9b282000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\320\37\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1840928, ...}) = 0
mmap(NULL, 3949248, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7efe9acc0000
mprotect(0x7efe9ae7b000, 2093056, PROT_NONE) = 0
mmap(0x7efe9b07a000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1ba000) = 0x7efe9b07a000
mmap(0x7efe9b080000, 17088, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7efe9b080000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7efe9b281000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7efe9b27f000
arch_prctl(ARCH_SET_FS, 0x7efe9b27f740) = 0
mprotect(0x7efe9b07a000, 16384, PROT_READ) = 0
mprotect(0x602000, 4096, PROT_READ)     = 0
mprotect(0x7efe9b2a7000, 4096, PROT_READ) = 0
munmap(0x7efe9b282000, 141491)          = 0
write(2, "Usage: time [-apvV] [-f format] "..., 177Usage: time [-apvV] [-f format] [-o file] [--append] [--verbose]
       [--portability] [--format=format] [--output=file] [--version]
       [--quiet] [--help] command [arg...]
) = 177
exit_group(1)                           = ?
+++ exited with 1 +++

答案1

$ strace -f time
execve("/usr/bin/time", ["time"], [/* 66 vars */]) = 0
brk(0)                                  = 0x84c000
...

strace直接调用被跟踪的程序。它不使用 shell 来运行子命令,除非子命令shell 调用。这里事件的大致顺序如下:

  1. shellstrace使用参数“strace”、“-f”、“time”执行。
  2. Strace 启动,解析其命令行,并最终分叉。
  3. 原始(父)strace 进程开始跟踪子strace 进程。
  4. 子 strace 进程/usr/bin/time使用参数“time”执行。
  5. 时间程序启动。

在第1步之后,原来的shell进程处于空闲状态,等待strace退出。它没有主动做任何事情。即使它正在做某事,strace 也不会跟踪它,因此它的活动不会出现在 strace 输出中。

答案2

有问题fork的是启动机制的一部分strace;当追踪开始时它已经结束。

相关内容