¿Cómo se debe usar strace?

273

Un colega me dijo una vez que la última opción cuando todo no pudo depurar en Linux era usar strace .

Traté de aprender la ciencia detrás de esta herramienta extraña, pero no soy un administrador de sistemas y realmente no obtuve resultados.

Entonces,

  • ¿Qué es exactamente y qué hace?
  • ¿Cómo y en qué casos se debe usar?
  • ¿Cómo debe entenderse y procesarse la salida?

En resumen, en palabras simples , ¿cómo funciona esto?

e-satis
fuente
2
strace -p <pid> le dirá lo que está sucediendo ahora con su programa ..... rápido y fácil que GDB
ernesto
1
Personalmente me parece man stracemuy fácil de leer y útil. (PS no sabía sobre strace antes de ayer y no era un experto en Linux)
Alexander Malakhov
1
"strace es un trazador de llamadas del sistema": solo muestra cómo se llaman las funciones del núcleo (con sus argumentos) como resultado de su programa.
Pithikos

Respuestas:

184

Descripción general de
Strace Strace se puede ver como un depurador ligero. Permite a un programador / usuario descubrir rápidamente cómo interactúa un programa con el sistema operativo. Lo hace monitoreando las llamadas y señales del sistema.

Usos
Bueno para cuando no tienes código fuente o no quieres que te molesten en leerlo.
Además, es útil para su propio código si no tiene ganas de abrir GDB, pero solo está interesado en comprender la interacción externa.

Una buena introducción
me encontré con esta introducción para usar strace el otro día: strace hello world

John Mulder
fuente
Entonces, ¿qué pasa si usa algo debajo de la capa que separa los monitores?
Pacerier
En ese caso, @Pacerier compruebe ltrace stackoverflow.com/a/52012215/5884955
prosti
Es ideal para depurar programas de bajo nivel que existen solo / principalmente para hacer llamadas interesantes al sistema, o experimentar con nuevas opciones para llamadas de sistema para ver qué hace su sistema operativo. Básicamente ahorra la molestia de escribir código de registro / verificación de errores para experimentos únicos. (O si está escrito en ensamblador o algo donde hay una buena probabilidad de que pasó accidentalmente los argumentos equivocados o número de llamada incluso.) Strace es mucho más rápido que el BGF, ya que mira hacia arriba errno códigos para usted, por ejemplo, -EFAULT(perdón, de sólo lectura buffer) o -ENOENT(vaya, se ejecutó desde el directorio incorrecto donde la ruta relativa no funcionaba).)
Peter Cordes
62

En palabras simples, strace rastrea todas las llamadas al sistema emitidas por un programa junto con sus códigos de retorno. Piense en cosas como operaciones de archivo / socket y muchas más oscuras.

Es más útil si tiene algún conocimiento práctico de C ya que aquí las llamadas al sistema representarían con mayor precisión las llamadas a la biblioteca C estándar.

Digamos que su programa es / usr / local / bin / cough. Simplemente use:

strace /usr/local/bin/cough <any required argument for cough here>

o

strace -o <out_file> /usr/local/bin/cough <any required argument for cough here>

para escribir en 'out_file'.

Toda la salida de strace irá a stderr (cuidado, el gran volumen a menudo pide una redirección a un archivo). En los casos más simples, su programa abortará con un error y podrá ver cuál fue su última interacción con el sistema operativo en la salida directa.

Más información debería estar disponible con:

man strace
bltxd
fuente
36

strace enumera todas las llamadas al sistema realizadas por el proceso al que se aplica. Si no sabe lo que significan las llamadas al sistema, no podrá obtener mucho kilometraje de él.

Sin embargo, si su problema involucra archivos o rutas o valores de entorno, ejecutar strace en el programa problemático y redirigir la salida a un archivo y luego agrupar ese archivo para su cadena de ruta / archivo / env puede ayudarlo a ver lo que su programa realmente está intentando hacer, a diferencia de lo que esperabas.

