Tutorial del comando strace de Linux para principiantes (8 ejemplos)

La línea de comandos de Linux ofrece muchas herramientas útiles para los desarrolladores de software. Una de ellas es strace, un comando para rastrear las llamadas y señales del sistema Linux. Los fundamentos de strace, de los que hablaremos en este tutorial mediante algunos ejemplos fáciles de entender.

Pero antes de hacerlo, conviene mencionar que todos los ejemplos de este artículo se han probado en una máquina Ubuntu 22.04 LTS y Debian 11.

El comando strace de Linux

El comando strace en Linux te permite rastrear las llamadas y señales del sistema. A continuación se muestra su sintaxis:

strace [OPTIONS] command

Y así es como lo explica la página man de la herramienta:

       In  the simplest case strace runs the specified command until it exits.
       It intercepts and records the  system  calls  which  are  called  by  a
       process  and  the signals which are received by a process.  The name of
       each system call, its arguments and its return  value  are  printed  on
       standard error or to the file specified with the -o option.

strace is a useful diagnostic, instructional, and debugging tool.  Sys?
tem administrators, diagnosticians and trouble-shooters  will  find  it
invaluable  for  solving problems with programs for which the source is
not readily available since they do not need to be recompiled in  order
to trace them.  Students, hackers and the overly-curious will find that
a great deal can be learned about a system  and  its  system  calls  by
tracing  even  ordinary programs.  And programmers will find that since
system calls and signals are events  that  happen  at  the  user/kernel
interface,  a close examination of this boundary is very useful for bug
isolation, sanity checking and attempting to capture race conditions.

A continuación se presentan algunos ejemplos de tipo Q&A que deberían darte una mejor idea de cómo funciona el comando strace.

Instalación del comando strace

El comando strace no está instalado por defecto en la mayoría de los sistemas, para instalarlo en Debian y Ubuntu, ejecuta este comando:

sudo apt-get install strace

Q1. ¿Cómo se utiliza el comando strace?

El uso básico es sencillo, sólo tienes que ejecutar ‘strace’ con un comando como entrada. Por ejemplo, yo lo he utilizado con el comando ls:

strace ls

Y aquí está la salida producida en mi sistema:

Uso del comando strace en Linux

Q2. ¿Cómo comprender la salida de strace?

Como puedes ver en la captura de pantalla de la sección anterior, el comando strace produce mucha salida. Así que debes saber cómo comprenderla.

Los siguientes extractos de la página del manual proporcionan una explicación precisa:

       Each line in the trace contains the system call name, followed  by  its
       arguments  in parentheses and its return value.  An example from strac?
       ing the command "cat /dev/null" is:

open(«/dev/null», O_RDONLY) = 3

Errors (typically a return value of -1) have the errno symbol and error
string appended.

open(«/foo/bar», O_RDONLY) = -1 ENOENT (No such file or directory)

Signals are printed as signal symbol and decoded siginfo structure.  An
excerpt from stracing and interrupting the command «sleep 666» is:

sigsuspend([] <unfinished …>
— SIGINT {si_signo=SIGINT, si_code=SI_USER, si_pid=…} —
+++ killed by SIGINT +++

Q3. ¿Cómo hacer que strace imprima el puntero de la instrucción?

Hay una opción -i que indica a strace que imprima el puntero de instrucción en el momento de la llamada al sistema.

Por ejemplo:

strace -i ls

Esta es la salida:

Cómo hacer que strace imprima el puntero de la instrucción

Así puedes ver que el puntero de la instrucción se imprimió en cada línea de la salida.

Q4. ¿Cómo hacer que strace imprima la marca de tiempo de cada llamada al sistema?

Existe una opción de línea de comandos -r que indica a strace que muestre una marca de tiempo relativa al entrar en cada llamada al sistema. La página del manual de la herramienta dice que esto registra la diferencia de tiempo entre el comienzo de las sucesivas llamadas al sistema.

Por ejemplo:

strace -r ls

A continuación se muestra la salida producida por este comando:

Cómo hacer que strace imprima la marca de tiempo de cada llamada al sistema

Así puedes ver que se produjo una marca de tiempo relativa al principio de cada línea.

Q5. ¿Cómo anteponer a cada línea de salida la hora del reloj?

Si quieres que cada línea de la salida de strace comience con la hora del reloj, puedes hacerlo utilizando la opción de línea de comandos -t.

Por ejemplo:

strace -t ls

Aquí está la salida de este comando en mi sistema:

Prefijo de tiempo Strace

Así puedes ver que la hora del sistema se imprime al principio de cada línea.

Ten en cuenta que hay otras dos opciones relacionadas que ofrece strace:

-tt         
If given twice, the time printed will include the microseconds.

-ttt
If given thrice, the  time  printed  will  include  the microseconds and the leading portion will
be printed as the number of seconds since the epoch.

Q6. ¿Cómo hacer que strace muestre el tiempo empleado en las llamadas al sistema?

Esto se puede conseguir utilizando la opción de línea de comandos -T.

Por ejemplo:

strace -T ls

La siguiente es la salida:

Mostrar los tiempos de las llamadas a funciones con strace

Así puedes ver que el tiempo empleado en las llamadas al sistema se imprime al final de cada línea.

Q7. ¿Cómo hacer que strace imprima un resumen en lugar de la salida habitual?

La salida de la línea de comandos -c se puede utilizar si quieres que la herramienta produzca un resumen.

Por ejemplo, el siguiente comando

strace -c ls

produjo esta salida en mi sistema:

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 93.66    0.000133           5        28           write
  6.34    0.000009           1        11           close
  0.00    0.000000           0         7           read
  0.00    0.000000           0        10           fstat
  0.00    0.000000           0        17           mmap
  0.00    0.000000           0        12           mprotect
  0.00    0.000000           0         1           munmap
  0.00    0.000000           0         3           brk
  0.00    0.000000           0         2           rt_sigaction
  0.00    0.000000           0         1           rt_sigprocmask
  0.00    0.000000           0         2           ioctl
  0.00    0.000000           0         8         8 access
  0.00    0.000000           0         1           execve
  0.00    0.000000           0         2           getdents
  0.00    0.000000           0         2         2 statfs
  0.00    0.000000           0         1           arch_prctl
  0.00    0.000000           0         1           set_tid_address
  0.00    0.000000           0         9           openat
  0.00    0.000000           0         1           set_robust_list
  0.00    0.000000           0         1           prlimit64
------ ----------- ----------- --------- --------- ----------------
100.00    0.000142                   120        10 total

Así que puedes ver que el resumen te da una idea de cuántas llamadas se hicieron por cada llamada al sistema, así como información relacionada con el tiempo de cada llamada al sistema.

También te podría gustar...