GNU Debugger o GDB: una potente herramienta de depuración de código fuente para programas de Linux

A debugger plays a vital role in any software development system. Nobody can write a bug-free code all at once. During the course of development, bugs are being raised and needs to be solved for further enhancement. A development system is incomplete without a debugger. Considering the open source developers community, GNU Debugger is their best choice. It is also used for commercial software development on UNIX type platforms.

Debugging source code with GNU Debugger

El Depurador GNU, también conocido como gdb, nos permite revisar el código mientras se ejecuta o ver lo que un programa intentaba hacer justo antes de que se bloqueara. Básicamente, el GDB nos ayuda a hacer cuatro cosas principales para detectar fallos en el código fuente.

  1. Iniciar el programa, especificando argumentos que pueden afectar el comportamiento general.
  2. Detener el programa en condiciones especificadas.
  3. Examinar el bloqueo o el momento en que se detuvo el programa.
  4. Cambiar el código y experimentar con el código modificado instantáneamente.

Podemos utilizar gdb para depurar programas escritos en C y C++ sin mucho esfuerzo. Hasta ahora, el soporte para otros lenguajes de programación como D, Modula-2, Fortran es parcial.

Empezar con el Depurador GNU o GDB

GDB se invoca utilizando el comando gdb. Al ejecutar gdb, muestra información sobre la plataforma y te lleva al prompt de (gdb) como se muestra a continuación.

[root@fedora20 ~]# gdb
Salida de ejemplo
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)

Escribe help list para ver las distintas clases de comandos disponibles dentro de gdb. Escribe help seguido de un nombre de clase para ver la lista de comandos en esa clase. Escribe help all para ver la lista de todos los comandos. Se permiten abreviaturas de nombres de comandos si son unívocos. Por ejemplo, puedes escribir n en lugar de escribir next o c para continue y así sucesivamente.

Los comandos GDB más comúnmente utilizados

Los comandos gdb comúnmente utilizados se enumeran en la siguiente tabla. Estos comandos deben ser utilizados desde el símbolo del sistema de gdb (gdb).

Command
Description
run
Start a program execution
quit
Quit gdb
print expr
Print expression where expr may be a variable name too
next
Go to next line
step
Step into next line
continue
Continue from the current line till the end of program or next break point

Observa la diferencia entre los dos comandos step y next. El comando next no ingresa a una función si la siguiente línea es una llamada a función. Mientras que el comando step puede ingresar a una función y ver lo que ocurre allí.

A sample session with GDB

Considera 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 en gcc de la siguiente manera.

$ gcc -g sum.c -o sum

El archivo de salida sum puede adjuntarse a gdb de dos formas diferentes:

1. Especificando el archivo de salida como un argumento para gdb.

$ gdb sum

2. Ejecutando el archivo de salida dentro de gdb utilizando el comando file.

$ gdb
(gdb) file sum

El comando list lista las líneas en el archivo de código fuente y mueve el puntero. Por lo tanto, primero list mostrará las primeras 10 líneas y luego list 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, emite el comando run . Ahora el programa se ejecutará normalmente. ¿Pero olvidamos poner algunos puntos de interrupción en el código fuente para depurar, verdad? Estos puntos de interrupción pueden especificarse para funciones o en líneas específicas.

(gdb) b main

Nota: He utilizado la abreviatura b para break.

Después de establecer un 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 lograr si se conoce el número de línea antes.

(gdb) b sum.c:11

Ahora avance por las líneas de código usando el comando next o n. Es importante tener en cuenta que el comando next no entra en el código de la función a menos que se establezca un punto de interrupción en la función. Probemos el comando print ahora. Establezca un punto de interrupción en la función sum 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 comandos, proporciónelos junto con el comando run.

(gdb) run   . . .

Los archivos de biblioteca compartida asociados con el programa que se está ejecutando actualmente pueden ser listados como sigue.

(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

Modificación de Variables

GDB también es capaz de modificar variables durante la ejecución del programa. Probemos esto. Como se mencionó anteriormente, establezca un 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 simplificar usando gdb.

Habilitar/Deshabilitar 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í hay un solo punto de interrupción y está activo. Para desactivarlo, especifique el número de punto de interrupción junto con el comando disable. Para activarlo posteriormente, use 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 puedes eliminar los puntos de interrupción con el comando delete.

Depurando procesos en ejecución

Numerosos procesos se están ejecutando en segundo plano en un sistema GNU/Linux. Para depurar un proceso en ejecución, primero necesitamos encontrar el identificador del proceso de ese proceso en particular. El comando pidof te da el pid de un proceso.

$ pidof <process_name>

Ahora necesitamos adjuntar este pid a gdb. Hay 2 maneras.

1. Especificando el pid junto con gdb.

$ gdb -p <pid>

2. Usando el comando attach desde gdb.

(gdb) attach <pid>

Eso es todo por ahora. Estos son solo los conceptos básicos de gdb para tener un buen comienzo en la depuración del código fuente y es mucho más que las cosas explicadas arriba. Por ejemplo, podemos depurar usando la información del stack, las variables de entorno y mucho más. Intenta jugar con todas estas cosas…

Source:
https://www.tecmint.com/debug-source-code-in-linux-using-gdb/