Fundamentos do strace - Rastreando Chamadas de Sistema para Troubleshooting

Fundamentos do strace - Rastreando Chamadas de Sistema para Troubleshooting

O que é o strace?

strace é uma ferramenta de depuração que registra e exibe as chamadas de sistema (requisições ao kernel) e sinais emitidos por um processo em tempo real. Ele expõe interações brutas como abertura de arquivos, estabelecimento de conexões de rede e criação de processos filhos -- tudo visível mesmo sem o código-fonte.

Quando usar o strace

  • Nenhuma saída útil nos logs, ou mensagens de erro que não revelam nada
  • Incerteza sobre qual arquivo de configuração a aplicação está realmente lendo
  • "Permission denied" ocorre mas você não sabe qual caminho está sendo rejeitado
  • Conexões de rede falham por razões obscuras

Por que o strace ajuda no troubleshooting?

Toda aplicação, por mais complexa que seja, acessa hardware e recursos do SO através de chamadas de sistema do kernel. O strace monitora exatamente essa interface -- portanto, mesmo sem código-fonte, você pode ver precisamente o que um processo tentou fazer e por que falhou.

Erros no nível do kernel como errno: ENOENT (arquivo não encontrado), errno: EACCES (permissão negada) e errno: ECONNREFUSED (conexão recusada) aparecem diretamente na saída do strace. Mesmo quando uma aplicação registra apenas "Ocorreu um erro", o strace leva você à causa raiz.

Como instalar o strace?

A maioria das distribuições inclui o strace por padrão. Instale-o com seu gerenciador de pacotes se estiver ausente.

# Ubuntu / Debian
sudo apt install strace

# RHEL / CentOS / Fedora
sudo dnf install strace

Verifique a instalação:

strace --version
strace -- version 6.x
...

Uso Básico

Rastrear um comando diretamente

strace ls /tmp

Uma sequência de saída aparece. As últimas linhas mostram o status de saída.

execve("/bin/ls", ["ls", "/tmp"], 0x7fff... /* 20 vars */) = 0
brk(NULL)                               = 0x55d3e...
...
openat(AT_FDCWD, "/tmp", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3
...
+++ exited with 0 +++

Anexar a um processo em execução

sudo strace -p PID

Encontre o PID com ps aux ou pgrep:

# Encontrar PID pelo nome do processo
pgrep nginx

# Anexar
sudo strace -p 12345

Anexar com -p geralmente requer privilégios root (não é necessário para seus próprios processos). Anexar a um serviço em produção pode afetar seu desempenho.

Rastrear processos filhos também

Para serviços multi-processo, -f é essencial:

strace -f -p PID

Como filtrar chamadas de sistema específicas?

A saída padrão é volumosa. Use -e trace= para restringir o foco:

strace -e trace=openat ls /tmp

Filtros comuns:

Filtro Rastreia
openat Abertura de arquivos
read,write Leituras e escritas
connect Conexões de rede
execve Execução de processos
file Todas as chamadas de arquivo
network Todas as chamadas relacionadas a rede
# Rastrear apenas acesso a arquivos
strace -e trace=file command

# Rastrear apenas conexoes de rede
strace -e trace=network command

Como ler a saída do strace?

O formato básico é:

syscall_name(args...) = return_value

Sucesso:

openat(AT_FDCWD, "/etc/hosts", O_RDONLY) = 3

Falha -- ENOENT (arquivo não encontrado):

openat(AT_FDCWD, "/etc/myapp.conf", O_RDONLY) = -1 ENOENT (No such file or directory)

Falha -- EACCES (permissão negada):

openat(AT_FDCWD, "/root/secret", O_RDONLY) = -1 EACCES (Permission denied)

Lendo o valor de retorno

  • = 0 ou maior: sucesso (número do file descriptor, bytes processados, etc.)
  • = -1: falha. O token errno que segue nomeia a razão específica.

Padrões Comuns de Troubleshooting

Padrão 1: Aplicação não lendo seu arquivo de configuração

strace -e trace=openat myapp 2>&1 | grep "ENOENT"
openat(AT_FDCWD, "/etc/myapp/config.yaml", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/home/user/.myapp/config.yaml", O_RDONLY) = -1 ENOENT (No such file or directory)

Você pode ver exatamente quais caminhos a aplicação tenta acessar.

Padrão 2: Identificando a causa de Permission denied

strace -e trace=openat myapp 2>&1 | grep "EACCES"
openat(AT_FDCWD, "/var/run/myapp.pid", O_WRONLY|O_CREAT) = -1 EACCES (Permission denied)

O caminho exato sendo rejeitado se torna visível.

Padrão 3: Diagnosticando uma falha de conexão

strace -e trace=network myapp 2>&1 | grep -E "connect|ECONNREFUSED"
connect(3, {sa_family=AF_INET, sin_port=htons(5432), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 ECONNREFUSED (Connection refused)

Confirme se o endereço e a porta correspondem às suas expectativas.

Padrão 4: Salvar saída para análise posterior

strace -o /tmp/trace.log -f myapp
grep ENOENT /tmp/trace.log

-o redireciona a saída para um arquivo, mantendo o stderr limpo e facilitando o uso de grep ou less posteriormente.

Referência Prática de Opções

Opção Efeito
-p PID Anexar a um processo em execução
-f Rastrear processos filhos criados por fork/clone
-e trace= Filtrar chamadas de sistema específicas
-o file Escrever saída em arquivo em vez de stderr
-t Prefixar cada linha com horário
-tt Timestamps com precisão de microssegundos
-T Mostrar tempo gasto em cada chamada de sistema
-c Exibir resumo de contagens, tempos e erros
-s 256 Definir comprimento máximo de exibição de string (padrão: 32)
-q Suprimir mensagens "Attaching..."

Verificando estatísticas com -c

strace -c ls /tmp
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 35.14    0.000147          14        10           mmap
 18.42    0.000077          11         7           openat
 ...
------ ----------- ----------- --------- --------- ----------------
100.00    0.000418                    48         2 total

Obtenha uma visão rápida de quais chamadas estão consumindo mais tempo.

Próximas Leituras