viernes, agosto 24, 2007

Depurando con Xailer

En los últimos 2 días, van 2 usuarios de Xailer que me dicen que no utilizan el depurador porque "no sé como hacerlo".... ¡ increíble ! Jose e Ignacio escribiendo líneas y líneas de código para que no lo usen los usuarios, malo malo, y bueno, que 2 usuarios en 2 días me salgan con que no lo usan porque no saben como, está mas mal todavía, así que he decidido escribir la guía rápida de depuración con Xailer.

Uno de los componentes mas potentes de Xailer, es el depurador de código, el debugger en otras palabras, me acuerdo en los lejanos días del Summer 87, que había "algo así" como un depurador de código, que si bien no era nada eficiente, algo permitía hacer, luego vino el depurador del Clipper 5.x, realmente MUY trabajado, buenísimo, pero hubo algo mucho mejor: MrDebug, ese si ya era el no va mas de los depuradores para Clipper, solo le faltaba que pudieras modificar el código para que fuera perfecto, te presentaba hasta las tablas y browses de las mismas en tiempo de ejecución de tu programa, estaba super bien hecho ese depurador.

Pero luego vino Windows, y bueno, en Windows no es tan fácil hacer un depurador, sobre todo cuando estas trabajando con entornos MDI, como decimos en México, ahí es donde tuerce el rabo el cerdo.

Los que venimos de FiveWin, ya nos habíamos aconstumbrado al sistema de "banderas" es decir a los "?" y a los MsgInfo(), a los Browse() y a los MsgList() metidos por todo el programa para verificar valores de varibles y para controlar el flujo del programa, sin embargo otros productos de desarrollo para Windows como VB y Delphi contaban con sistemas de depuración desde sus primeras versiones.

Xailer no es la excepción y cuenta con un extraordinario depurador que además es increíblemente simple de utilizar y las opciones con las que cuenta son para ponerse a babear un rato pensando ¿ cómo hicieron esto ?, veamos como utilizarlo:

Lo primero que tenemos que hacer, es abrir nuestro proyecto Xailer e indicar que nuestros programas tienen que compilarse con la opción "/B", que si bien recuerdas, es la opción que en Clipper activaba el depurador, pero como en Xailer no se indican las banderas de compilación directamente, lo haremos desde el Menú Principal del IDE opción: PROYECTO / PROPIEDADES DEL PROYECTO, aparecerá un fomulario con esta apariencia:



Selecciona del árbol de la izquierda la opción [x]Harbour y marca la casilla que dice "INCLUIR INFORMACION DE DEBUGGER", y luego haz click en el botón de aceptar.

Eso es todo..... ¿ Cómo así ?, ¿ Solamente eso ?, ¿ no necesito mas ?, pues no, de momento, eso es lo único que tienes que hacer para indicar que tu programa debe compilarse con información para el depurador, el famoso switch "/b" de Clipper.

Para que todo nuestro código fuente pueda ser analizado por el depurador de Xailer, deberemos RECONSTRUIR el proyecto en su totalidad, así que presionaremos Alt+F9 en el IDE o bien desde el menú principal en la opción PROYECTO / RECONSTRUIR

Ya estamos casi listos, antes de ejecutar nuestro programa y para activar el depurador, tendremos que incluir en nuestro código fuente los llamados "PUNTOS DE RUPTURA", ¿ que son ?, pues simplemente son indicaciones para el depurador de la línea dentro del código fuente donde deseamos detener la ejecución del programa, para ello, en el editor de código fuente, seleccionamos el PRG sobre el cual queremos hacer la depuración y nos vamos a la línea donde queremos que el programa se "detenga" para analizar hasta ese punto su comportamiento.

Para marcar los puntos de ruptura en el código fuente, utilizaremos una opción del Menú del IDE que por lo que me doy cuenta casi nadie utiliza, que es la opción EJECUTAR , y seleccionaremos de ella la opción PUNTO DE RUPTURA, puedes también utilizar las teclas Ctrl+F5, y verás como dentro del código fuente de tu programa, la línea donde tenías el cursor, cambia de color:



Puedes marcar tantos puntos de ruptura como quieras, en tantos PRGs de tu proyecto Xailer quieras, que te olvidaste de poner algún punto de ruptura antes de ejecutar el programa, no hay problema, aún en tiempo de ejecución del programa puedes incluir mas puntos de ruptura en el código fuente.

El flujo del programa lo iremos controlando desde la ventana del depurador, como veremos un poco mas adelante.

Ahora sí, ya estamos listos para ejecutar nuestro programa, hemos activado las opciones de depuración, hemos reconstruido nuestro proyecto, y hemos marcado nuestros puntos de ruptura en el código fuente, ¿ y ahora que sigue ?

