LINUX

5 herramientas de depuración de espacio de usuario en Linux

Por definición, las herramientas de depuración son aquellos programas que nos permiten monitorear, controlar y corregir errores en otros programas mientras se ejecutan. ¿Por qué deberíamos utilizar herramientas de depuración? Para responder a esto, hay varias situaciones en las que nos quedamos atascados mientras ejecutamos algunos programas y tendremos la necesidad de comprender qué sucedió exactamente. Por ejemplo, podríamos estar ejecutando una aplicación y produce algunos mensajes de error. Para corregir esos errores, primero debemos averiguar por qué y de dónde provienen los mensajes de error. Una aplicación podría bloquearse repentinamente y tendremos que saber qué otros procesos se estaban ejecutando en ese momento. También podríamos tener que averiguar qué estaba haciendo el proceso ‘x’ en el momento del bloqueo. Para analizar esos detalles, necesitaremos la ayuda de herramientas de depuración. Hay algunas herramientas y técnicas de depuración de espacio de usuario en Linux que son bastante útiles para analizar problemas de espacio de usuario. Son:

  • declaraciones ‘imprimir’
  • Consultando (/ proc, / sys, etc.)
  • Rastreo (strace / ltrace)
  • Valgrind (memwatch)
  • GDB

Repasemos cada uno de ellos uno por uno.

Declaraciones de ‘impresión’

Esta es una forma básica o primitiva de depurar un problema. Podemos insertar declaraciones de impresión en medio de un programa para comprender el flujo de control y obtener el valor de las variables clave. Aunque es una técnica simple, tiene algunas desventajas. Los programas deben editarse para agregar declaraciones ‘imprimir’ que luego tendrán que recompilarse y volver a ejecutarse para obtener el resultado. Este es un método que requiere mucho tiempo si el programa que se va a depurar es bastante grande.

2. Consulta

En algunas situaciones, es posible que deseemos averiguar en qué estado se encuentra un proceso en ejecución en el kernel o cuál es el mapa de memoria que está ocupando allí, etc. Para obtener este tipo de información, no necesitamos insertar ningún código en el núcleo. En su lugar, se puede utilizar el sistema de archivos / proc.
/ proc es un pseudo sistema de archivos que se llena con información del sistema en tiempo de ejecución (información de la CPU, cantidad de memoria, etc.) una vez que el sistema está en funcionamiento.

salida de 'ls / proc'
salida de ‘ls / proc’

Como puede ver, cada proceso que se ejecuta en el sistema tiene una entrada en el sistema de archivos / proc en forma de su ID de proceso. Los detalles sobre cada uno de estos procesos se pueden obtener examinando los archivos presentes en su directorio de identificación de proceso.

Explicar todas las entradas dentro del sistema de archivos / proc está fuera del alcance de este documento. Algunos de los útiles se enumeran a continuación:

/ proc / cmdline -> Línea de comando del kernel

/ proc / cpuinfo -> información sobre la marca, modelo, etc. del procesador

/ proc / filesystems -> información del sistema de archivos compatible con el kernel

/ proc // cmdline -> argumentos de línea de comando pasados ​​al proceso actual

/ proc // mem -> memoria retenida por el proceso

/ proc // status -> estado del proceso

3. Rastreo

strace e ltrace son dos de las herramientas de rastreo utilizadas en Linux para rastrear los detalles de ejecución del programa.

strace:

strace intercepta y registra las llamadas al sistema dentro de un proceso y las señales que recibe. Para el usuario, muestra las llamadas al sistema, los argumentos que se les pasan y los valores de retorno. strace se puede adjuntar a un proceso que ya se está ejecutando o a un nuevo proceso. Es útil como herramienta de diagnóstico y depuración para desarrolladores y administradores de sistemas. También se puede utilizar como una herramienta para comprender cómo funcionan las llamadas al sistema al rastrear diferentes programas. La ventaja de esta herramienta es que no se necesita código fuente y no es necesario volver a compilar los programas.

La sintaxis básica para usar strace es:

strace mando
Hay varias opciones que están disponibles para usarse con el comando strace. Se puede consultar la página de manual de la herramienta strace para obtener más detalles.

