Herramientas de usuario

Herramientas del sitio


notas:strace

Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

Ambos lados, revisión anteriorRevisión previa
Próxima revisión
Revisión previa
Próxima revisiónAmbos lados, revisión siguiente
notas:strace [2020/04/17 01:15] – [Uso] cayunotas:strace [2020/04/17 01:58] – [Extras y referencias útiles] cayu
Línea 1: Línea 1:
 ====== Strace ====== ====== Strace ======
  
-**strace** es una utilidad que nos puede ayudar en la comprobación de errores en procesos en el sistema operativo GNU/Linux. La misma sirve para monitorear las llamadas al sistema usadas por un determinado programa todas las señales que éste recibe. Esto es posible por una característica del núcleo linux llamada ptrace.+**strace** es una utilidad que nos puede ayudar en la comprobación de errores y cuellos de botella en procesos en el sistema operativo GNU/Linux. La misma sirve para monitorear las llamadas al sistema usadas por un determinado programatodas las señales que éste recibe y cuando tiempo toma cada llamada. Esto es posible por una característica del núcleo linux llamada **ptrace**.
  
-Su uso más común consiste en arrancarlo junto al programa al que se le efectúa el trazadoel cual imprime una lista de llamadas al sistema que dicho programa ejecuta. Es útil para averiguar la causa del fallo de un programa determinado porque informa de situaciones en las que por ejemplo, el programa está intentando acceder a un fichero que no existe o que no tiene permiso de lectura.+Se puede arrancar junto al programa al que se le efectúa el trace, imprime la lista de llamadas al sistema que dicho programa ejecuta. Es útil para averiguar la causa del fallo de un programa determinado porque informa de situaciones en las que por ejemplo, el programa está intentando acceder a un fichero que no existe o que no tiene permiso de lectura o tiempos de espera muy altos al intentar obtener un servicio remoto por red.
  
 ===== Uso ===== ===== Uso =====
