execve() 명령을 실행하기 전에 부모 쉘이 자식 프로세스라는 것을 strace가 보고하지 않는 이유는 무엇입니까?

execve() 명령을 실행하기 전에 부모 쉘이 자식 프로세스라는 것을 strace가 보고하지 않는 이유는 무엇입니까?

strace종료할 때까지 지정된 명령을 실행합니다. 프로세스에서 호출한 시스템 호출과 프로세스에서 수신한 신호를 가로채서 기록합니다.

Bash 셸에서 외부 명령을 실행할 때 셸은 fork()먼저 자식 프로세스이고 그 다음에는 execve()자식 프로세스의 명령입니다. 그래서 나는 이것이 strace보고할 fork()것이라고 생각합니다.clone()

그러나 다음 예는 그렇지 않음을 보여준다. 명령 전에 strace상위 쉘이 하위 프로세스로 보고되지 않는 이유는 무엇입니까 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는 추적된 프로그램을 직접 호출합니다. 하위 명령이 없으면 하위 명령을 실행하기 위해 쉘을 사용하지 않습니다.쉘 호출. 대략적인 이벤트 순서는 다음과 같습니다.

  1. 쉘은 strace"strace", "-f" 및 "time" 매개변수를 사용하여 실행됩니다.
  2. Strace가 시작되고 명령줄을 구문 분석한 후 결국 분기됩니다.
  3. 원래(상위) strace 프로세스가 하위 strace 프로세스 추적을 시작합니다.
  4. 하위 strace 프로세스는 /usr/bin/time"time" 매개변수를 사용하여 실행됩니다.
  5. 시간 프로그램이 시작됩니다.

1단계 이후에는 원래 셸 프로세스가 유휴 상태가 되어 strace가 종료될 때까지 기다립니다. 적극적으로 아무것도 하지 않습니다. 무언가를 하고 있더라도 strace는 이를 추적하지 않으므로 해당 활동은 strace 출력에 나타나지 않습니다.

답변2

문제 fork는 시작 메커니즘의 일부입니다 strace. 추적이 시작되면 이미 종료되었습니다.

관련 정보