La salida de strace puede ser bastante larga y es posible que no estemos interesados ​​en repasar todas y cada una de las líneas que se muestran. Podemos usar la opción ‘-e expr’ para filtrar los datos no deseados.
Utilice la opción ‘-p pid’ para adjuntarlo a un proceso en ejecución.

La salida del comando se puede redirigir a un archivo usando la opción ‘-o’

salida de strace
salida de strace filtrando solo la llamada al sistema abierto

ltrace:

ltrace rastrea y registra las llamadas de biblioteca dinámicas (tiempo de ejecución) realizadas por un proceso y las señales recibidas por él. También puede rastrear las llamadas al sistema realizadas dentro de un proceso. Su uso es similar al de strace.

trazar mando
La opción ‘-i’ imprime el puntero de instrucción en el momento de la llamada a la biblioteca

La opción ‘-S’ se usa para mostrar tanto las llamadas al sistema como las llamadas a la biblioteca

Consulte la página del manual de ltrace para conocer todas las opciones disponibles.

salida de ltrace
salida de captura de ltrace
llamada a la biblioteca ‘strcmp’

4. Valgrind

Valgrind es un conjunto de herramientas de depuración y creación de perfiles. Una de las herramientas predeterminadas y ampliamente utilizadas es una herramienta de verificación de memoria llamada ‘Memcheck’ que intercepta las llamadas realizadas a malloc (), new (), free () y delete (). En otras palabras, es útil para detectar problemas como:

  • pérdidas de memoria
  • doble liberación
  • desbordamiento de límites
  • usando memoria no inicializada
  • usar una memoria después de haberla liberado, etc.

Funciona directamente con los archivos ejecutables.

Valgrind también tiene algunos inconvenientes. Puede ralentizar su programa a medida que aumenta la huella de memoria. A veces puede producir falsos positivos y falsos negativos. No puede detectar el acceso fuera de rango a matrices asignadas estáticamente

Para usarlo, primero descárguelo e instálelo en su sistema. (Página de descarga de Valgrind). Se puede instalar usando el administrador de paquetes para el sistema operativo que se está usando.

La instalación mediante la línea de comandos implica descomprimir y desmarcar el archivo descargado.

tar -xjvf valgring-xyztar.bz2 (donde xyz es el número de versión que está intentando instalar)

Ingrese al directorio recién creado (valgrind-xyz) y ejecute los siguientes comandos:

./configurar
hacer
hacer la instalación

Entendamos cómo funciona valgrind con un programa pequeño (test.c):

#include

vacío f (vacío)

{
int x = malloc (10 * tamaño de (int));

X[10] = 0;
}

int main ()
{
F();
return 0;
}

Compila el programa:
gcc -o prueba -g prueba.c

Ahora tenemos un archivo ejecutable llamado ‘prueba’. Ahora podemos usar valgrind para verificar errores de memoria:

valgrind –tool = memcheck –leak-check = sí prueba

Aquí está la salida de valgrind que muestra los errores:

salida valgrind
salida de valgrind que muestra el desbordamiento del bloque de pila y la fuga de memoria

Como podemos ver en el mensaje anterior, estamos intentando acceder al área más allá de la asignada en la función f y la memoria asignada no se libera.

5. BGF

GDB es un depurador de Free Software Foundation. Es útil para localizar y solucionar problemas en el código. Le da control al usuario para realizar varias acciones cuando el programa a depurar se está ejecutando, como:

  • iniciando el programa
  • detenerse en lugares específicos
  • detenerse en condiciones específicas
  • examinar la información requerida
  • realizar cambios en los datos del programa, etc.

También se puede adjuntar un volcado de memoria de un programa bloqueado a GDB y analizar la causa del bloqueo.

GDB ofrece muchas opciones para depurar programas. Sin embargo, cubriremos algunas opciones importantes aquí para que uno pueda tener una idea de cómo comenzar con GDB.

Si aún no tiene GDB instalado, puede descargarlo desde Sitio web oficial de GDB.

Programas de compilación:

Para depurar un programa usando GDB, debe compilarse usando gcc con la opción ‘-g’. Esto produce información de depuración en el formato nativo del sistema operativo y GDB trabaja con esta información.

Aquí hay un programa simple (ejemplo1.c) que realiza la división por cero para mostrar el uso de GDB:

#incluir
int divide ()
{
int x = 5, y = 0;
return x / y;
}

int main ()
{
dividir();
}

