El depurador GNU ( GDB ) es un depurador portátil que se ejecuta en muchos sistemas tipo Unix y funciona para muchos lenguajes de programación , incluidos Ada , Assembly , C , C++ , D , Fortran , Haskell , Go , Objective-C , OpenCL C , Modula-2 , Pascal , Rust , [2] y parcialmente otros. [3]
GDB fue escrito por primera vez por Richard Stallman en 1986 como parte de su sistema GNU , después de que su GNU Emacs fuera "razonablemente estable". [4] GDB es un software libre publicado bajo la Licencia Pública General GNU (GPL). Fue diseñado a partir del depurador DBX , que venía con las distribuciones Berkeley Unix . [4]
De 1990 a 1993 fue mantenido por John Gilmore . [5] Ahora es mantenido por el Comité Directivo del GDB que es designado por la Free Software Foundation . [6]
GDB ofrece amplias funciones para rastrear y modificar la ejecución de programas informáticos . El usuario puede supervisar y modificar los valores de las variables internas de los programas e incluso invocar funciones independientemente del comportamiento normal del programa.
Los procesadores de destino de GDB (a partir de 2003) incluyen: Alpha , ARM , AVR , H8/300 , Altera Nios / Nios II , System/370 , System 390 , X86 y su extensión de 64 bits X86-64 , IA-64 "Itanium", Motorola 68000 , MIPS , PA-RISC , PowerPC , SuperH , SPARC y VAX . Los procesadores de destino menos conocidos admitidos en la versión estándar incluyen A29K , ARC , ETRAX CRIS , D10V, D30V, FR-30, FR-V , Intel i960 , 68HC11 , Motorola 88000 , MCORE , MN10200, MN10300 , NS32K , Stormy16 y Z8000 . (Es probable que las versiones más nuevas no admitan algunos de estos). GDB ha compilado simuladores para procesadores de destino incluso menos conocidos, como M32R o V850 . [7]
GDB sigue en desarrollo activo. A partir de la versión 7.0, las nuevas características incluyen compatibilidad con scripts Python [8] y, a partir de la versión 7.8, también con scripts GNU Guile [9] . Desde la versión 7.0, está disponible la compatibilidad con la "depuración reversible", que permite que una sesión de depuración retroceda, de forma similar a rebobinar un programa bloqueado para ver qué sucedió. [10]
GDB ofrece un modo "remoto" que se utiliza a menudo para depurar sistemas integrados. La operación remota es cuando GDB se ejecuta en una máquina y el programa que se está depurando se ejecuta en otra. GDB puede comunicarse con el "stub" remoto que entiende el protocolo GDB a través de un dispositivo serial o TCP/IP. [11] Se puede crear un programa stub mediante la vinculación a los archivos stub apropiados provistos con GDB, que implementan el lado de destino del protocolo de comunicación. [12] Alternativamente, se puede utilizar gdbserver para depurar remotamente el programa sin necesidad de cambiarlo de ninguna manera.
El mismo modo también es utilizado por KGDB para depurar un núcleo Linux en ejecución en el nivel de fuente con gdb. Con KGDB, los desarrolladores de núcleos pueden depurar un núcleo de la misma manera que depuran programas de aplicación. Permite colocar puntos de interrupción en el código del núcleo, recorrer el código y observar variables. En arquitecturas donde hay registros de depuración de hardware disponibles, se pueden establecer puntos de vigilancia que activan puntos de interrupción cuando se ejecutan o acceden a direcciones de memoria específicas. KGDB requiere una máquina adicional que esté conectada a la máquina que se va a depurar mediante un cable serial o Ethernet . En FreeBSD , también es posible depurar mediante acceso directo a memoria FireWire (DMA). [13]
El depurador no contiene su propia interfaz gráfica de usuario y, por defecto, utiliza una interfaz de línea de comandos , aunque sí contiene una interfaz de usuario de texto . Se han creado varios front-ends para él, como UltraGDB, Xxgdb, Data Display Debugger (DDD), Nemiver , KDbg, el depurador Xcode , GDBtk/Insight, Gede [1], Seer [2] y HP Wildebeest Debugger GUI (WDB GUI). Los IDE como Codelite , Code::Blocks , Dev-C++ , Geany , GNAT Programming Studio (GPS), KDevelop , Qt Creator , Lazarus , MonoDevelop , Eclipse , NetBeans y Visual Studio pueden interactuar con GDB. GNU Emacs tiene un "modo GUD" y existen herramientas para Vim (por ejemplo, clewn). Estas ofrecen funciones similares a los depuradores que se encuentran en los IDE.
Se han diseñado otras herramientas de depuración para trabajar con GDB, como los detectores de fugas de memoria .
GDB utiliza una llamada al sistema llamada ptrace (el nombre es una abreviatura de "process trace") para observar y controlar la ejecución de otro proceso, y examinar y cambiar la memoria y los registros del proceso.
Un punto de interrupción se implementa reemplazando una instrucción en una dirección de memoria dada con otra instrucción especial. La ejecución de una instrucción de punto de interrupción provoca SIGTRAP.
Considere el siguiente código fuente escrito en C :
#include <stdio.h> #include <stdlib.h> #include <string.h> tamaño_t foo_len ( const char * s ) { return strlen ( s ); } int principal ( int argc , char * argv [] ) { const char * a = NULL ; printf ( "tamaño de a = %lu \n " , foo_len ( a ) ); salir ( 0 ); }
Si se utiliza el compilador GCC en Linux , el código anterior debe compilarse utilizando el -g
indicador para incluir la información de depuración adecuada en el binario generado, lo que permite inspeccionarlo mediante GDB. Suponiendo que el archivo que contiene el código anterior se llama example.c
, el comando para la compilación podría ser:
$ gcc ejemplo.c -Og -g -o ejemplo
Y ahora se puede ejecutar el binario:
$ ./ejemplo Fallo de segmentación
Dado que el código de ejemplo, al ejecutarse, genera una falla de segmentación , se puede utilizar GDB para inspeccionar el problema.
$ gdb ./example GNU gdb (GDB) Fedora (7.3.50.20110722-13.fc16) Copyright (C) 2011 Free Software Foundation, Inc. Licencia GPLv3+: GNU GPL versión 3 o posterior <https://gnu.org/licenses/gpl.html> Este es software libre: usted es libre de modificarlo y redistribuirlo. NO HAY GARANTÍA, en la medida permitida por la ley. Escriba "show copying" y "show warranty" para obtener más detalles. Este GDB se configuró como "x86_64-redhat-linux-gnu". Para obtener instrucciones sobre cómo informar errores, consulte: <https://www.gnu.org/software/gdb/bugs/>... Leyendo símbolos desde /path/example...hecho. (gdb) ejecutar Iniciando programa: /path/exampleEl programa recibió la señal SIGSEGV, Fallo de segmentación. 0x0000000000400527 en foo_len (s=0x0) en example.c:7 7 return strlen (s); (gdb) print s $ 1 = 0x0
El problema está presente en la línea 7 y ocurre al llamar a la función strlen
(porque su argumento, s
, es NULL
). Dependiendo de la implementación de strlen ( en línea o no), la salida puede ser diferente, por ejemplo:
GNU gdb (GDB) 7.3.1 Copyright (C) 2011 Free Software Foundation, Inc. Licencia GPLv3+: GNU GPL versión 3 o posterior <https://gnu.org/licenses/gpl.html> Este es software libre: usted es libre de modificarlo y redistribuirlo. NO HAY GARANTÍA, en la medida permitida por la ley. Escriba "show copying" y "show warranty" para obtener más detalles. Este GDB se configuró como "i686-pc-linux-gnu". Para obtener instrucciones sobre cómo informar errores, consulte: <https://www.gnu.org/software/gdb/bugs/>... Leyendo símbolos de /tmp/gdb/example...hecho. (gdb) ejecutar Iniciando programa: /tmp/gdb/exampleEl programa recibió la señal SIGSEGV, Fallo de segmentación. 0xb7ee94f3 en strlen () desde /lib/i686/cmov/libc.so.6 (gdb) bt # 0 0xb7ee94f3 en strlen () desde /lib/i686/cmov/libc.so.6 # 1 0x08048435 en foo_len ( s = 0x0 ) en example.c:7 # 2 0x0804845a en main ( argc = <optimized out>, argv = <optimized out> ) en example.c:14
Para solucionar el problema, la variable a
(en la función main
) debe contener una cadena válida. A continuación, se muestra una versión corregida del código:
#include <stdio.h> #include <stdlib.h> #include <string.h> tamaño_t foo_len ( const char * s ) { return strlen ( s ); } int main ( int argc , char * argv [] ) { const char * a = "Esta es una cadena de prueba" ; printf ( "tamaño de a = %lu \n " , foo_len ( a ) ); salir ( 0 ); }
Recompilar y ejecutar nuevamente el ejecutable dentro de GDB ahora arroja un resultado correcto:
$ gdb ./example GNU gdb (GDB) Fedora (7.3.50.20110722-13.fc16) Copyright (C) 2011 Free Software Foundation, Inc. Licencia GPLv3+: GNU GPL versión 3 o posterior <https://gnu.org/licenses/gpl.html> Este es software libre: usted es libre de modificarlo y redistribuirlo. NO HAY GARANTÍA, en la medida permitida por la ley. Escriba "show copying" y "show warranty" para obtener más detalles. Este GDB se configuró como "x86_64-redhat-linux-gnu". Para obtener instrucciones sobre cómo informar errores, consulte: <https://www.gnu.org/software/gdb/bugs/>... Leyendo símbolos de /path/example...hecho. (gdb) ejecutar Iniciando programa: /path/example tamaño de a = 21 [Inferior 1 (proceso 14290) salió normalmente]
GDB imprime la salida printf
en la pantalla y luego informa al usuario que el programa salió normalmente.
lo que llevó en total alrededor de un año y medio, comencé a volver a trabajar en otras partes del sistema. Desarrollé un depurador al que llamé GDB, que es un depurador simbólico para código C, que recientemente entró en distribución. Ahora bien, este depurador se inspira en gran medida en DBX, que es un depurador que viene con Berkeley Unix.