Hola, sean bienvenidos. En este post hablaremos sobre como depurar nuestros programas, cuando hablamos de depurar es la accion de ver los recursos utilizados por nuestro codigo fuente al ejecutarlo, esto es util para ver y analizar sus comportamientos.
Los compiladores pueden trabajar con o sin simbolos, si lo hiciera con simbolos se creara un mapeo necesario entre el codigo fuente y su programa generado, esto es utilizado para apuntar la linea del codigo fuente correspondiente a la siguiente accion del programa. Los depuradores permiten las siguientes acciones en nuestro codigo fuente:
- Ver los resultados de cada instruccion ejecutada
- Ver el estado actual de cada variable
- Examinar estructuras de datos complejos
- Visualizar el valor de los datos miembros en las clases
- Ver los valores actuales en memoria de varios apuntadores y otras ubicaciones en memoria
Para nosotros poder usar el depurador GNU, tambien conocido como gdb, es asegurarse de al momento de compilarse se haya incluido el codigo requerido en el archivo ejecutable, esta informacion le permite al depurador saber donde se guardan las variables, los nombres de estas y de las funciones, y por ende como relacionar el codigo fuente con el codigo binario. En forma predeterminada, cuando compilamos un programa esta informacion no es cargada en el programa, el motivo es porque reduce el tiempo de ejecucion y ocupa mas espacio en la memoria y por esto nosotros debemos informarle al compilador para incluirlo, la forma es la siguiente:
g++ -g codigo.cpp -o programa
Una vez compilado de esta forma podremos utilizar el depurador, hasta aqui hemos hablado de como funciona y habilitarlo en nuestro programa pero es necesario instalarlo y para esto debemos bajaarlo del repositorio de la distribucion de tu linux, en el caso de haber hecho desde el principio del curso estaran usando Debian y por ende de debe usar esta linea:
tinchicus@dbn001dsk:~/lenguaje/c++$ sudo apt-get install gdb
Una vez instalado, estos son algunos de los comandos disponibles para poder utilizar en gdb.
Descripcion | Valor |
break [archivo:]funcion | Establece un punto de interrupcion al entrar a funcion en archivo, archivo es opcional |
bt | Forma abreviada de backtrace: muestra la pila del programa |
c | Continua la ejecucion del programa despues del punto de interrupcion |
disassemble | Muestra el codigo binario como codigo en lenguaje ensamblador en vez de lenguaje fuente |
display exp | Muestra el valor de la variable exp cada vez que el programa se detenga |
help | Muestra la ayuda en general, acompañado con el comando muestra las opciones de ese comando |
list [[archivo:]linea] | Muestra ±5 lineas del codigo fuente. archivo y linea especifican el codigo fuente a mostrar y son opcionales |
next | Ejecuta el siguiente paso del programa sin entrar en las funciones llamadas |
print exp | Imprime exp, donde exp puede ser una variable, nombre de funcion o expresion compleja, el nombre de un Array, Esto permite examinar la memoria |
quit | Sale del gdb |
run arglista | Ejecutar el programa desde el principio con la lista opcional de argumentos de linea de comandos, contenidos en arglista |
set variable = exp | Asigna a una variable del codigo fuente un valor. Esto permite alterar el estado de la memoria |
set | Modifica las variables del entorno de gdb |
step | Ejecutar el siguiente paso del programa, entrar en cualquier funcion llamada |
undisplay | Cancelar un despliegue |
watch | Crea un punto de observacion |
whatis exp | Despliega el tipo de datos de exp |
El depurador tambien acepta opciones de linea de comando, para invocarlo en general podemos hacerlo de esta forma:
tinchicus@dbn001dsk:~/lenguaje/c++$ gdb tinchicus@dbn001dsk:~/lenguaje/c++$ gdb suprograma
Tambien se puede utilizar para depurar cuando falla en la ejecucion, por ejemplo bajarlo a un archivo llamado core, donde se podra examinar la memoria y la pila de llamadas, la forma de llamarlo es asi:
tinchicus@dbn001dsk:~/lenguaje/c++$ gdb suprograma core
Pasemos a hablar un poco sobre el uso de algunos de los comandos presentados anteriormente, estos son algunos de los mas utilizados.
Puntos de interrupcion (break)
Los puntos de interrupcion son instrucciones indicadoras al depurador cuando se llegue a una linea especifica el programa debe detenerse, esto nos permitira ejecutar el programa sin interrupcion hasta la linea indicada y con esto podras analizar la condicion de las variables hasta y despues de la linea critica.
Puntos de observacion (watch)
Los puntos de observacion permiten solicitar al depurador mostrar un valor especifico o detener al leer o escribir una variable especifica, y algunas veces permiten modificar el valor de una variable mientras el programa esta en ejecucion.
Examen y modificacion del estado de la memoria (print)
Algunas veces necesitamos ver los valores almacenados en memoria, actualmente los depuradores pueden mostrar en el formato de la variable actual, cadenas como caracteres, enteros como numeros en lugar de mostrarlos como cuatro bytes y asi sucesivamente. Tambien es posible mostrar clases completas y mostrar el valor actual de todas las variables miembro, e igual al caso anterior permite cambiar los valores de las variables cuando el programa se esta ejecutando.
Desensamble (disassemble)
Algunas veces con leer el codigo fuente no es suficiente para descubrir un bug (error), para circunstancias mas extremas es posible ver por medio del depurador el codigo en ensamblador generado para cada linea del codigo fuente, por medio de esto se puede examinar los registros, la memoria y sus indicadores. y por lo general ahondar en el funcionamiento interno de su programa tanto como lo requiera.
Por ultimo vamos a ver un caso de como utilizar el gdb en la vida real, primero vamos a crear un programa con la opcion para depurarlo:
tinchicus@dbn001dsk:~/lenguaje/c++$ g++ -g error01.cpp -o error01a
Luego utilizaremos el comando gdb y como quedamos finalmente en el programa:
tinchicus@dbn001dsk:~/lenguaje/c++$ gdb error01a GNU gdb (Debian 7.12-6) 7.12.0.20161007-git Copyright (C) 2016 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 "i686-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"… Reading symbols from error01a…done. (gdb)
Y por ultimo usaremos un comando simple llamado list:
(gdb) list 51 if (tamanio < 10) throw xMuyChico(); if (tamanio > 30000) 52 throw xMuyGrande(); 53 if (tamanio < 0) 54 throw xNegativo(); 55 apTipo = new int[ tamanio ]; 56 for(int i = 0; i < tamanio; i++) 57 apTipo[ i ] = 0; 58 } 59 60 int main() (gdb)
Hasta aqui hemos visto de que se trata, como trabaja y como usarlo al depurador en nuestros programas, tambien los usos principales utilizados para disminuir al minimo los «bugs» en nuestro programa, espero les haya sido util sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.
Tengo un Patreon donde podes acceder de manera exclusiva a material para este blog antes de ser publicado, sigue los pasos del link para saber como.


Tambien podes donar
Es para mantenimiento del sitio, gracias!
$1.50