Este artículo bien podría llamarse "Tips para convertirse en un ZinjaI Master (parte 5)", pero preferí ponerle un título diferente donde aparezca la palabra "Depuración" ya que trata de este tema en particular, y los tips son algo más específicos. En la pestaña Depuración del cuadro de Preferencias (al cual se accede con el ítem "Preferencias..." del menú "Archivo"), los tres últimos ítems son
bastante particulares, pero bien utilizados ayudan mucho.
El primero,
"Mejorar inspecciones automáticamente según tipo", hace que cuando
ingresemos (durante la depuración) una inspección de algún tipo
configurado allí (se configuran con el botón "Opciones" que tiene al lado), ZinjaI la
modifique automáticamente. Por ejemplo, cuando trabajamos con la clase std::string,
usualmente queremos inspeccionar el contenido de la cadena, y no la estructura de
la clase. En gcc, por ejemplo, esta clase tiene el contenido del string en un puntero llamado _M_p que
está dentro de un struct miembro llamado _M_dataplus; y la clase tiene además otras cosas que en general no nos interesa ver, como el npos. En resúmen, si el string es s, no interesa evaluar solamente el valor de "s._M_dataplus._M_p" en lugar de "s". Sin esta opción, hay que buscar dentro de la
clase el atributo que queremos, lo cual se hace fácilmente con un par de dobles clicks sobre el
valor de la inspección y borrando luego las inspecciones que sobren, pero se torna tedioso y repetitivo. Con esta opción, ZinjaI puede hacerlo automáticamente.
Prueben crear un string s, asignarle alguna cadena, detener el depurador, e ingresar "s" en la tabla de inspecciones, para ver cómo al presionar Enter se convierte en "s._M_dataplus._M_p" y pueden ver directamente el valor de la cadena. Por defecto, ZinjaI tiene configurados los reemplazos para los tipos string y wxString, los cuales pueden tomar de ejemplo para crear reemplazos para inspecciones de cualquier otro tipo que quieran.
El ante-último elemento de la pestaña Depuración es "Archivo de
definiciones de macros para gdb", y permite ingresar el nombre de un
script que ejecutará gdb antes de comenzar la depuración. En este script
se pueden definir varias cosas, pero lo más interesante son las macros, que son
como comandos para el depurador definidos por el usuario. Por ejemplo, por defecto ZinjaI
incluye macros para ver los contenedores STL. Si crean una
"std::list<algo> la_lista" y quieren inspeccionarla, no van a ver
nada útil, ya que verán la estructura de la clase list, que en este caso
ni siquiera tiene a mano el contenido como pasaba con string. Para
ver el contenido hay que saber cómo es por dentro esa clase, qué
atributos seguir para encontrar los nodos y qué cast aplicar, nada fácil. Pero si ponen
como expresión para inspeccionar ">plist int la_lista" verán el truco. Y si
después le hacen click con el botón derecho y eligen "Mostrar en tabla
separada" mejor todavía. El ">" al comienzo de la inspección le
indica a ZinjaI que no es una inspección real, sino un comando que debe
pasarle directamente a gdb; "plist" es una macro definida en ese archivo
de macros, "int" es el tipo de datos que guarda la lista, y "la_lista" es el argumento. La macro plist está escrita por alguien que conoce como es la lista de gcc por
dentro y sabe extraer los datos, y modificada por mí para que la salida se parezca a la de una clase común, y entonces ZinjaI pueda mostrarla en una tabla
separada. Si ingresan ">help" verán
una lista de las macros habilitadas, y si miran el archivo definido en
"Archivo de definiciones de macros para gdb" pueden cambiarlas o agregar
nuevas.
Y para terminar con las preferencias, una opción menos complicada y tal vez
más útil es la que dice "Fuentes a evitar para el step in". Cuando estamos depurando y
avanzamos con "Step In", si el depurador se detiene en algún archivo de
esta lista, sigue avanzando un paso más. Por ejemplo, si estamos
depurando un programa que llama a una función que recibe un string y
queremos meternos en la función, el depurador primero se meterá en el
constructor del string argumento. Una vez allí, hacemos click derecho
sobre el trazado inverso y elegimos "Evitar detenerse para este fuente"
para que ZinjaI nunca más se detenga dentro de un método de string; así
la próxima vez se salteará el constructor e irá directamente a la
función que queríamos depurar. Como ven, esta opción no hay que
configurarla desde preferencias (a menos que quieran sacar algo de la
lista), sino que es más fácil hacerlo durante la depuración, con el menú
contextual del panel de trazado inverso.
Finalmente, quiero recomendar que se tomen unos segundos para observar las opciones del menú contextual de la tabla de Inspecciones, ya que allí tal vez encuentren algo útil que no esperaban. Por ejemplo, suelo querer recordar el valor que tenía una variable en algún momento, o en alguna corrida, para luego compararla con otro valor que tome. Para ello, teniendo la inspección del primer valor, puedo usar las opciones "Duplicar inspección" para obtener una copia y "Congelar valor" para que una de las copias ya no se actualice más. Otra opción útil es la de "Mostrar en ventana separada" para ver inspecciones muy largas que no entran en la tabla, como cadenas de texto.
Las que les acabo de comentar no son las mejores ni más importantes opciones de depuración, pero sí son, dentro de las útiles, las que suelen no saber que existen. Como dije en el post anterior, espero que estos trucos les sean útiles, pero también me pondría contento que si dan buenos resultados sirvan para que se les despierte la curiosidad y se acostumbren a investigar un poco más las opciones no tan a la vista de los programas que utilicen (no solo ZinjaI, sino en general).
No hay comentarios:
Publicar un comentario