GDB para depurar programas en C/C++ en GNU/Linux

6:02 pm GNU/Linux, Programación

Miremos la descripción de gdb sacada del mismo man:

El proposito de un depurador como GDB es permitir al usuario ver lo que
esta ocurriendo “dentro” de otro programa mientras que se esta ejecu-
tando — o lo que estaba haciendo en el momento que fallo.

GDB puede hacer cuatro tipo de cosas (mas otras cosas para dar soporte
a estas) para ayudarte a capturar errores en el acto:

o Comenzar tu programa, especificando cualquier cosa que pueda
afectar a su comportamiento.

o Hacer que tu programa se pare al cumplirse las condiciones
especificadas.

o Examinar que ha pasado, cuando tu programa se ha parado.

o Cambiar cosas de tu programa, de tal manera que puedas experi-
mentar corrigiendo los efectos de un fallo y continuar para des-
cubrir otros.

Generalmente todas las distribuciones GNU/Linux ya tendrán este depurador instalado o en su defecto, lo encontraran en su administrador de paquetes preferido/formato de paquetes preferido (deb,rpm, etc..).

Me entere del programa entrado al canal de IRC de gentoo en freenode.org, la cuestión es que probaba el proyecto de fin de semestre para “Programación de Sistemas” en Gentoo, como la interfaz gráfica es usando Ncurses no creí que hubiera error alguno y bueno, paso lo que menos me imagine el programa brinco y aborto la ejecución al iniciar la compilación (el proyecto es un “Editor de Textos” para implementar el manejo de un compilador :P ). Entre mi dije, demonios!! yo que creía que todo iba ser miel sobre hojuelas :( , en fin, después de probarlo hace unos minutos me encontré con el error y supe solucionar :D .

Ahora empecemos con la parte práctica que es la más me gusta, para compilar un código con información útil para gdb hay que hacerlo de la siguiente manera (opción: –ggdb):

g++ [nombre].cpp -lncurses -ggdb -o [nombre_binario]

Para iniciar gdb con el binario es tan simple como poner el comando con el mismo nombre y el ejecutable a depurar:

Se puede ejecutar gdb sin argumentos ni opciones; pero la manera mas
comun de comenzar GDB es con uno o dos argumentos, especificando un
programa ejecutable con el argumento:

gdb programa

soullost@UnderHouse ~/c++/curses/editor $ gdb [nombre_binario]
GNU gdb 6.6
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...
Using host libthread_db library "/lib/libthread_db.so.1".
(gdb)

Aquí empieza lo interesante.

Poner un breakpoint (lugar donde se detendrá el programa en ejecución para hacer acciones de depuración):

break [fichero:]funcion
Pone un punto de ruptura en funcion (en fichero).

(gdb) break separar
Breakpoint 1 at 0x804ad44

Para iniciar la ejecución de programa:

run [arglist]
Comienza tu programa (con arglist, si se especifica).

(gdb) run

Si establecimos un breakpoint, se detiene el programa y posteriormente después de realizar algunas acciones (como mirar valor de variables, adelantar unas líneas, etc..) queremos que el programa se siga ejecutando normalmente hacemos:

c Continua ejecutando tu programa (despues de parar, p.e. en un
punto de ruptura).

 (gdb) c 

Para mirar la pila de los eventos guardados por gdb:

bt Backtrace: muestra la pila del programa.

(gdb) bt
#0  0xffffe410 in __kernel_vsyscall ()
#1  0xb7cb7101 in raise () from /lib/libc.so.6
#2  0xb7cb88e8 in abort () from /lib/libc.so.6
#3  0xb7cedcbb in __libc_message () from /lib/libc.so.6
#4  0xb7cf3a00 in malloc_printerr () from /lib/libc.so.6
#5  0xb7cf56f9 in free () from /lib/libc.so.6
#6  0x08049bd8 in analizadorLexico ()
#7  0x0804ae76 in separar ()
#8  0x0804c727 in main ()

En este caso nos menciona más o menos lo siguiente:

#2 Abortado
#3 Aviso Error
#4 Aviso Error
#5 Ejecución de la función free()
#6 Entra a analizadorLexico()
#7 Entra a separar()
#8 Entra a main

Ya nos dijo que el error existe después de llamar a free(), para asegurarnos ejecutamos nuevamente el programa con las opciones next y step:

next. Nos dice en que línea va ejecutando el programa pero con un peculiaridad, si existe la llamada a una función simplemente la ejecuta y continua con la línea posterior después de la llamada a la función.

step. Lo mismo que lo anterior pero este si entra a la función y no simplemente la ejecuta, por lo que si se topa con alguna, entrará a la función y se ejecutará paso a paso desde la primera línea y al terminar regresará al punto donde fue llamada la función para continuar.

Ejemplo, continuando con la depuración del editor que nos causaba problemas:

(gdb) next
660                     while(ptrToken){
(gdb) next
661                             strcpy(tokens[z].nombre,ptrToken);
(gdb) next
662                             tokens[z].linea=i;
(gdb) next
663                             z++;
(gdb) next
664                             ptrToken = strtok(NULL," ");
(gdb) next
660                     while(ptrToken){

Cuando se usa step y pasa a ejecutar una función paso a paso.

(gdb) step
analizadorLexico (token=0x804f7a0 "inicio", linea=0) at main.cpp:702
702             int w=0;

Si en algunas casos queremos mirar el valor de alguna variable podemos usar print:

print expr
Muestra el valor de una expresion.

(gdb) print tokens[i]
$1 = {nombre = "inicio\000\000\000", linea = 0}

Y bueno, es algo básico que me ayudó a mirar el error que provocaba que el programa abortara la ejecución, el error tuvo que ver con la llamada a free() y que con comentarlo bastó para solucionarse :shock: y fue bastante raro porque en Dev C++ no provoco error alguno y el programa en windows corre bien.

Corriendo el programa en gnome-terminal :D

Editor

Si están interesados en más información sobre gdb pueden mirar:
man gdb (consola)
info gdb (consola)
http://www.ldc.usb.ve/~figueira/Cursos/ci3825/taller/material/gdb.html
http://www.ac.uma.es/educacion/cursos/informatica/FundSistOp/gdb.pdf

Hay bastante más información en google :P , nos vemos ;) .

Califica el tema:
1 Star2 Stars3 Stars4 Stars5 Stars (1 votes, average: 5 out of 5)
Loading ... Loading ...

Temas Relacionados:
  • Soporte para webcam con emesene en GNU/Linux
  • Emesene a convertirse en el IM oficial para GNU/Linux
  • Notepad++ y TASM
  • HACHA para GNU/Linux
  • Script para grabar imagenes de XBOX en GNU/Linux
  • 5 Responses

    1. zer0 Says:

      Interesante.

    2. Fernando Says:

      Uh! Qué buen artículo!
      Justamente le estoy metiendo a programación en C con GCC e intentando dominar Emacs, leer algo de GDB me viene al pelo.

    3. soullost Says:

      Posiblemente les podría interesar:

      http://www.drk.com.ar/docs/development/conociendo_gdb.php

      Tengo entendido que Emacs usa por defecto GDB como depurador :P .

      saludos!!

    4. moreno delgado Says:

      esta pagina es un asco

    5. soullost Says:

      :)

      Tal vez te guste http://www.metroflog.com / http://www.yuvutu.com

    Leave a Comment

    Your comment

    You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

    Please note: Comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.