From 0cfcbee3c536ac6d11ec806d47ce4c136f695697 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Fri, 21 Dec 2012 12:54:17 +0000
Subject: Unloaded loaded plugins and (started to) avoid memory leaks.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@307 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                   | 16 +++++++++
 configure.ac                |  9 +++--
 plugins/pychrysa/pychrysa.c | 21 ++++++++++--
 plugins/pychrysa/pychrysa.h |  3 ++
 src/main.c                  |  2 ++
 src/plugins/pglist.c        | 28 ++++++++++++++++
 src/plugins/pglist.h        |  3 ++
 src/plugins/plugin-int.h    |  4 +++
 src/plugins/plugin.c        | 80 +++++++++++++++++++++++++++++++++++++++++----
 9 files changed, 156 insertions(+), 10 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index bc095d6..a0579f3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+12-12-21  Cyrille Bagard <nocbos@gmail.com>
+
+	* configure.ac:
+	Use Python debug libraries in debug mode.
+
+	* plugins/pychrysa/pychrysa.c:
+	* plugins/pychrysa/pychrysa.h:
+	Update.
+
+	* src/main.c:
+	* src/plugins/pglist.c:
+	* src/plugins/pglist.h:
+	* src/plugins/plugin.c:
+	* src/plugins/plugin-int.h:
+	Unload loaded plugins and (start to) avoid memory leaks.
+
 12-12-19  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/analysis/binaries/file.c:
diff --git a/configure.ac b/configure.ac
index c1df58c..5658e46 100644
--- a/configure.ac
+++ b/configure.ac
@@ -188,8 +188,13 @@ AC_SUBST(LIBXML_LIBS)
 
 #--- Checks for Python
 
-LIBPYTHON_CFLAGS=`python-config --cflags`
-LIBPYTHON_LIBS=`python-config --libs`
+if test "x$enable_debug" = "xyes"; then
+   LIBPYTHON_CFLAGS=`python-dbg-config --cflags`
+   LIBPYTHON_LIBS=`python-dbg-config --libs`
+else
+   LIBPYTHON_CFLAGS=`python-config --cflags`
+   LIBPYTHON_LIBS=`python-config --libs`
+fi
 
 AC_SUBST(LIBPYTHON_CFLAGS)
 AC_SUBST(LIBPYTHON_LIBS)
diff --git a/plugins/pychrysa/pychrysa.c b/plugins/pychrysa/pychrysa.c
index d7cdfe4..0e8446d 100644
--- a/plugins/pychrysa/pychrysa.c
+++ b/plugins/pychrysa/pychrysa.c
@@ -180,8 +180,6 @@ bool init_plugin(GPluginModule *plugin, GObject *ref)
 
     }
 
-    //Py_Finalize();
-
     return true;
 
 }
