Llevo algún tiempo participando en el desarrollo de una aplicación que utiliza las librería glib. Estas librerías tienen una gestión de memoria propia basada en mecanismo de slab allocator desarrollado por Jeff Bonwick para su uso en SunOS. La librería glib denomina a este sistema de gestión de memoria memory slices
Me estaba encontrando con un segmentation fault en diferentes rutinas de liberación o reserva de memoria, lo cual me llevó a pensar que estaba corrompiendo algún bloque de gestión de memoria. Aprovechando las facilidades de depurcación que ofrece la librería glib, que puede verse en running glib applications. Se puede controlar el comportamiento del sistema de gestión de memoria de la glib estableciendo la variable de entorno G_SLICE. Ésta permite tres valores:
- always-malloc Si la variable de entorno tiene este valor, el sistema rutará todas las llamadas para reservar los slices que utiliza en la gestión de memoria a través de g_malloc y g_free, que se conectan directamente con las librerías del sistema. Esto puede ser util para intentar detectar memoria que no se libera o si sobreescribimos en memoria no reservada con herramientas como valgrind.
- debug-blocks Esta opción activa las opciones de depuración y comprobación cuando se intenta liberar un
slice de memoria, comprobando que las direcciones y tamaños de los slices son adecuados.
- all Si se quieren activar las dos opciones anterioes a la vez.
Cuando me enfrenté al error tuve bastante suerte, porque al final fue un doble free que pude detectar fácilmente con el gdb:
gdb ./programa
(gdb)set enviroment G_SLICE=all
(gdb)run
.... esperar que la aplicación falle
(gdb) bt
Con el volcado de la pila que se obtiene con la orden backtrace (bt), pude ver directamente cual era el sitio donde estaba fallando el programa.