El programa se ejecuta sin problemas, es un programa sencillo
Pero muy de vez en cuando, el programa explota
No es fácil reproducirlo y generar ese casque
Después de bastante tiempo de observación, veo que explota después de dejarlo inactivo duranto un periodo de tiempo. Curioso
Reproduzco el error haciendo un volcado de memoria con la tabla de símbolos.
El resultado es incoherente, si ningún sentido.
Así que le paso valgrind y...
vaya, parece que hay unos cuantos errores y uno de ellos es AL INICIAR el programa
Es un error de punteros (acceso a una memoria borrada)
La librería que estoy preparado, intenta que estas cosas no puedan pasar fácilmente
* Captura y gestiona el error de división por cero de enteros
* Utiliza siempre countptr. No tienen aritmética de punteros, no se puede pedir la dirección del puntero si este no es válido...
* Contenedores con verificación de límites y validad de iteradores
* ...
Aún así hay un error en el arranque
El problema viene por un sutil cambio en el orden de un par de señales
Una señal indica el cambio de estado y la otra gestiona la acción a realizar en este cambio
¿Se debe cambiar el estado y luego generar la acción? ¿o al revés?
Supongamos que generamos la acción primero, y como consecuencia de esa acción, se genera una petición a la máquina de estados. SE HARÁ SOBRE UN ESTADO INCORRECTO (caducado, obsoleto)
Entonces, tenemos que cambiar el estado primero y luego generar la acción
Lo malo, es que al cambiar el estado, sale de ámbito el estado anterior MIENTRAS SIGUE EJECUTÁNDOSE código de dicho estado
La solución es muy sencilla, pero esa no es la cuestión. La cuestión es porqué se pueden cometer este tipo de errores sin darse cuenta, siendo estos errores tan difíciles de localizar (si no fuera por valgrind)
Y sobre todo, la cuestión es qué se puede hacer para evitarlo
Un consejo frecuente con los eventos o los signal-slot, es que se llamen al final del método
No siempre es posible
Creo que tener un signal-slot asíncrono, sería de gran ayuda para evitar estas situaciones y simplificar otras
Un signal-slot asíncrono podría trabajar fácilmente entre hebras, aunque eso no me interesa en este momento
En un sistema no paralelo, sería mejor que el sistema de signal-slot asíncronos (funcionarían de forma muy parecida a mensajes) despachara en el mismo orden en que se producen
Un sistema de signal-slot asíncrono con tipado fuerte, parece que sería caro
Con tipado débil, sería una implementación mucho más sencilla, menos memoria para datos y programa, pero sin verificación de tipos en compilación y más lento en ejecución
Volviendo al problema, un error en punteros al iniciar el programa, genera que este explote pasado bastante tiempo. Además, es necesario dejar el programa inactivo un buen rato y hacer otras cosas (lo que generará reordenación de la memoria del proceso por parte del sistema operativo)
Sin valgrind, este error sería imposible de localizar y corregir (sus efectos están demasiado lejos del punto donde se produce un error
No hay comentarios:
Publicar un comentario