lunes, 30 de julio de 2012

Espejitos de Colores

Vengo a develar el oscuro misterio que envuelve a mi computadora cuando se conecta a un proyector para dar clases. Los más supersticiosos dicen que el código se escribe solo, los escépticos quieren saber por qué. Yo no entiendo nada...

Uno, como desarrollador de un proyecto de software que a su vez consume (que uso para mis otros desarrollos o para mis clases), tiene una posición de privilegio. Porque si uno programa para otro, tiene que hacer ingeniería de software de la que no me gusta hacer. Hay que averiguar que necesita el usuario (averiguar no es preguntarle, normalmente el usuario no sabe ni qué quiere ni qué se puede hacer), hay que entender su posición, imaginar el detalle de los casos de uso, identificar los problemas, proponer las mejoras, etc. Estando a la vez en la posición del desarrollador y del usuario, no hay tanto que adivinar. Generalmente creo que sé que me gustaría ver en mis programas, y sé qué puedo implementar y que no (aunque también suelen sorprenderme gratamente sugerencias de otros usuarios o características de otros entornos que no se me habían ocurrido).

lunes, 23 de julio de 2012

Cómo prepararse para enfrentar un segfault (parte 2)

En la primer parte comenté cómo hacer para que un programa simule un punto de interrupción si encuentra una condición inesperada. Buscando algo más en google, encontré algunas otras macros interesantes, diseñadas para generar errores en tiempo de compilación y ya no de ejecución. Si bien esto no cuadra con el título (más abajo hay otros ejemplos que sí), igual vale la pena comentarlo para completar el tema de los asserts y la macro _revienta que empezé en la primer parte. Se basan en errores como declarar arreglos con tamaños negativos, o tratar de utilizar especializaciones de una plantilla que no existen. La idea de la primer versión es (simplificado y con llaves extra para evitar un problema cuando hay mensajes repetidos):
    #define _compile_assert(x,mensaje) { char _compile_assert##mensaje [x?1:-1]; }
    ....
       _compile_assert(sizeof(T1)
            <sizeof(T2),EL_TAMANIO_DE_T1_DEBE_SER_MENOR_QUE_EL_DE_T2);
que va a generar un error del tipo"error: size of array '_compile_assert_EL_TAMANIO_DE_T1_DEBE_SER_MENOR_QUE_EL_DE_T2' is negative", pero que también va a generar un warning del tipo "unused variable '_compile_assert_EL_TAMANIO_DE_T1_DEBE_SER_MENOR_QUE_EL_DE_T2'" si estos warnings están habilitados. La ventaja de este enfoque es que permite insertar en el mensaje de error algún texto propio para agregar más información. El segundo enfoque no, pero aún así me parece más elegante:

jueves, 19 de julio de 2012

Cómo prepararse para enfrentar un segfault (parte 1)

Segfault (segmentation fault, violación de segmento) es un intento por parte de un proceso de hacer algo "ilegal" como por ejemplo desreferenciar un puntero a NULL, escribir en un arreglo en posiciones fuera de los límites válidos, etc. Usualmente el sistema operativo envía una señal al proceso y hace que el programa se cierre. Si lo habíamos invocado desde una consola vemos el discreto mensaje "Segmentation fault". En Windows veríamos esa molesta ventana de la que lo único que recuerdo es que tiene un botón que dice "No enviar" (otrora una escalofriante pantalla azul). Cuando un programa tiene que lidiar con estructuras de datos complejas, o que hacer operaciones complejas en estructuras no necesariamente tan complejas, suelen aparecer estos problemas, y muy frecuentemente están asociados al manejo de memoria dinámica, punteros, o índices en arreglos. Por ejemplo, a mi me pasa mucho cuando hago operaciones sobre mallas en mi trabajo (donde hay muchas referencias cruzadas que mantener), o muchas veces cuando cambio algo en el parser de ZinjaI (ya que la forma en que almacena su información es bastante rebuscada). En general estos errores son difíciles de depurar, ya que a menos que se hayan tomado los recaudos necesarios, el problema puede saltar en un punto de la ejecución alejado de una u otra forma del punto en donde realmente se metió la pata. La idea de estos post es comentar mi experiencia intentado cazar estos errores y tirar algunos tips muy útiles que aprendí en el camino.