2010-11-23 41 views
22

Je développe une bibliothèque en utilisant un certain nombre de structures de données glib (GHashTable, GSList, etc.). J'ai vérifié mon code fréquemment pour des fuites de mémoire en utilisant valgrind. La plupart des problèmes soulignés par Valgrind sont assez faciles à résoudre, mais il y en a quelques-uns que je n'arrive pas à comprendre.Valgrind signale une perte de mémoire lors de l'utilisation de types de données glib

Tous ces éléments sont signalés comme «éventuellement perdus».

Au sommet du stacktrace valgrind, je trouve toujours les mêmes 4 bibliothèques:

==29997== 1,512 bytes in 3 blocks are possibly lost in loss record 24 of 25 
==29997== at 0x4004B11: memalign (vg_replace_malloc.c:532) 
==29997== by 0x4004B6B: posix_memalign (vg_replace_malloc.c:660) 
==29997== by 0x5E9AC4: ??? (in /lib/libglib-2.0.so.0.1200.3) 
==29997== by 0x5EA4FE: g_slice_alloc (in /lib/libglib-2.0.so.0.1200.3) 

Plus bas dans la pile d'appel, il y a toujours un appel à une fonction bien pendue, comme g_key_file_new(), g_slist_prepend(), g_strsplit(), g_key_file_load_from_file(), g_file_get_contents().

Mes questions sont les suivantes:

  • Quelqu'un at-il rencontré ce et a trouvé un moyen de contourner cela?

  • Ou est-ce quelque chose que je peux ignorer? Est-ce dû au glib utilisant des pools de mémoire, comme suggéré here?

J'utilise

  • valgrind-3.5.0
  • glib-2.12.3
  • gcc (GCC) 4.1.2 20.080.704 (Red Hat 4.1.2-48)
  • CentOS version 5.5 (final)

Répondre

32

GLib a quelques caractéristiques qui brouillent Valgrind. Un des pools de mémoire (g_slice dans new glib, "mem chunks" dans l'ancien). Ce sont des allocateurs spécialisés utilisés pour les petits objets tels que les noeuds de liste. Vous pouvez l'utiliser pour désactiver l'allocateur de tranche: G_SLICE=always-malloc valgrind myprogram

Un deuxième problème est que parfois GLib évite d'initialiser une nouvelle mémoire ou de conserver des pointeurs morts dans les tranches/blocs libérés. Vous pouvez résoudre ce problème avec: G_DEBUG=gc-friendly valgrind myprogram

Alors, ensemble, bien sûr: G_DEBUG=gc-friendly G_SLICE=always-malloc valgrind myprogram

Un troisième problème est que GLib a des variables globales qui sont tout simplement jamais libérés mais considérés comme état de programme permanent. Par exemple, GType enregistré n'est jamais déchargé, et quelques autres. Ceci n'est pas réparable, mais valgrind devrait montrer que ces allocations globales sont accessibles, plutôt que comme perdues.

+0

Exécuter le programme avec G_SLICE = always-malloc ne montre aucune mémoire perdue, qui confirme ma suspicion que toute perte de mémoire (possible) se produit à cause des pools de mémoire. Merci Havoc P pour la réponse claire. – ttreitlinger

+0

Havoc pouvez-vous confirmer que votre déclaration sur les variables globales est toujours vrai pour GLib 2.32? Merci! –

+3

oui, par exemple dans gconvert.c "static GHashTable * iconv_cache" etc. (juste un exemple) –

0

glib-2.12 est assez vieux. Essayez d'obtenir glib-2.24, compilez et installez le (avec --prefix =/usr/local/glib-2.24 par exemple) puis utilisez-le pour compiler votre application.

Si vous avez encore, essayez de lire le manuel pendue à nouveau :)

+0

Malheureusement, je suis bloqué avec cette version de glib, car le logiciel que je développe fonctionnera sur un serveur géré, avec 2.12 étant la version par défaut – ttreitlinger