Automatización Linux, scripting Bash y herramientas para sysadmins

strace avanzado: filtra syscalls como un profesional y depura procesos sin ruido

#linux#debugging#strace#sysadmin

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íaIncluye
fileopen, stat, read, write, close, unlink…
networksocket, connect, bind, sendto, recvfrom…
processfork, execve, wait4, exit_group, clone…
ipcshmget, semop, msgget…
signalkill, sigaction, sigreturn…
memorymmap, munmap, mprotect, brk…
descSyscalls 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.