uso de gdb
Un ejemplo que muestra el uso de gdb

Invocación de GDB:

GDB se puede iniciar ejecutando ‘gdb’ en la línea de comandos:

invocando gdb
invocando gdb

Una vez invocado, permanece allí esperando los comandos del terminal y ejecutándolos hasta salir.
Si un proceso ya se está ejecutando y necesita adjuntarle GDB, puede hacerlo especificando el ID del proceso
Supongamos que un programa ya se ha bloqueado y uno quiere analizar la causa del problema, entonces ayuda adjuntar GDB al archivo principal.

Iniciando el programa:

Una vez que esté dentro de GDB, use el comando ‘ejecutar’ para iniciar el programa a depurar

Pasando argumentos al programa:

Utilice el comando ‘set args’ para enviar los argumentos a su programa la próxima vez que se ejecute
‘show args’ mostrará los argumentos pasados ​​al programa

Verificando la pila:

Siempre que un programa se detiene, lo primero que todos quieren entender es por qué se detuvo y cómo se detuvo allí. Esta información se llama seguimiento. Cada llamada de función generada por un programa se almacena junto con las variables locales, los argumentos pasados, la ubicación de la llamada, etc. en un bloque de datos dentro de la pila y se denomina marco. Usando GDB podemos examinar todos estos datos. GDB identifica estos marcos dándoles números que comienzan desde el marco más interno.

bt: imprime el trazo inverso de toda la pila
bt <n> imprime el trazo inverso de n fotogramas
cuadro : cambia al marco especificado e imprime ese marco
arriba <n>: mover ‘n’ fotogramas hacia arriba
abajo : mueve ‘n’ fotogramas hacia abajo. (n es 1 por defecto)

Examinando datos:

Los datos del programa se pueden examinar dentro de GDB usando el comando ‘imprimir’. Por ejemplo, si ‘x’ es una variable dentro del programa de depuración, ‘print x’ imprime el valor de x.

Fuente de examen:

Se pueden imprimir partes del archivo de origen dentro de GDB. El comando ‘list’ imprime por defecto 10 líneas de código.

lista : enumera el archivo de origen alrededor de ‘linenum’
lista <función>: enumera la fuente desde el principio de ‘función’

desastre : muestra el código de máquina para la función

Detener y reanudar el programa:

Usando GDB, podemos establecer puntos de interrupción, punto de observación, etc. para detener el programa donde sea necesario.

descanso : Establece un punto de interrupción en ‘ubicación’. Cuando se golpea mientras se ejecuta el programa, se le da el control al usuario.
reloj : GDB se detiene cuando el programa escribe ‘expr’ y su valor cambia
atrapar <evento>: GDB se detiene cuando ocurre el ‘evento’.
desactivar : deshabilita el punto de interrupción especificado
habilitar <punto de ruptura>: habilita el punto de interrupción especificado
eliminar <punto de ruptura>: eliminar el punto de interrupción / punto de observación / punto de captura pasado
Si no se pasan argumentos, la acción predeterminada es trabajar en todos los puntos de interrupción

paso: ejecutar el programa paso a paso
Seguir: continuar con la ejecución del programa hasta que se complete la ejecución

Saliendo de GDB:

Utilice el comando ‘salir’ para salir de GDB
Hay muchas más opciones disponibles con GDB. Utilice la opción de ayuda una vez que esté dentro de GDB para obtener más detalles.

gdb-help
obtener ayuda dentro de gdb

Resumen

En este artículo, hemos visto diferentes tipos de herramientas de depuración de espacio de usuario disponibles en Linux. Para resumirlos todos, aquí hay una guía rápida sobre cuándo usar qué:
Depuración básica, obtención de valores de variables clave – declaraciones de impresión

Obtenga información sobre los sistemas de archivos compatibles, la memoria disponible, la CPU, el estado de un programa en ejecución en el kernel, etc. – consulta / sistema de archivos proc

Diagnóstico inicial de problemas, problemas relacionados con llamadas al sistema o llamadas a la biblioteca, comprensión del flujo del programa – strace / ltrace

Problemas de memoria relacionados con el espacio de la aplicación – valgrind

Para examinar el comportamiento en tiempo de ejecución de las aplicaciones, analizar los fallos de las aplicaciones: gdb.

Publicaciones relacionadas

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Botón volver arriba
Cerrar