diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/analysis/db/collection.c | 14 | ||||
-rw-r--r-- | src/analysis/project.c | 3 | ||||
-rw-r--r-- | src/analysis/routine.c | 6 | ||||
-rw-r--r-- | src/gleak.c | 137 | ||||
-rw-r--r-- | src/gleak.h | 2 | ||||
-rw-r--r-- | src/main.c | 4 | ||||
-rw-r--r-- | src/plugins/plugin-def.h | 20 |
7 files changed, 173 insertions, 13 deletions
diff --git a/src/analysis/db/collection.c b/src/analysis/db/collection.c index 9c28c4a..0a617f3 100644 --- a/src/analysis/db/collection.c +++ b/src/analysis/db/collection.c @@ -149,6 +149,18 @@ static void g_db_collection_init(GDbCollection *collec) static void g_db_collection_dispose(GDbCollection *collec) { + if (collec->items != NULL) + { + g_list_free_full(collec->items, g_object_unref); + collec->items = NULL; + } + + if (collec->sorted != NULL) + { + g_list_free_full(collec->sorted, g_object_unref); + collec->sorted = NULL; + } + G_OBJECT_CLASS(g_db_collection_parent_class)->dispose(G_OBJECT(collec)); } @@ -1130,6 +1142,8 @@ bool g_db_collection_load_all_items(GDbCollection *collec, sqlite3 *db) result = g_db_item_load(new, values, count); result &= g_db_collection_add_item(G_DB_COLLECTION(collec), new); + g_object_unref(G_OBJECT(new)); + } /* Sortie propre */ diff --git a/src/analysis/project.c b/src/analysis/project.c index 6156fbc..57ebcc6 100644 --- a/src/analysis/project.c +++ b/src/analysis/project.c @@ -1345,6 +1345,9 @@ static void on_new_content_resolved(GContentResolver *resolver, wgroup_id_t wid, } + if (handler->filter != NULL) + handler->filter(NULL, handler->data); + } else diff --git a/src/analysis/routine.c b/src/analysis/routine.c index 8b49456..d206e5e 100644 --- a/src/analysis/routine.c +++ b/src/analysis/routine.c @@ -539,12 +539,8 @@ GDataType *g_binary_routine_get_return_type(const GBinRoutine *routine) void g_binary_routine_add_arg(GBinRoutine *routine, GBinVariable *var) { - routine->args_count++; + routine->args = realloc(routine->args, ++routine->args_count * sizeof(GBinVariable *)); - routine->args = (GBinVariable **)realloc(routine->args, - routine->args_count * sizeof(GBinVariable *)); - - g_object_ref(G_OBJECT(var)); routine->args[routine->args_count - 1] = var; } 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; + + } + } diff --git a/src/gleak.h b/src/gleak.h index 233fabb..f80e167 100644 --- a/src/gleak.h +++ b/src/gleak.h @@ -25,6 +25,8 @@ #define _GLEAK_H +/* Constitue une base de données de nom de tous les GTypes. */ +void remember_gtypes_for_leaks(void); /* Affiche la liste des instances courantes restantes par type. */ void dump_remaining_gtypes(void); @@ -404,6 +404,10 @@ int main(int argc, char **argv) exit_complete_gui: +#ifdef TRACK_GOBJECT_LEAKS + remember_gtypes_for_leaks(); +#endif + exit_all_plugins(); if (!batch_mode) diff --git a/src/plugins/plugin-def.h b/src/plugins/plugin-def.h index 6d4253e..3717035 100644 --- a/src/plugins/plugin-def.h +++ b/src/plugins/plugin-def.h @@ -223,14 +223,22 @@ typedef struct _plugin_interface uint64_t magic; /* Vérification a minima */ plugin_abi_version_t abi_version; /* Version du protocole utilisé*/ - const char *gtp_name; /* Désignation du GType associé*/ - const char *name; /* Désignation humaine courte */ - const char *desc; /* Description plus loquace */ - const char *version; /* Version du greffon */ + /** + * Les champs suivants ne sont généralement pas alloués dynamiquement, + * car issus des données des greffons natifs. + * + * Dans le cas des autres types d'extensions (par exemple ceux en Python), + * les éléments sont construits à la volée, donc à libérer après usage. + */ + + char *gtp_name; /* Désignation du GType associé*/ + char *name; /* Désignation humaine courte */ + char *desc; /* Description plus loquace */ + char *version; /* Version du greffon */ bool container; /* Mise en place de greffons ? */ - const char **required; /* Pré-chargements requis */ + char **required; /* Pré-chargements requis */ size_t required_count; /* Quantité de ces dépendances */ plugin_action_t *actions; /* Liste des actions gérées */ @@ -251,7 +259,7 @@ typedef struct _plugin_interface #define AL(...) BUILD_PG_LIST(.actions, ((plugin_action_t []){ __VA_ARGS__ })) -#define RL(...) BUILD_PG_LIST(.required, ((const char *[]){ __VA_ARGS__ })) +#define RL(...) BUILD_PG_LIST(.required, ((char *[]){ __VA_ARGS__ })) #define NO_REQ EMPTY_PG_LIST(.required) |