GNU Debugger o GDB: una poderosa herramienta de depuración de código fuente para programas Linux
Un depurador juega un papel vital en cualquier sistema de desarrollo de software. Nadie puede escribir un código libre de errores de una sola vez. Durante el curso del desarrollo, se detectan errores que deben resolverse para seguir mejorando. Un sistema de desarrollo está incompleto sin un depurador. Teniendo en cuenta la comunidad de desarrolladores de código abierto, GNU Debugger es su mejor opción. También se utiliza para el desarrollo de software comercial en plataformas tipo UNIX.
GNU Debugger, también conocido como gdb, nos permite colarnos en el código mientras se ejecuta o en lo que un programa estaba intentando hacer en el momento antes de fallar. Básicamente, GDB nos ayuda a hacer cuatro cosas principales para detectar fallas en el código fuente.
- Inicie el programa, especificando argumentos que puedan afectar el comportamiento general.
- Detenga el programa en condiciones específicas.
- Examine el accidente o cuándo se detuvo el programa.
- Cambie el código y experimente con el código modificado instantáneamente.
Podemos usar gdb para depurar programas escritos en C y C++ sin mucho esfuerzo. A partir de ahora, el soporte para otros lenguajes de programación como D, Modula-2, Fortran es parcial.
Comenzando con GNU Debugger o GDB
GDB se invoca utilizando el comando gdb. Al emitir gdb, muestra información sobre la plataforma y lo lleva al mensaje (gdb) como se muestra a continuación. .
[root@fedora20 ~]# gdb
Salida de muestra
GNU gdb (GDB) Fedora 7.6.50.20130731-19.fc20
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
(gdb)
Escriba help list para ver las diferentes clases de comandos disponibles dentro de gdb. Escriba ayuda seguido del nombre de una clase para obtener una lista de comandos en esa clase. Escriba ayuda a todos para obtener la lista de todos los comandos. Se permiten abreviaturas de nombres de comandos si no son ambiguas. Por ejemplo, puede escribir n en lugar de escribir siguiente o c para continuar y así sucesivamente.
Comandos GDB más utilizados
Los comandos gdb más utilizados se enumeran en la siguiente tabla. Estos comandos deben usarse desde el símbolo del sistema de gdb (gdb).
-
Command
- Descripción
-
run
- Iniciar la ejecución de un programa
-
quit
- Salir de gdb
-
print expr
- Imprimir expresión donde expr también puede ser un nombre de variable
-
next
- Ir a la siguiente línea
-
step
- Pase a la siguiente línea
-
continue
- Continuar desde la línea actual hasta el final del programa o el siguiente punto de interrupción
Tenga en cuenta la diferencia entre los dos comandos paso y siguiente. El comando siguiente no va dentro de la función si la siguiente línea es una llamada de función. Mientras que el comando paso puede entrar dentro de la función y ver qué sucede allí.
Una sesión de muestra con GDB
Considere el siguiente código fuente.
// sum.c
#include <stdio.h>
int sum (int a, int b) {
int c;
c = a + b;
return c;
}
int main() {
int x, y, z;
printf("\nEnter the first number: ");
scanf("%d", &x);
printf("Enter the second number: ");
scanf("%d", &y);
z = sum (x, y);
printf("The sum is %d\n\n", z);
return 0;
}
Para depurar el archivo de salida, necesitamos compilarlo con la opción -g para gcc de la siguiente manera.
gcc -g sum.c -o sum
El archivo de salida sum se puede adjuntar a gdb mediante cualquiera de las siguientes dos formas:
1. Especificando el archivo de salida como argumento para gdb.
gdb sum
2. Ejecutar el archivo de salida dentro de gdb usando el comando archivo.
gdb
(gdb) file sum
El comando list enumera líneas en el archivo de código fuente y mueve el puntero. Entonces, la primera lista mostrará las primeras 10 líneas y la siguiente lista mostrará las siguientes 10 y así sucesivamente.
(gdb) list
1 #include <stdio.h>
2
3 int sum (int a, int b) {
4 int c;
5 c = a + b;
6 return c;
7 }
8
9 int main() {
10 int x, y, z;
Para iniciar la ejecución, emita el comando ejecutar . Ahora el programa se ejecuta normalmente. Pero nos olvidamos de poner algunos puntos de interrupción en el código fuente para la depuración, ¿verdad? Estos puntos de interrupción se pueden especificar para funciones o en líneas específicas.
(gdb) b main
Nota: he utilizado una abreviatura b para descanso.
Después de establecer el punto de interrupción en la función principal, volver a ejecutar el programa se detendrá en la línea 11. Lo mismo se puede hacer efectivo si se conoce el número de línea antes.
(gdb) b sum.c:11
Ahora recorra las líneas de código usando el comando siguiente o n. Es importante tener en cuenta que el comando siguiente no ingresa dentro del código de función a menos que se establezca un punto de interrupción en la función. Probemos ahora el comando imprimir. Establezca el punto de interrupción en la suma de la función como se muestra a continuación.
(gdb) b sum
Breakpoint 1 at 0x4005aa: file sum.c, line 5.
(gdb) r
Starting program: /root/sum
Enter the first number: 2
Enter the second number: 3
Breakpoint 1, sum (a=2, b=3) at sum.c:5
5 c = a + b;
(gdb) p a
$1 = 2
(gdb) p b
$2 = 3
(gdb) c
Continuing.
The sum is 5
[Inferior 1 (process 3444) exited normally]
Si el programa que se está ejecutando requiere parámetros de línea de comando, proporcione los mismos junto con el comando ejecutar como.
(gdb) run . . .
Los archivos de biblioteca compartidos asociados con el programa en ejecución actual se pueden enumerar como.
(gdb) info share
From To Syms Read Shared Object Library
0x00000035a6000b10 0x00000035a6019c70 Yes /lib64/ld-linux-x86-64.so.2
0x00000035a641f560 0x00000035a6560bb4 Yes /lib64/libc.so.6
Modificar variables
GDB también es capaz de modificar variables durante la ejecución del programa. Probemos esto. Como se mencionó anteriormente, establezca el punto de interrupción en la línea 16 y ejecute el programa.
(gdb) r
Starting program: /root/sum
Enter the first number: 1
Enter the second number: 2
Breakpoint 1, main ( ) at sum.c:16
16 printf("The sum is %d\n\n", z);
(gdb) set z=4
(gdb) c
Continuing.
The sum is 4
Ahora a=1, b=2 y el resultado debería ser z=3. Pero aquí cambiamos el resultado final a z=4 en la función principal. De esta manera, la depuración se puede facilitar utilizando gdb.
Activar/desactivar puntos de interrupción
Para obtener la lista de todos los puntos de interrupción, escriba info breakpoints.
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000004005c2 in main at sum.c:11
Aquí sólo hay un punto de quiebre y es To. habilitado deshabilitar los puntos de interrupción, especifique el número del punto de interrupción junto con el comando deshabilitar. Para habilitarlo posteriormente, utilice el comando enable.
(gdb) disable 1
(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep n 0x00000000004005c2 in main at sum.c:11
También puede eliminar los puntos de interrupción con el comando eliminar.
Depuración de procesos en ejecución
Numerosos procesos se ejecutan en segundo plano en un sistema GNU/Linux. Para depurar un proceso en ejecución, primero que nada necesitamos encontrar la identificación del proceso de ese proceso en particular. El comando pidof le proporciona el pid de un proceso.
pidof <process_name>
Ahora necesitamos adjuntar este pid a gdb. Hay 2 maneras.
1. Especificando pid junto con gdb.
gdb -p <pid>
2. Usando el comando adjuntar de gdb.
(gdb) attach <pid>
Eso es todo por ahora. Estos son sólo los conceptos básicos de gdb para comenzar bien en la depuración del código fuente y son mucho más que lo explicado anteriormente. Por ejemplo, podemos depurar utilizando la información de la pila, variables de entorno y mucho más. Intenta jugar con todas estas cosas...