@@ -189,6 +187,25 @@ bool init_plugin(GPluginModule *plugin, GObject *ref)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : plugin = instance représentant le greffon en déchargement.   *
+*                                                                             *
+*  Description : Libère le greffon permettant l'usage de Python.              *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void exit_plugin(GPluginModule *plugin)
+{
+    Py_Finalize();
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : plugin = greffon à consulter.                                *
 *                                                                             *
 *  Description : Indique les opérations offertes par un greffon donné.        *
diff --git a/plugins/pychrysa/pychrysa.h b/plugins/pychrysa/pychrysa.h
index daa0ccf..4145f11 100644
--- a/plugins/pychrysa/pychrysa.h
+++ b/plugins/pychrysa/pychrysa.h
@@ -40,6 +40,9 @@ char *get_plugin_name(void);
 /* Initialise le greffon permettant l'usage de Python. */
 bool init_plugin(GPluginModule *, GObject *);
 
+/* Libère le greffon permettant l'usage de Python. */
+void exit_plugin(GPluginModule *);
+
 /* Indique les opérations offertes par un greffon donné. */
 PluginAction get_plugin_action(const GPluginModule *);
 
diff --git a/src/main.c b/src/main.c
index 8612b1d..9efc94d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -164,6 +164,8 @@ int main(int argc, char **argv)
     gtk_main();
     gdk_threads_leave();
 
+    exit_all_plugins();
+
     exit_global_pango_context();
 
     unload_configuration(config);
diff --git a/src/plugins/pglist.c b/src/plugins/pglist.c
index 6b51690..e7a3ab0 100644
--- a/src/plugins/pglist.c
+++ b/src/plugins/pglist.c
@@ -76,6 +76,7 @@ void browse_directory_for_plugins(plugins_list *, const char *);
 bool init_all_plugins(GObject *ref)
 {
     _list.ref = ref;
+    g_object_ref(ref);
 
     browse_directory_for_plugins(&_list, PACKAGE_SOURCE_DIR "/plugins");
 
@@ -86,6 +87,33 @@ bool init_all_plugins(GObject *ref)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Procède au déchargement des différents greffons présents.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void exit_all_plugins(void)
+{
+    size_t i;                               /* Boucle de parcours          */
+
+    for (i = 0; i < _list.plugins_count; i++)
+        g_object_unref(_list.plugins[i]);
+
+    if (_list.plugins != NULL)
+        free(_list.plugins);
+
+    g_object_unref(_list.ref);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : entry = entrée de répertoire à analyser.                     *
 *                                                                             *
 *  Description : Filtre les répertoire et les modules de greffons pootentels. *
diff --git a/src/plugins/pglist.h b/src/plugins/pglist.h
index e77bc8b..8e95050 100644
--- a/src/plugins/pglist.h
+++ b/src/plugins/pglist.h
@@ -38,6 +38,9 @@
 /* Procède au chargement des différents greffons trouvés. */
 bool init_all_plugins(GObject *);
 
+/* Procède au déchargement des différents greffons présents. */
+void exit_all_plugins(void);
+
 /* Founit un greffon offrant le service demandé. */
 GPluginModule *get_one_plugin_for_action(PluginAction);
 
diff --git a/src/plugins/plugin-int.h b/src/plugins/plugin-int.h
index 055f6ff..20d9720 100644
--- a/src/plugins/plugin-int.h
+++ b/src/plugins/plugin-int.h
@@ -40,6 +40,9 @@ typedef char * (* get_plugin_name_fc) (void);
 /* Procède à l'initialisation du greffon. */
 typedef bool (* init_plugin_fc) (GPluginModule *, GObject *);
 
+/* Procède à l'extinction du greffon. */
+typedef void (* exit_plugin_fc) (GPluginModule *);
+
 /* Fournit une indication sur le type d'opération(s) menée(s). */
 typedef PluginAction (* get_plugin_action_fc) (const GPluginModule *);
 
@@ -65,6 +68,7 @@ struct _GPluginModule
     PluginType type;                        /* Type(s) du greffon          */
 
     init_plugin_fc init;                    /* Procédure d'initialisation  */
+    exit_plugin_fc exit;                    /* Procédure d'extinction      */
     get_plugin_action_fc get_action;        /* Opération(s) menée(s)       */
 
     is_matching_fc is_matching;             /* Recherche de correspondance */
diff --git a/src/plugins/plugin.c b/src/plugins/plugin.c
index dabe493..968cf65 100644
--- a/src/plugins/plugin.c
+++ b/src/plugins/plugin.c
@@ -44,6 +44,11 @@ static void g_plugin_module_class_init(GPluginModuleClass *);
 /* Initialise une instance de greffon. */
 static void g_plugin_module_init(GPluginModule *);
 
+/* Supprime toutes les références externes. */
+static void g_plugin_module_dispose(GPluginModule *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_plugin_module_finalize(GPluginModule *);
 
 
 /* Indique le type défini pour un greffon. */
@@ -53,7 +58,7 @@ G_DEFINE_TYPE(GPluginModule, g_plugin_module, G_TYPE_OBJECT);
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : klass = classe à initialiser.                                *
+*  Paramètres  : class = classe à initialiser.                                *
 *                                                                             *
 *  Description : Initialise la classe des greffons.                           *
 *                                                                             *
@@ -63,15 +68,21 @@ G_DEFINE_TYPE(GPluginModule, g_plugin_module, G_TYPE_OBJECT);
 *                                                                             *
 ******************************************************************************/
 
-static void g_plugin_module_class_init(GPluginModuleClass *klass)
+static void g_plugin_module_class_init(GPluginModuleClass *class)
 {
+    GObjectClass *object;                   /* Autre version de la classe  */
+
+    object = G_OBJECT_CLASS(class);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_plugin_module_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_plugin_module_finalize;
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : line = instance à initialiser.                               *
+*  Paramètres  : plugin = instance à initialiser.                             *
 *                                                                             *
 *  Description : Initialise une instance de greffon.                          *
 *                                                                             *
@@ -81,8 +92,57 @@ static void g_plugin_module_class_init(GPluginModuleClass *klass)
 *                                                                             *
 ******************************************************************************/
 
-static void g_plugin_module_init(GPluginModule *line)
+static void g_plugin_module_init(GPluginModule *plugin)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : plugin = instance d'objet GLib à traiter.                    *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_plugin_module_dispose(GPluginModule *plugin)
+{
+    if (plugin->exit != NULL)
+        plugin->exit(plugin);
+
+    if (plugin->module != NULL)
+        g_module_close(plugin->module);
+
+    G_OBJECT_CLASS(g_plugin_module_parent_class)->dispose(G_OBJECT(plugin));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : plugin = instance d'objet GLib à traiter.                    *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_plugin_module_finalize(GPluginModule *plugin)
 {
+    if (plugin->name != NULL)
+        free(plugin->name);
+    if (plugin->filename != NULL)
+        free(plugin->filename);
+
+    G_OBJECT_CLASS(g_plugin_module_parent_class)->finalize(G_OBJECT(plugin));
 
 }
 
@@ -109,9 +169,14 @@ GPluginModule *g_plugin_module_new(const gchar *filename)
 
     result = g_object_new(G_TYPE_PLUGIN_MODULE, NULL);
 
-
     result->module = g_module_open(filename, G_MODULE_BIND_LAZY);
-    if (!result->module) goto bad_plugin;
+    if (result->module == NULL)
+    {
+        log_variadic_message(LMT_ERROR, 
+                             _("Error while loading the plugin candidate '%s' : %s"),
+                             filename, g_module_error());
+        goto bad_plugin;
+    }
 
     if (!g_module_symbol(result->module, "get_plugin_name", (gpointer *)&get_name))
     {
@@ -127,6 +192,9 @@ GPluginModule *g_plugin_module_new(const gchar *filename)
     if (!g_module_symbol(result->module, "init_plugin", (gpointer *)&result->init))
         result->init = NULL;
 
+    if (!g_module_symbol(result->module, "exit_plugin", (gpointer *)&result->exit))
+        result->exit = NULL;
+
     /*
 
 
-- 
cgit v0.11.2-87-g4458