Pues ahora llegó el momento de experimentar por nosotros mismos el depurador, ejecuta tu programa, y verás que todo se ejecuta normalmente , hasta que llegues a la línea de tu código fuente donde marcaste el primer punto de ruptura, cuando llegues ahí, la ejecución de tu programa se detiene, y aparece el editor de código junto con una ventana como esta:



Esta es la ventana del depurador de Xailer, a través de ella tenemos acceso tanto a controlar la ejecución del programa, como a analizar los valores de las variables visbiles en ese punto del programa, además de poder analizar nuestras "areas" de trabajo (hablando de DBFs), también podemos visualizar el estado de los SETs (SET DATE, SET EPOCH, SET CENTURY, etc) y el "Call stack" o pila de llamadas, es decir desde que línea en que función fue llamada la rutina en la que nos encontramos actualmente.

La ventana del depurador está dividida en la siguientes secciones, analizaremos cada una de ellas detenidamente:


Hablemos primero del Inspector de Variables, como puedes apreciar en la imagen, tienes acceso a todos los tipos de variables soportados por xHarbour, incluyendo los objetos, lo sorprendente de esto, es que además de tener una lista super completa de los los valores de las variables ¡¡¡¡ ES POSIBLE CAMBIARLOS EN TIEMPO DE EJECUCION !!!!!, si leíste bien, sin importar que sea un objeto, una local, o una pública asignada a un valor en el código fuente, el inspector de variables te permite cambiar su valor, o de cualquiera de sus datas, en tiempo de ejecución del programa, veamos como:

Cuando tu das doble click sobre alguna de las variables que aparecen en el inspector, aparece un formulario donde podrás cambiar el valor de dicha variable, algo parecido a esto:



Simplemente teclea el nuevo valor, presiona la tecla aceptar y ¡ listo !, haz cambiado el valor de una variable en tiempo de ejecución.

¿ Qué pasa si el tipo de variable es algo mas complicado, por ejemplo un array ?, esto es una gozada, si la variable a editar es un array, entonces Xailer te muestra TODOS los elementos del ARRAY en una estructura de árbol, y si tienes arrays anidados, pues te mostrará otro árbol dentro de la rama del árbol original:



Y para editar los valores del array, pues igual que lo anterior: doble click en el elemento, aparece el formulario de modificación de valor, lo cambias y ¡ listo !

Y bueno, si la variable en cuestión es un Formulario Xailer, es decir, un objeto con todas sus propiedes, que a su vez contiene otros controles dentro, que a su vez tienen propiedades, ¿ como lo depura Xailer ?

Un objeto, para los que no lo sabían, es en realidad un array, así que para depurar un objeto, el inspector de variables utiliza la misma técnica que para depurar arreglos, solo que la presentación es un poco distinta:



Como verás tienes acceso a TODAS las propiedades de un objeto obviamente también las puedes cambiar en tiempo de ejecución, si ese objeto contiene COMPONENTS adicionales, como es el caso de un formulario que tiene controles o datasets y datasources, el depurador te los mostrará con letras negritas, y dando doble click sobre ellos tendrás acceso a sus propiedades para revisarlas y/o modificarlas.

Cabe mencionar que las 2 ventanas anteriores son MODALES, con lo cual, será necesario que las cierres para que puedas continuar con la depuración de tu programa.

La zona de mensajes del debugger está diseñada para que puedas enviar "mensajes" que se desplegarán en esa zona mediante la función de Xailer OutDebug(), para que no extrañes los mensajes del tipo "ya llegó", "si entró" o bien si quieres desplegar el valor de algún paramétro variable no visible por el depurador, alguna PRIVATE por ejemplo, entonces mediante la función OutDebug() el mensaje será desplegado en la ventana de mensajes del debugger, en el siguiente ejemplo te muestro la llamada a OutDebug("hola") en la línea 51 del editor de código fuente y como se vería en la ventana de mensajes del depurador:




Para borrar la lista de mensajes del depurador, presiona la cruz roja, el último icono de la barra y desaparecerán todos los mensajes de depuración que tenga esta ventana.

Pasemos ahora a estudiar el control de flujo del programa, que mas bien tendría que haberlo llamado control de ejecución del programa.

Una vez que nuestro programa se ha detenido en la línea donde tiene marcado el punto de ruptura, utilizaremos los 5 primeros botones de la barra de la ventana del depurador para ir controlando la ejecución del programa:



