strace avanzado: filtra syscalls como un profesional y depura procesos sin ruido
El problema con strace sin filtros
Si alguna vez ejecutaste strace sin opciones, viste esto:
strace ls
Cientos de líneas por segundo. El 95% son llamadas a read, write, mmap que no te interesan. Encontrar el error real entre todo ese ruido es como buscar una aguja en un pajar en llamas.
strace tiene un sistema de filtrado mucho más potente de lo que parece. No es solo -e trace=file. Hay categorías, exclusiones, estadísticas y seguimiento de procesos hijos.
Filtros básicos con -e trace
# Solo syscalls de archivos (open, read, write, stat, close...)
strace -e trace=file ls
# Solo syscalls de red (socket, connect, sendto, recvfrom...)
strace -e trace=network curl -s example.com > /dev/null
# Solo syscalls de procesos (fork, execve, wait4, exit...)
strace -e trace=process firefox --headless
Todas las categorías disponibles
| Categoría | Incluye |
|---|---|
file | open, stat, read, write, close, unlink… |
network | socket, connect, bind, sendto, recvfrom… |
process | fork, execve, wait4, exit_group, clone… |
ipc | shmget, semop, msgget… |
signal | kill, sigaction, sigreturn… |
memory | mmap, munmap, mprotect, brk… |
desc | Syscalls con file descriptors |
Excluir ruido con !
A veces es más fácil decir “todo menos esto”:
# Todas las syscalls excepto read y write (las más ruidosas)
strace -e trace=\!read,write ls
# Todo menos llamadas de memoria (mmap, munmap, brk)
strace -e trace=\!memory nginx -t
El signo ! niega el filtro. Útil cuando no sabes qué estás buscando exactamente pero sí sabes lo que NO te interesa.
Estadísticas con -c
En vez de ver cada syscall, pedí un resumen al final:
strace -c ls
Salida típica:
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
45.23 0.000234 12 19 read
23.67 0.000122 11 11 1 openat
12.45 0.000064 8 8 close
8.12 0.000042 14 3 write
...
Te dice cuántas veces se llamó cada syscall, cuánto tiempo tomó y cuántos errores hubo. Si openat tiene 11 llamadas pero 1 error, ahí hay algo raro.
Ordenar estadísticas
# Por tiempo total (default)
strace -c ls
# Por nombre de syscall (alfabético)
strace -c -S name ls
# Por cantidad de llamadas
strace -c -S calls ls
Seguir procesos hijos con -f
Si el programa lanza otros procesos, -f los sigue:
strace -f -e trace=network nginx
Verás las syscalls de red del proceso principal y de cada worker. Sin -f, solo ves al padre y te pierdes lo que hacen los hijos.
Para diferenciar quién hace qué, agregá -ff:
strace -ff -o /tmp/nginx_trace nginx
Esto crea archivos separados: nginx_trace.1234 (proceso padre), nginx_trace.1235 (worker 1), etc.
Filtro por descriptor de archivo
Si sabés qué file descriptor te interesa, filtrá por él:
# Solo syscalls que usan el fd 3 (el primero que abre el proceso)
strace -e trace=read,write -e read=3,write=3 cat /etc/hosts
Combinar filtros
Puedes apilar múltiples -e:
# Syscalls de archivo Y de red, pero sin read ni write
strace -e trace=file,network -e trace=\!read,write wget example.com
El 90% de las veces que uso strace es con -e trace=file o -e trace=network. Pero cuando el problema es esquivo, las estadísticas (-c) y el seguimiento de forks (-f) son lo que te salva.