martes, 23 de abril de 2013

Depuración (parte 2): Controlando la ejecución I

Habiendo introducido las nociones básicas en la parte 1, vamos a profundizar sobre los dos aspectos prácticos más importantes: el control de la ejecución y la inspección de los datos en memoria. En esta parte 2 (y la que sigue) voy a hablar del control de la ejecución. Con el control de la ejecución me refiero a cómo definimos cuándo y hasta dónde se ejecuta. Hay que saber que el mecanismo básico es el punto de interrupción, pero cualquier depurador nos provee un conjunto de instrucciones para avanzar de a poco sin tener que explicitar nuevos puntos de interrupción. Por ejemplo, si estoy detenido en cierto punto y quiero que ejecute una sola linea y vuelva a detenerse (ejecución paso a paso), tendría que poner un punto de interrupción en la siguiente línea y decirle luego que continúe ejecutando, y una vez detenido nuevamente quitar ese punto de interrupción. Si bien es un mecanismo válido, los depuradores tienen instrucciones para hacer todo esto junto y de forma transparente, de modo que al usuario el usuario ni se entere de ese punto de interrupción auxiliar. Y así, hay comandos para avanzar por linea o por instrucción (que no es lo mismo), hasta llegar a cierta línea, o hasta salir de cierta función, etc. También hay mecanismos para alterar la ejecución y volver a ejecutar una línea que ya pasamos, y otros trucos útiles. De eso habla este post.

lunes, 15 de abril de 2013

Herramientas mágicas: Memcheck (de Valgrind)

La caja de herramientas básica de todo programador debe contener mínimamente un editor, un compilador y un depurador. Y si están empaquetados en su IDE de confianza mucho mejor. Pero además del kit básico, hay varias otras herramientas dando vueltas que pueden resultar muy muy útiles en muchos casos, y que conviene conocer. Sin embargo, no siempre se conocen, y por eso empiezo esta sección, para presentarles las que yo fui encontrando con el tiempo. Son herramientas que antes no extrañaba porque no sabía que existían, a las que tal vez no les encontré el potencial de entrada, pero que después de usarlas un tiempo y explorarlas mejor me parecieron geniales. Por esto, las terminé integrando en ZinjaI, mediante el menú genérico "Herramientas", donde pongo todo lo que no es básico e imprescindible para el alumno, pero sí útil para otros usuarios algo más exigentes.

En esta primera entrega voy a hablar de memcheck, una de las herramientas incluidas en un paquete más grande que se conoce como Valgrind. Valgrind es un framerwork para herramientas de análisis dinámico. Es decir, una infraestructura para analizar automáticamente cómo se comporta un programa cuando se ejecuta (de ahí el "dinámico"). Sobre esta infraestructura se construyen herramientas específicas, por eso cuando instalamos valgrind estamos instalando varias (6 al menos) herramientas que comparten una base común respecto a cómo ejecutan y analizan el programa, pero que centran su atención en partes diferentes, y por ello extraen información diferente. La más interesante de ellas es memcheck, que sirve para analizar cómo usa la memoria un programa, y detectar errores.

lunes, 8 de abril de 2013

Depuración (parte 1): ¿para qué sirve y cómo funciona?

Si hay una habilidad imprescindible en todo buen programador, es la habilidad para depurar un programa. La depuración es en general el proceso de corregir errores, pero cuando hablamos de programación, yendo a la práctica, la clave es ejecutar el programa con un "depurador", una herramienta que nos permite interrumpirlo en cualquier momento para ver qué está haciendo o qué tiene en su memoria. Un programador habilidoso en la depuración, sabe dónde interrumpirlo o qué buscar en la memoria a la hora de encontrar la causa de un problema, o entender cierto comportamiento. Y esto se adquiere con la práctica, como todo en la programación. Hay que conocer qué pueden hacer en teoría las herramientas, pero la práctica y la experiencia nos ayudarán a decidir cómo utilizarlas. Sin embargo, hay muchas funcionalidades básicas de un depurador que puede aprovechar incluso el principiante para entender cómo funciona un ejemplo o una estructura en particular.

El problema es que a pesar de lo importante que nos parezca a muchos programadores, cuando se enseña a programar en general se le da poco y nada de importancia. En la mayoría de los casos, los libros de programación no dedican un capítulo a esto, ni los docentes dedican una de sus clases. Pareciera que es algo para aprender cuando ya sabemos programar, para dejar para cursos avanzados y segundas partes, y esa idea no puede estar más equivocada. Las nociones básicas y el hábito de usar un depurador se deben inculcar desde temprano (desde que dejamos el pseudocódigo y pasamos a un lenguaje real diría yo). Por eso, en esta serie les voy a empezar a contar a los principiantes qué se puede hacer con un depurador, y daré algunas pistas para los más curiosos o avanzados de cómo hace lo que hace, aunque esto último no sea necesario saberlo para comenzar a utilizarlo.