Como usar strace para depurar processos no Linux

1. Introdução ao strace e seus fundamentos

O strace é uma ferramenta de diagnóstico poderosa para sistemas Linux que intercepta e registra chamadas de sistema (system calls) e sinais recebidos por um processo. Ele permite que você veja exatamente como um programa interage com o kernel do Linux — abrindo arquivos, criando processos, enviando dados pela rede e muito mais.

Os casos de uso típicos do strace incluem:
- Depuração de falhas: descobrir por que um programa não consegue abrir um arquivo de configuração
- Análise de desempenho: identificar chamadas de sistema lentas que causam gargalos
- Diagnóstico de permissões: verificar se um processo tem acesso adequado a arquivos e diretórios
- Compreensão de comportamento: entender como um programa funciona internamente sem acesso ao código-fonte

Para instalar o strace em distribuições Linux:

# Debian/Ubuntu
sudo apt install strace

# RHEL/CentOS/Fedora
sudo yum install strace      # ou sudo dnf install strace

2. Sintaxe básica e primeiros passos

A sintaxe fundamental do strace é simples:

strace [opções] comando [argumentos...]
strace -p PID

Vamos executar o strace em um comando simples:

$ strace ls
execve("/usr/bin/ls", ["ls"], 0x7ffc... ) = 0
brk(NULL)                               = 0x55...
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
...
write(1, "Documentos  Downloads  Music\n", 29) = 29

A saída mostra:
- Syscall: o nome da chamada de sistema (ex.: openat, write)
- Argumentos: os parâmetros passados (ex.: caminhos de arquivos, descritores)
- Valor de retorno: o resultado (ex.: = 0 para sucesso, = -1 para erro)
- Erros: quando o retorno é -1, o strace exibe o código de erro (ex.: ENOENT — arquivo não encontrado)

3. Principais opções de linha de comando

Redirecionar saída para arquivo (-o)

$ strace -o saida.log ls

Filtrar chamadas de sistema específicas (-e trace=)

$ strace -e trace=open,read,write ls

Anexar a um processo em execução (-p)

$ strace -p 1234   # anexa ao processo com PID 1234

Estatísticas de chamadas de sistema (-c)

$ strace -c ls
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 20.00    0.000012           3         4           read
 15.00    0.000009           2         4           openat
 10.00    0.000006           1         5           close
...
------ ----------- ----------- --------- --------- ----------------
100.00    0.000060                    30           total

4. Filtrando e personalizando a saída

Categorias de syscalls

# Apenas chamadas de rede
strace -e trace=network curl http://example.com

# Apenas chamadas de arquivo
strace -e trace=file ls

# Apenas chamadas de processo
strace -e trace=process bash -c "echo hello"

Limitar tamanho de strings (-s)

$ strace -s 64 ls   # exibe no máximo 64 caracteres por string

Modo verboso (-v)

$ strace -v stat /tmp

Exibir strings em hexadecimal (-x)

$ strace -x cat /dev/urandom | head -5

5. Depuração de problemas comuns de processos

Identificando arquivos não encontrados

Quando um programa falha ao abrir um arquivo, o strace mostra o erro ENOENT:

$ strace -e trace=openat ./meu_programa
openat(AT_FDCWD, "/etc/minha_config.conf", O_RDONLY) = -1 ENOENT (No such file or directory)

Rastreando acesso a rede

Para depurar problemas de conexão:

$ strace -e trace=connect,recvfrom,sendto curl http://exemplo.com
connect(3, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("93.184.216.34")}, 16) = 0
sendto(3, "GET / HTTP/1.1\r\nHost: exemplo.com\r\n...", 74, 0, NULL, 0) = 74
recvfrom(3, "HTTP/1.1 200 OK\r\nDate: Mon, 15...", 16384, 0, NULL, NULL) = 1337

Detectando processos bloqueados

Processos travados geralmente ficam presos em chamadas como read ou poll:

$ strace -p 5678
poll([{fd=3, events=POLLIN}], 1, 30000) = 1   # esperando por I/O
read(3, 0x7ffe..., 1024)                      # bloqueado aguardando dados

6. Análise de desempenho com strace

Resumo estatístico com -c

$ strace -c find /usr -name "*.conf" 2>&1 | tail -10
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 35.00    0.045000           2        180           newfstatat
 25.00    0.032000           1        200           getdents64
 20.00    0.025000           3         80           openat
...

Medindo tempo por chamada com -T

$ strace -T ls 2>&1 | grep "openat"
openat(AT_FDCWD, ".", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3 <0.000012>

O valor entre < > mostra o tempo gasto em segundos.

Identificando gargalos

Chamadas lentas de read em disco ou select com timeout longo indicam problemas:

$ strace -T -e trace=read mysql -e "SELECT * FROM tabela" 2>&1 | grep "<0.1"
read(22, "data...", 65536) = 65536 <0.234567>   # 234ms para ler dados

7. Casos práticos de depuração

Caso 1: Script que falha ao ler arquivo de configuração

$ strace -o log.txt ./startup.sh
$ grep "ENOENT" log.txt
openat(AT_FDCWD, "/opt/app/config.ini", O_RDONLY) = -1 ENOENT

Solução: o caminho do arquivo está incorreto ou o arquivo não existe.

Caso 2: Servidor web que não responde na porta 80

$ strace -p $(pgrep nginx) -e trace=bind,listen,accept
bind(3, {sa_family=AF_INET, sin_port=htons(80)}, 16) = -1 EACCES

Solução: o processo não tem permissão para usar portas privilegiadas (executar como root).

Caso 3: Rastreando processos filho com -f

$ strace -f -o fork.log bash -c "ls; echo pronto"

O -f segue forks, permitindo rastrear processos filhos em aplicações multithread ou que criam subprocessos.

8. Boas práticas e limitações

Impacto de desempenho

O strace pode tornar um processo 10x a 100x mais lento, pois cada chamada de sistema é interceptada. Evite usar em produção sem necessidade crítica.

Combinando com outras ferramentas

# Filtrar apenas erros
strace ls 2>&1 | grep "= -1"

# Contar ocorrências de cada syscall
strace -c ls 2>&1 | sort -k4 -n

# Combinar com ltrace para chamadas de biblioteca
ltrace -S ls   # -S mostra syscalls junto com chamadas de biblioteca

Alternativas para cenários avançados

  • perf: análise de desempenho de baixo nível sem overhead extremo
  • sysdig: monitoramento de sistema em tempo real com filtros avançados
  • bpftrace: tracing dinâmico baseado em eBPF para cenários complexos

Referências