Línea 121: Línea 121:
 } }
 </code> </code>
 +Para compilarlo procederemos a ejecutar **gcc**:
 +<code>
 +gcc socket.c -o socket
 +</code>
 +Strace nos mostrará muchos datos, como llamadas al sistema para imprimi como files descriptors, llamadas a memoria etc. Si solo nos interesa las llamadas a funciones de red, podemos agregarle los siguientes argumentos //-e trace=network,read,write// o simplemente //-e trace=network//
 +<code>
 +00    strace -e trace=network,read,write ./socket  cayu.com.ar 80
 +01    read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\360r\2\0\0\0\0\0"..., 832) = 832
 +02    read(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784) = 784
 +03    read(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32) = 32
 +04    read(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0q7?\324>\326\250>\n\253\230<:\227\0362"..., 68) = 68
 +05    read(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784) = 784
 +06    read(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32) = 32
 +07    read(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0q7?\324>\326\250>\n\253\230<:\227\0362"..., 68) = 68
 +08    read(3, "# The \"order\" line is only used "..., 4096) = 92
 +09    read(3, "", 4096)                       = 0
 +10    read(3, "# Generated by NetworkManager\nna"..., 4096) = 52
 +11    read(3, "", 4096)                       = 0
 +12    socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 3
 +13    connect(3, {sa_family=AF_UNIX, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No existe el archivo o el directorio)
 +14    socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 3
 +15    connect(3, {sa_family=AF_UNIX, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No existe el archivo o el directorio)
 +16    read(3, "# /etc/nsswitch.conf\n#\n# Example"..., 4096) = 542
 +17    read(3, "", 4096)                       = 0
 +18    read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\3005\0\0\0\0\0\0"..., 832) = 832
 +19    read(3, "127.0.0.1\tlocalhost\n127.0.1.1\tt4"..., 4096) = 303
 +20    read(3, "", 4096)                       = 0
 +21    read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0000\16\0\0\0\0\0\0"..., 832) = 832
 +22    read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0@G\0\0\0\0\0\0"..., 832) = 832
 +23    read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 #\0\0\0\0\0\0"..., 832) = 832
 +24    socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, IPPROTO_IP) = 3
 +25    setsockopt(3, SOL_IP, IP_RECVERR, [1], 4) = 0
 +26    connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("127.0.0.53")}, 16) = 0
 +27    sendto(3, "\334f\1\0\0\1\0\0\0\0\0\0\4cayu\3com\2ar\0\0\1\0\1", 29, MSG_NOSIGNAL, NULL, 0) = 29
 +28    recvfrom(3, "\334f\201\200\0\1\0\1\0\0\0\0\4cayu\3com\2ar\0\0\1\0\1\300\f\0"..., 1024, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("127.0.0.53")}, [28->16]) = 45
 +29    socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
 +30    setsockopt(3, SOL_TCP, TCP_NODELAY, [1], 4) = 0
 +31    connect(3, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("69.61.93.142")}, 16) = 0
 +32    write(3, "GET /\r\n", 7)                = 7
 +33    read(3, "<html>\r\n<head><title>301 Moved P"..., 1023) = 178
 +34    write(2, "<html>\r\n<head><title>301 Moved P"..., 178<html>
 +35    <head><title>301 Moved Permanently</title></head>
 +36    <body bgcolor="white">
 +37    <center><h1>301 Moved Permanently</h1></center>
 +38    <hr><center>nginx</center>
 +39    </body>
 +40    </html>
 +41    ) = 178
 +42    read(3, "", 1023)                       = 0
 +43    shutdown(3, SHUT_RDWR)                  = 0
 +44    +++ exited with 0 +++
 +45    
 +</code>
 +
 +En la línea 00 podemos ver el comando completo, vemos llamadas al DNS en varios read y un connect en la línea **26** para efectivamente realizar la consulta, la resolución del nombre en la línea **28** y efectivamente el connect de lo que queremos obtener en la línea **31**, el GET que enviamos en la línea **32**, su lectura y su escritura en pantalla.
 +
 +Si por ejemplo solo queremos ver los system calls //open, close, read, y write// podemos proceder de la siguiente forma :
 +<code>
 +strace -e trace=open,close,read,write  ./socket  cayu.com.ar 80
 +close(3)                                = 0
 +read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\360r\2\0\0\0\0\0"..., 832) = 832
 +read(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784) = 784
 +read(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32) = 32
 +read(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0q7?\324>\326\250>\n\253\230<:\227\0362"..., 68) = 68
 +read(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784) = 784
 +read(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32) = 32
 +read(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0q7?\324>\326\250>\n\253\230<:\227\0362"..., 68) = 68
 +close(3)                                = 0
 +read(3, "# The \"order\" line is only used "..., 4096) = 92
 +read(3, "", 4096)                       = 0
 +close(3)                                = 0
 +read(3, "# Generated by NetworkManager\nna"..., 4096) = 52
 +read(3, "", 4096)                       = 0
 +close(3)                                = 0
 +close(3)                                = 0
 +close(3)                                = 0
 +read(3, "# /etc/nsswitch.conf\n#\n# Example"..., 4096) = 542
 +read(3, "", 4096)                       = 0
 +close(3)                                = 0
 +close(3)                                = 0
 +read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\3005\0\0\0\0\0\0"..., 832) = 832
 +close(3)                                = 0
 +read(3, "127.0.0.1\tlocalhost\n127.0.1.1\tt4"..., 4096) = 303
 +read(3, "", 4096)                       = 0
 +close(3)                                = 0
 +close(3)                                = 0
 +read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0000\16\0\0\0\0\0\0"..., 832) = 832
 +close(3)                                = 0
 +read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0@G\0\0\0\0\0\0"..., 832) = 832
 +close(3)                                = 0
 +close(3)                                = 0
 +read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 #\0\0\0\0\0\0"..., 832) = 832
 +close(3)                                = 0
 +close(3)                                = 0
 +write(3, "GET /\r\n", 7)                = 7
 +read(3, "<html>\r\n<head><title>301 Moved P"..., 1023) = 178
 +write(2, "<html>\r\n<head><title>301 Moved P"..., 178<html>
 +<head><title>301 Moved Permanently</title></head>
 +<body bgcolor="white">
 +<center><h1>301 Moved Permanently</h1></center>
 +<hr><center>nginx</center>
 +</body>
 +</html>
 +) = 178
 +read(3, "", 1023)                       = 0
 +close(3)                                = 0
 ++++ exited with 0 +++
 +</code>
 +===== Extras y referencias útiles =====
 +A veces también puede servirnos **ltrace**, que es una utilidad de depuración, que se usa para mostrar las llamadas que una aplicación de espacio de usuario hace a las bibliotecas compartidas.
 +
 +  * https://www.linkedin.com/learning/faster-python-services/strace
 +  * https://www.amazon.es/Linux-Security-Cookbook-Daniel-Barrett/dp/0596003919
 +  * https://www.mcanan.uy/blog/strace/
 +  * https://strace.io/
notas/strace.txt · Última modificación: 2020/04/17 02:11 por cayu