Por que o Strace não relata que o shell pai () é um processo filho antes de um comando execve ()?

1

strace executa um comando especificado até sair. Ele intercepta e registra as chamadas do sistema que são chamadas por um processo e os sinais recebidos por um processo.

Ao executar um comando externo em um bash shell, o shell em primeiro lugar fork() um processo filho e, em seguida, execve() o comando no processo filho. Então eu acho que strace irá reportar fork() ou algo similar como clone()

Mas o exemplo a seguir mostra que não. Por que não strace informa que o shell pai fork() do processo filho antes de execve() o comando? Obrigado.

$ 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, "7ELF
$ 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, "7ELF%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%>%pre%%pre%%pre%%pre%0%pre%%pre%%pre%%pre%%pre%"..., 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 +++
%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%>%pre%%pre%%pre%%pre%0%pre%%pre%%pre%%pre%%pre%"..., 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 +++
    
por Tim 03.03.2016 / 00:26

2 respostas

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

Strace invoca diretamente o programa a ser rastreado. Ele não usa o shell para executar comandos filhos, a menos que o comando filho seja uma chamada de shell. A sequência aproximada de eventos aqui é a seguinte:

  1. O shell executa strace com argumentos "strace", "-f", "time".
  2. Strace inicia, analisa sua linha de comando e, eventualmente, bifurca-se.
  3. O processo strace original (pai) começa a rastrear o processo de strace filho.
  4. O processo de strace filho executa /usr/bin/time com o argumento "time".
  5. O programa de tempo é iniciado.

Após o passo 1, o processo original do shell está ocioso, aguardando a saída do strace. Não está fazendo nada ativamente. E mesmo se estivesse fazendo algo, não está sendo rastreado por strace, então sua atividade não apareceria na saída strace.

    
por 03.03.2016 / 01:47
4

O fork em questão faz parte do mecanismo que inicia strace ; concluiu no momento em que o rastreamento começa.

    
por 03.03.2016 / 00:49