El primer botón, el de la flecha verde, continuará la ejecución del programa hasta que se encuentre con el siguiente punto de ruptura, si no hay mas puntos de ruptura en el programa, el programa se ejecutará como normalmente lo hace, si se encontrara algún punto de ruptura mas adelante dentro del código el programa se detendrá al llegar a él.

El segundo botón (rectángulo azul), detiene la ejecución del programa, y regresa el control al IDE de Xailer.

Los siguientes 3 botones son los mas importante para el control de ejecución.

El tercero ejecuta línea por línea el programa deteniéndose en cada línea para que puedas ver como cambia los valores en el inspector de variables, ten en cuenta que cada vez que pulses este botón iras viendo en el editor de código fuente, en que línea se encuentra la ejecución del programa.

¿ Qué pasa si en una línea que estés depurando hay una llamada a una función ?, algo como esto:

cAlias := OpenDBF("archivo.dbf",.T.,.F.,5)

Si este es el caso tienes 2 opciones y es aquí donde entra en acción el 4to. botón, supongamos que tu quieres mirar paso a paso lo que hace la función OpenDBF(), en ese caso continúa presionando el 3er botón y verás como el editor de código fuente te lleva al PRG donde está dicha función, y podrás ejecutarla línea por línea (el inspector de variables se actualizará con los nuevos valores), puedes continuar presionando el 3er botón hasta que termine la función y el flujo del programa regrese a la línea desde donde fue llamada.

Supongamos ahora que no te interesa saber lo que hace la función OpenDBF(), para evitar entrar el la función, tendrás que presionar el 4to botón: ejecutar saltando funciones con eso, el depurador no te mostrará paso a paso la ejecución de la función OpenDBF(), pero si la ejecutará, y guardará el valor en la variable cAlias, esto es sumamente útil cuando conoces de antemano que los procesos que ejecuta una función son correctos.

Finalmente tenemos el 5to. botón que es ejecutar hasta el final de la función, presionando este botón, la ejecución de programa continuará sin visualizar la ejecución línea por línea hasta que llegue al RETURN de la función o método, cuando llegue ahí se detendrá nuevamente, como si tuviese un punto de ruptura establecido, como es de imaginar, los valores del inspector de variables están actualizados, este modo de ejecución es sumamente útil cuando te interesa solo conocer el valor final de las variables después de ejecutar una función o método.

Como verás, el depurador de Xailer es bastante completo, pero aún hay mas sorpresas, hay 3 inspectores mas que pueden ser de mucha utilidad en un momento dado:


El mas impresionante de los 3 es es Inspector de áreas de trabajo, si estas trabajando con DBF ya sea con índices NTX o CDX o bien con Advantage Database Server, este inspector proporciona información muy valiosa sobre el estado de las áreas de trabajo y de las tablas abiertas:



Del lado izquierdo del inspector de áreas de trabajo, tienes el "área" y el "alias" de todas las tablas que tengas abiertas en ese momento, ¿ que cuantas tablas abiertas al mismo tiempo soporta Xailer ?, bueno yo creo que esa respuesta nos la da xHarbour directamente, en teoría, si Clipper podía tener abiertas 256 áreas de trabajo, 16^2 (aunque todos sabemos que esto no es cierto, depende del valor de Files y buffers configurado en el config.sys y de la cantidad de memoria del equipo que ejecute el programa), xHarbour puede tener 32^2, osea 1,024, este valor si es real, aunque no he tenido oportunidad de comprobarlo, lo que si puedo asegurarles es que yo he abierto mas de 150 áreas simultáneamente y nunca he tenido ningún problema ni con xHarbour ni con Xailer.

Pero volvamos al depurador de Xailer, en la sección de "áreas y alias", del lado izquierdo de la ventana, podrás saber exactamente en que área esta cada tabla DBF, este inspector es particularmente útil si trabajas con la técnica de "alias dinámicos".

Del lado derecho de la ventana tenemos información valiosa sobre la tabla que tenemos seleccionada, como por ejemplo que RDD esta usando, si está abierta como exclusiva o compartida, cuantos registros tiene, en que fecha fue modificada por última vez, etc. pero hay mas información importante marcada en el árbol con letra negrita.

Tenemos por ejemplo acceso a la estructura de la tabla:



Si la estructura de la imagen anterior no te suena mucho a DBF (si te fijas hay un campo tipo SHORTINT y otro tipo DOUBLE), es porque no es un DBF, es una tabla ADT de Advantage, y los tipos de datos son distintos que los DBFs aunque para manipularlos desde programa se haga igual que con los tipos de datos normales de un DBF.

Veamos ahora la sección RECORD, que nos presenta información sobre la posición del puntero de la base de datos:



