Anuncios

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.

Anuncios

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
Anuncios

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
Anuncios

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
Anuncios

Una vez instalado, estos son algunos de los comandos disponibles para poder utilizar en gdb.

 DescripcionValor
break [archivo:]funcionEstablece un punto de interrupcion al entrar a funcion en archivo, archivo es opcional
btForma abreviada de backtrace: muestra la pila del programa
cContinua la ejecucion del programa despues del punto de interrupcion
disassembleMuestra el codigo binario como codigo en lenguaje ensamblador en vez de lenguaje fuente
display expMuestra el valor de la variable exp cada vez que el programa se detenga
helpMuestra 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
nextEjecuta el siguiente paso del programa sin entrar en las funciones llamadas
print expImprime exp, donde exp puede ser una variable, nombre de funcion o expresion compleja, el nombre de un Array, Esto permite examinar la memoria
quitSale del gdb
run arglistaEjecutar el programa desde el principio con la lista opcional de argumentos de linea de comandos, contenidos en arglista
set variable = expAsigna a una variable del codigo fuente un valor. Esto permite alterar el estado de la memoria
setModifica las variables del entorno de gdb
stepEjecutar el siguiente paso del programa, entrar en cualquier funcion llamada
undisplayCancelar un despliegue
watchCrea un punto de observacion
whatis expDespliega el tipo de datos de exp
Anuncios

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 
Anuncios

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.

Anuncios

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.

Anuncios

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.

Anuncios

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.

Anuncios

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.

Anuncios

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)
Anuncios

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)
Anuncios

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.

Anuncios

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.00