Asaf Bartov
fuente
77
Y para programas no triviales, esto es a menudo como beber de una manguera contra incendios, por lo que tienes que trabajar mucho para ver los resultados ...
dmckee --- ex-gatito moderador
17
strace <prog_name>para rastrear un programa. strace -o <out_file> <prog_name>para poner en un archivo
Jestin Joy
8
strace prog 2> & 1 | grep ^ open \ (
eisbaw
10
O simplemente: strace -e open myprogO para todas las llamadas al sistema relacionadas con el archivo:strace -e file myprog
Amit Naidu
17

Strace se destaca como una herramienta para investigar sistemas de producción en los que no puede permitirse ejecutar estos programas bajo un depurador. En particular, hemos usado strace en las siguientes dos situaciones:

  • El programa foo parece estar en un punto muerto y no responde. Esto podría ser un objetivo para gdb; sin embargo, no siempre hemos tenido el código fuente o, a veces, estábamos tratando con lenguajes con secuencias de comandos que no eran fáciles de ejecutar con un depurador. En este caso, ejecuta strace en un programa que ya se está ejecutando y obtendrá la lista de llamadas al sistema que se están realizando. Esto es particularmente útil si está investigando una aplicación cliente / servidor o una aplicación que interactúa con una base de datos
  • Investigar por qué un programa es lento. En particular, nos acabábamos de mudar a un nuevo sistema de archivos distribuido y el nuevo rendimiento del sistema era muy lento. Puede especificar strace con la opción '-T' que le indicará cuánto tiempo pasó en cada llamada al sistema. Esto ayudó a determinar por qué el sistema de archivos estaba haciendo que las cosas se ralentizaran.

Para ver un ejemplo de análisis utilizando strace, vea mi respuesta a esta pregunta .

Terson
fuente
15

Uso strace todo el tiempo para depurar problemas de permisos. La técnica es así:

$ strace -e trace=open,stat,read,write gnome-calculator

¿Dónde gnome-calculatorestá el comando que desea ejecutar?

Jeff Sheffield
fuente
8

strace -tfp PID monitoreará las llamadas al sistema del proceso PID, por lo tanto, podemos depurar / monitorear el estado de nuestro proceso / programa.

Leslie Zhu
fuente
6

Strace se puede utilizar como herramienta de depuración o como perfilador primitivo.

Como depurador, puede ver cómo se llamaron, ejecutaron y se devolvieron llamadas del sistema. Esto es muy importante, ya que le permite ver no solo que un programa falló, sino POR QUÉ falló un programa. Por lo general, es solo el resultado de una codificación pésima que no capta todos los resultados posibles de un programa. Otras veces son solo rutas codificadas a los archivos. Sin dificultad, puedes adivinar qué salió mal dónde y cómo. Con strace obtienes un desglose de una llamada al sistema, por lo general, solo mirar un valor de retorno te dice mucho.

Perfilar es otro uso. Puede usarlo para cronometrar la ejecución de cada syscalls individualmente o como un agregado. Si bien esto podría no ser suficiente para solucionar sus problemas, al menos reducirá en gran medida la lista de posibles sospechosos. Si ve muchos pares fopen / close en un solo archivo, probablemente abra y cierre archivos innecesariamente cada ejecución de un bucle, en lugar de abrirlo y cerrarlo fuera de un bucle.

Ltrace es primo cercano de strace, también muy útil. Debes aprender a diferenciar dónde está tu cuello de botella. Si una ejecución total es de 8 segundos, y gasta solo 0.05 segundos en llamadas al sistema, entonces el ajuste del programa no le hará mucho bien, el problema está en su código, que generalmente es un problema lógico, o el programa realmente necesita tomar tanto tiempo para correr.

El mayor problema con strace / ltrace es leer su salida. Si no sabe cómo se realizan las llamadas, o al menos los nombres de las llamadas al sistema / funciones, será difícil descifrar el significado. Saber qué devuelven las funciones también puede ser muy beneficioso, especialmente para diferentes códigos de error. Si bien es difícil descifrarlo, a veces realmente devuelven una perla de conocimiento; una vez que vi una situación en la que me quedé sin inodos, pero no sin espacio libre, por lo que todas las utilidades habituales no me dieron ninguna advertencia, simplemente no pude crear un nuevo archivo. Leer el código de error de la salida de strace me señaló en la dirección correcta.

Marcin
fuente
4

Strace es una herramienta que te dice cómo interactúa tu aplicación con tu sistema operativo.

Lo hace diciéndole qué sistema operativo utiliza su aplicación y con qué parámetros los llama.

Entonces, por ejemplo, ve qué archivos intenta abrir su programa y resiste la llamada.

Puede depurar todo tipo de problemas con esta herramienta. Por ejemplo, si la aplicación dice que no puede encontrar la biblioteca que sabes que has instalado, Strace te diría dónde está buscando ese archivo la aplicación.

Y eso es solo una punta del iceberg.

Luka Marinko
fuente
Esto es muy preciso.
prosti
4

Strace es una buena herramienta para aprender cómo su programa realiza varias llamadas al sistema (solicitudes al núcleo) y también informa las que han fallado junto con el valor de error asociado con esa falla. No todas las fallas son errores. Por ejemplo, un código que intenta buscar un archivo puede obtener un error ENOENT (No existe tal archivo o directorio), pero ese puede ser un escenario aceptable en la lógica del código.

Un buen caso de uso de strace es depurar las condiciones de carrera durante la creación de archivos temporales. Por ejemplo, un programa que puede estar creando archivos al agregar el ID de proceso (PID) a alguna cadena predefinida puede enfrentar problemas en escenarios de subprocesos múltiples. [Un PID + TID (id. De proceso + id. De hilo) o una mejor llamada al sistema, como mkstemp, lo solucionarán].

También es bueno para depurar bloqueos. Puede encontrar útil este (mi) artículo sobre strace y errores de depuración .

mohit
fuente
4

Ejemplo ejecutable mínimo

Si un concepto no está claro, hay un ejemplo más simple que no ha visto que lo explica.

En este caso, ese ejemplo es el ensamblado Linux x86_64 hello world independiente (sin libc):

hola s

.text
.global _start
_start:
    /* write */
    mov $1, %rax    /* syscall number */
    mov $1, %rdi    /* stdout */
    mov $msg, %rsi  /* buffer */
    mov $len, %rdx  /* buffer len */
    syscall

    /* exit */
    mov $60, %rax   /* exit status */
    mov $0, %rdi    /* syscall number */
    syscall
msg:
    .ascii "hello\n"
len = . - msg

GitHub aguas arriba .

Montar y ejecutar:

as -o hello.o hello.S
ld -o hello.out hello.o
./hello.out

Salidas de lo esperado:

hello

Ahora usemos strace en ese ejemplo:

env -i ASDF=qwer strace -o strace.log -s999 -v ./hello.out arg0 arg1
cat strace.log

Usamos:

strace.log ahora contiene:

execve("./hello.out", ["./hello.out", "arg0", "arg1"], ["ASDF=qwer"]) = 0
write(1, "hello\n", 6)                  = 6
exit(0)                                 = ?
+++ exited with 0 +++

Con un ejemplo tan mínimo, todos los caracteres de la salida son evidentes:

  • execvelínea: muestra cómo se straceejecuta hello.out, incluidos los argumentos de CLI y el entorno tal como se documenta enman execve

  • writelínea: muestra la llamada al sistema de escritura que realizamos. 6es la longitud de la cadena "hello\n".

    = 6es el valor de retorno de la llamada al sistema, que como se documenta en man 2 writeel número de bytes escritos.

  • exitlínea: muestra la llamada al sistema de salida que hemos realizado. ¡No hay valor de retorno, ya que el programa se cerró!

Ejemplos más complejos

La aplicación de strace es, por supuesto, para ver qué llamadas al sistema están haciendo los programas complejos para ayudar a depurar / optimizar su programa.

Notablemente, la mayoría de las llamadas al sistema que es probable que encuentre en Linux tienen envoltorios glibc, muchos de ellos de POSIX .

Internamente, los envoltorios glibc usan el ensamblaje en línea más o menos de esta manera: ¿Cómo invocar una llamada del sistema a través de sysenter en el ensamblaje en línea?

El siguiente ejemplo que debes estudiar es un POSIX writehola mundo:

C Principal

#define _XOPEN_SOURCE 700
#include <unistd.h>

int main(void) {
    char *msg = "hello\n";
    write(1, msg, 6);
    return 0;
}

Compilar y ejecutar:

gcc -std=c99 -Wall -Wextra -pedantic -o main.out main.c
./main.out

Esta vez, verá que glibc está haciendo un montón de llamadas al sistema antes mainde configurar un entorno agradable para main.

Esto se debe a que ahora no estamos utilizando un programa independiente, sino más bien un programa glibc más común, que permite la funcionalidad libc.

Luego, en cada extremo, strace.logcontiene:

write(1, "hello\n", 6)                  = 6
exit_group(0)                           = ?
+++ exited with 0 +++

Entonces concluimos que la writefunción POSIX usa, ¡sorpresa !, la writellamada al sistema Linux .

También observamos que return 0conduce a una exit_groupllamada en lugar de exit. ¡Ja, no sabía sobre esto! Por eso stracees tan genial. man exit_groupluego explica:

Esta llamada al sistema es equivalente a la salida (2), excepto que termina no solo el hilo de llamada, sino todos los hilos en el grupo de hilos del proceso de llamada.

Y aquí hay otro ejemplo en el que estudié qué llamada de sistema dlopenutiliza: /unix/226524/what-system-call-is-used-to-load-libraries-in-linux/462710#462710

Probado en Ubuntu 16.04, GCC 6.4.0, kernel de Linux 4.4.0.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
fuente
2

Aquí hay algunos ejemplos de cómo uso strace para cavar en sitios web. Espero que esto sea útil.

Verifique el tiempo para el primer byte de esta manera:

time php index.php > timeTrace.txt

Vea qué porcentaje de acciones están haciendo qué. Muchos lstaty fstatpodrían ser una indicación de que es hora de borrar el caché:

strace -s 200 -c php index.php > traceLstat.txt

Emite a trace.txtpara que pueda ver exactamente qué llamadas se están realizando.

strace -Tt -o Fulltrace.txt php index.php

Utilice esta opción para comprobar si algo tuvo entre .1al .9de un segundo para cargar:

cat Fulltrace.txt | grep "[<]0.[1-9]" > traceSlowest.txt

Vea qué archivos o directorios faltantes quedaron atrapados en el strace. Esto generará muchas cosas relacionadas con nuestro sistema; los únicos bits relevantes involucran los archivos del cliente:

strace -vv php index.php 2>&1 | sed -n '/= -1/p' > traceFailures.txt
Kerwin Smith
fuente
1

Me gustaron algunas de las respuestas donde se lee stracecomprueba cómo interactúa con su sistema operativo.

Esto es exactamente lo que podemos ver. El sistema llama. Si comparas stracey ltracela diferencia es más obvia.

$>strace -c cd
Desktop  Documents  Downloads  examples.desktop  Music  Pictures  Public  Templates  Videos
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
  0.00    0.000000           0         7           read
  0.00    0.000000           0         1           write
  0.00    0.000000           0        11           close
  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.000000                    93        10 total

Por otro lado, hay ltracefunciones de rastreo.

$>ltrace -c cd
Desktop  Documents  Downloads  examples.desktop  Music  Pictures  Public  Templates  Videos
% time     seconds  usecs/call     calls      function
------ ----------- ----------- --------- --------------------
 15.52    0.004946         329        15 memcpy
 13.34    0.004249          94        45 __ctype_get_mb_cur_max
 12.87    0.004099        2049         2 fclose
 12.12    0.003861          83        46 strlen
 10.96    0.003491         109        32 __errno_location
 10.37    0.003303         117        28 readdir
  8.41    0.002679         133        20 strcoll
  5.62    0.001791         111        16 __overflow
  3.24    0.001032         114         9 fwrite_unlocked
  1.26    0.000400         100         4 __freading
  1.17    0.000372          41         9 getenv
  0.70    0.000222         111         2 fflush
  0.67    0.000214         107         2 __fpending
  0.64    0.000203         101         2 fileno
  0.62    0.000196         196         1 closedir
  0.43    0.000138         138         1 setlocale
  0.36    0.000114         114         1 _setjmp
  0.31    0.000098          98         1 realloc
  0.25    0.000080          80         1 bindtextdomain
  0.21    0.000068          68         1 opendir
  0.19    0.000062          62         1 strrchr
  0.18    0.000056          56         1 isatty
  0.16    0.000051          51         1 ioctl
  0.15    0.000047          47         1 getopt_long
  0.14    0.000045          45         1 textdomain
  0.13    0.000042          42         1 __cxa_atexit
------ ----------- ----------- --------- --------------------
100.00    0.031859                   244 total

Aunque revisé los manuales varias veces, no he encontrado el origen del nombre, stracepero es probable que sea un rastreo de llamadas al sistema, ya que esto es obvio.

Hay tres notas más grandes para decir strace.

Nota 1: ambas funciones stracey ltraceestán utilizando la llamada al sistema ptrace. Entonces ptrace, la llamada al sistema es efectivamente cómo stracefunciona.

La llamada al sistema ptrace () proporciona un medio por el cual un proceso (el "trazador") puede observar y controlar la ejecución de otro proceso (el "trazo"), y examinar y cambiar la memoria y los registros del trazo. Se utiliza principalmente para implementar la depuración de puntos de interrupción y el seguimiento de llamadas del sistema.

Nota 2: Hay diferentes parámetros con los que puede usar strace, ya que stracepueden ser muy detallados. Me gusta experimentar con lo -cque es como un resumen de las cosas. De acuerdo con esto -c, puede seleccionar una llamada al sistema como -e trace=opendonde solo verá esa llamada. Esto puede ser interesante si está examinando qué archivos se abrirán durante el comando que está rastreando. Y, por supuesto, puede usarlo greppara el mismo propósito, pero tenga en cuenta que necesita redirigir de esta manera 2>&1 | grep etcpara comprender que los archivos de configuración están referenciados cuando se emitió el comando.

Nota 3: Encuentro esta nota muy importante. No está limitado a una arquitectura específica. stracete sorprenderá, ya que puede rastrear binarios de diferentes arquitecturas. ingrese la descripción de la imagen aquí

prosti
fuente