Como verás nos indica en que registro está el puntero de la base de datos, si el registro está borrado o bloqueado, y lo mas importante, nos muestra los valores ACTUALES que tiene dicho registro, indicando además el nombre del campo, su tipo y longitud.

Por el lado de los índices también tenemos acceso a información muy interesante, como los nombres de los tags, condiciones de indexación, número de registros en el índice, etc:



Nota que además de toda la información que tiene acerca de un índice, el depurador de Xailer también te dice que tag es el que está activo actualmente.

Para terminar con el inspector de áreas de trabajo, también tenemos acceso a los filtros que tenga la tabla en un momento dado:


Aquí podemos analizar la expresión de un filtro, y si el filtro está activo o no.

Veamos ahora el Inspector de valores SET:



Este inspector nos muestra los valores de nuestro entorno de trabajo establecidos por los comandos SET....., no son valores editables, es decir, no se pueden cambiar en tiempo de ejecución, incluso te darás cuenta que hay valores SET que en la vida los había escuchado nombrar (yo por lo menos) ,¿ que hace SET EXTRAFILE ?, o ¿ para que sirve SET DIRCASE ?, creo que tendré que echarle un vistazo al manual de xHarbour.

Por último tenemos el Inspector de Call Stack, o de las pila de llamadas a las funciones, que nos muestra la lista de funciones previas a la que estamos ejecutando en este momento, así como la línea desde la cual fue llamada la función anterior, esta información también es de suma importancia porque puedes saber cual que función o método llamó desde que línea a cual función o método:




¿ Como afecta el depurador al EXE final si se me olvida quitar las opciones del depurador ?.

De ninguna manera, el depurador solo es utilizable desde dentro del IDE de Xailer, si tu distribuyes tu EXE y olvidaste compilarlo quitando las opciones de mensajes del depurador, tu usuario final ni siquiera notará nada.

¿ Qué le falta al depurador de Xailer ?, desde mi punto de vista y viniendo yo de una herramienta que carecía de depurador, todo lo que hace Xailer me parece una pasada, sin embargo en cada curso tengo mas "disidentes" de otros lenguajes de programación, mayoritariamente Visual Basic y FoxPro, y cuando vemos el tema del depurador me comentan.... "¿ y como hago para regresar X lineas y que vuelva a ejecutar las instrucciones desde ahí ?, en Visual Basic se puede".... respuesta: En Xailer (de momento), no se puede. Sin duda si me pidieran alguna mejora al Debugger yo pediría eso, poder "devolver el flujo del programa a una linea X y volver a ejecutar desde ese punto", comprendo que es complicado, pero bueno, si se trata de pedir yo pido.

El depurador de Xailer es sin duda una de las piezas de software mas finas que me haya tocado analizar, posee un grado de sofisticación difícil de igualar aun por los depuradores de otros lenguajes de programación, ya no hablemos de cualquier otra GUI para xHarbour, dudo muchísimo que el mismo Visual xHarbour pueda llegar a tal refinamiento para la depuración.

En una de esas interesantes charlas que sostengo con Ignacio cada vez que paso por sus oficinas en Madrid, me comentaba que "tal vez", trabajando un poco, sería posible hacer funcionar el depurador de Xailer con alguna otra GUI para xHarbour, por medio del XEdit que es la herramienta gestor de proyectos / Editor editor de código / gestor de compilación para xHarbour que puedes descargar gratuitamente desde la web de Xailer (el XEdit hace muchas, pero muchas cosas que ni siquiera te imaginas), pero que el Xailer Team había decidido que el depurador sería exclusivamente para Xailer, lo siento por las otras GUIs, se perdieron de una gran herramienta, pero los usuarios de Xailer ganamos una herramienta que nos va a recortar enormemente el tiempo de depuración, adiós a los MsgInfo() regados por todo el programa.

4 comentarios:

Anónimo dijo...

René, buenísimo, yo tampoco lo usaba. y eso que probé varias veces con los puntos de ruptura y no me funcionaba porque no lo habilitaba en el proyecto.

Mario

wilson dijo...

Maestro, excelente , ya estoy usandolo, gracias
Podrias informar en tu blog las fechas de los cursos de Xailer en Mexico en mes de septiembre ?? o solo vas a dictar estos que anuncias los primeros dias ??
saludos desde Quito Ecuador

JORGE dijo...

Cordial saludo.

Es posible utilizar este xedit, para generar exe de xharbour modo consola, sin usar xailer.

JORGE EDUARDO

Rene Flores dijo...

Si, y también se puede utilizar el Debugger en aplicaciones de modo consola.

En unos dias publicare un articulo sobre el nuevo xEdit que incluye ademas un DBU integrado en el editor.