diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2019-02-09 13:01:58 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2019-02-09 13:01:58 (GMT) |
commit | 5863af232b8fc57de210702afe659a7383bb8840 (patch) | |
tree | 18e6fd0fb7be2f01d23cda34f8d7b3f29b1a250b /src/gleak.c | |
parent | 32bef30025f5e3f513c2b4936c0573cc3b629961 (diff) |
Fixed another batch of memory leaks.
Diffstat (limited to 'src/gleak.c')
-rw-r--r-- | src/gleak.c | 137 |
1 files changed, 135 insertions, 2 deletions
diff --git a/src/gleak.c b/src/gleak.c index 3212d9f..4423cbb 100644 --- a/src/gleak.c +++ b/src/gleak.c @@ -24,10 +24,12 @@ #include "gleak.h" +#include <assert.h> #include <glib-object.h> #include <malloc.h> #include <stdbool.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> @@ -39,12 +41,122 @@ #define DUMP_CLOSE_MSG "\n----------------------------------------------\n\n" +/* Description de type utilisé */ +typedef struct _tracked_gtype_t +{ + GType type; /* Type GLib représenté */ + char *name; /* Désignation humaine */ + +} tracked_gtype_t; + +/* Conservation des types même sans les greffons associés */ +static tracked_gtype_t *__tracking = NULL; +static size_t __count = 0; + + +/* Effectue une comparaison entre deux mémorisations de GTypes. */ +static int compare_gtypes_for_leaks(const tracked_gtype_t *, const tracked_gtype_t *); + +/* Constitue une base de données de nom de tous les GTypes. */ +static void _remember_gtypes_for_leaks(GType); /* Parcourt l'arborescence des types à la recherche de fuites. */ static void track_gtype_for_leak(GType, bool *); + +/****************************************************************************** +* * +* Paramètres : a = première description à comparer. * +* b = seconde description à comparer. * +* * +* Description : Effectue une comparaison entre deux mémorisations de GTypes. * +* * +* Retour : Bilan de l'opération (-1, 0 ou 1). * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int compare_gtypes_for_leaks(const tracked_gtype_t *a, const tracked_gtype_t *b) +{ + int result; /* Bilan à retourner */ + + if (a->type < b->type) + result = -1; + + else if (a->type > b->type) + result = 1; + + else + result = 0; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : root = racine des types d'instance à parcourir. * +* * +* Description : Constitue une base de données de nom de tous les GTypes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void _remember_gtypes_for_leaks(GType root) +{ + GType *children; /* Liste de tous les sous-types*/ + guint count; /* Taille de cette liste */ + tracked_gtype_t *new; /* Nouvelle feuille à mémoriser*/ + GType *iter; /* Boucle de parcours */ + + children = g_type_children(root, &count); + + if (count == 0) + { + __tracking = realloc(__tracking, ++__count * sizeof(tracked_gtype_t)); + + new = &__tracking[__count - 1]; + + new->type = root; + new->name = strdup(g_type_name(root)); + + } + + else + for (iter = children; *iter != 0; iter++) + _remember_gtypes_for_leaks(*iter); + + g_free(children); + +} + + +/****************************************************************************** +* * +* Paramètres : root = racine des types d'instance à parcourir. * +* * +* Description : Constitue une base de données de nom de tous les GTypes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void remember_gtypes_for_leaks(void) +{ + _remember_gtypes_for_leaks(G_TYPE_OBJECT); + +} + + /****************************************************************************** * * * Paramètres : root = racine des types d'instance à retrouver. * @@ -62,8 +174,9 @@ static void track_gtype_for_leak(GType root, bool *first) { GType *children; /* Liste de tous les sous-types*/ guint count; /* Taille de cette liste */ - GType *iter; /* Boucle de parcours */ int remaining; /* Nombre d'instances restantes*/ + const tracked_gtype_t *tracked; /* Infos de type mémorisées */ + GType *iter; /* Boucle de parcours */ children = g_type_children(root, &count); @@ -79,7 +192,12 @@ static void track_gtype_for_leak(GType root, bool *first) *first = false; } - fprintf(stderr, "%s: %d\n", g_type_name(root), remaining); + tracked = bsearch((tracked_gtype_t []) { { .type = root } }, __tracking, + __count, sizeof(tracked_gtype_t), (__compar_fn_t)compare_gtypes_for_leaks); + + assert(tracked != NULL); + + fprintf(stderr, "%s: %d\n", tracked->name, remaining); } @@ -110,6 +228,7 @@ void dump_remaining_gtypes(void) { char *debug; /* Conditions d'environnement */ bool first; /* Première fois ? */ + size_t i; /* Boucle de parcours */ debug = get_env_var("GOBJECT_DEBUG"); @@ -125,6 +244,8 @@ void dump_remaining_gtypes(void) { first = true; + qsort(__tracking, __count, sizeof(tracked_gtype_t), (__compar_fn_t)compare_gtypes_for_leaks); + track_gtype_for_leak(G_TYPE_OBJECT, &first); if (!first) @@ -134,4 +255,16 @@ void dump_remaining_gtypes(void) free(debug); + for (i = 0; i < __count; i++) + free(__tracking[i].name); + + if (__tracking != NULL) + { + free(__tracking); + + __tracking = NULL; + __count = 0; + + } + } |