/soc/2012/sanket/statscollector-2.x.y: 438ff68e99d9: Memory leak...

Sanket Agarwal sanket at soc.pidgin.im
Sun Mar 31 00:37:39 EDT 2013


Changeset: 438ff68e99d9a1450410aabfc89f18c826f0caf3
Author:	 Sanket Agarwal <sanket at soc.pidgin.im>
Date:	 2013-03-30 17:23 +0530
Branch:	 soc.2012.statscollector
URL: https://hg.pidgin.im/soc/2012/sanket/statscollector-2.x.y/rev/438ff68e99d9

Description:

Memory leak management with Valgrind.

Partially fix nagging memory leaks with the code. It's not a complete or
exhaustive list of bugs by any chance, but lots of leaks have been fixed. Work
is still in progress to fix the remaining memory leaks reported by valgrind.

diffstat:

 libpurple/plugins/statscollector.c |  81 ++++++++++++++++++++++++++++---------
 1 files changed, 61 insertions(+), 20 deletions(-)

diffs (225 lines):

diff --git a/libpurple/plugins/statscollector.c b/libpurple/plugins/statscollector.c
--- a/libpurple/plugins/statscollector.c
+++ b/libpurple/plugins/statscollector.c
@@ -304,7 +304,7 @@ get_os_32_64(){
 #elif defined _POSIX_VERSION
 
   struct utsname os_utsname;
-  char *m_name;
+  char *m_name, *bit_size_str;
 
 #endif
 
@@ -348,7 +348,11 @@ get_os_32_64(){
 
 #endif
 
-  xmlnode_insert_data(bit_size_xml, g_strdup_printf("%d", bit_size), -1);
+  bit_size_str = g_strdup_printf("%d", bit_size);
+  xmlnode_insert_data(bit_size_xml, bit_size_str, -1);
+
+  /* Free OWNED objects */
+  g_free(bit_size_str);
 
   return bit_size_xml;
 
@@ -676,15 +680,17 @@ get_ui_info(){
 
   schedule_stats_save();
 
+  /* Free OWNED objects */
+  xmlnode_free(ui_info_xml);
 
 }
 
 
-static const gchar *
+static gchar *
 md5(const guchar *str)
 {
         PurpleCipherContext *context;
-        static gchar digest[41];
+        gchar digest[41];
 
         context = purple_cipher_context_new_by_name("md5", NULL);
         g_return_val_if_fail(context != NULL, NULL);
@@ -696,7 +702,7 @@ md5(const guchar *str)
 
         purple_cipher_context_destroy(context);
 
-        return digest;
+        return g_strdup(digest);
 }
 
 static char *
@@ -725,13 +731,14 @@ acc_sign_on_event(PurpleAccount *account
    * 1.1 If no, then add the account to the list of accounts used
    */
 
-  const char *username, *protocol, *connect_server="";
-  char *id, *username_dup;
+  const char *username, *protocol, *connect_server = "";
+  char *id, *username_dup, *len_str;
   xmlnode *acc, *p_node, *len_node, *connect_server_node;
   int len;
   PurplePlugin *prpl_plugin;
   PurplePluginProtocolInfo *prpl_info;
   GList *user_splits, *l;
+  GSList *buddies_in_account;
 
   username = purple_account_get_username(account);
   protocol = purple_account_get_protocol_id(account);
@@ -753,9 +760,11 @@ acc_sign_on_event(PurpleAccount *account
   xmlnode_insert_data(p_node, protocol, -1);
 
   /* Number of buddies in account list */
-  len = g_slist_length(purple_find_buddies(account, NULL));
+  buddies_in_account = purple_find_buddies(account, NULL);
+  len = g_slist_length(buddies_in_account);
   len_node = xmlnode_new("buddies");
-  xmlnode_insert_data(len_node, g_strdup_printf("%d", len), -1);
+  len_str = g_strdup_printf("%d", len);
+  xmlnode_insert_data(len_node, len_str, -1);
   xmlnode_insert_child(acc, len_node);
 
   /* We can also send ``username-splits'' as they will be helpful
@@ -765,8 +774,7 @@ acc_sign_on_event(PurpleAccount *account
   if(user_splits != NULL){
     for (l = g_list_last(user_splits);l != NULL;l = l->prev) {
         PurpleAccountUserSplit *split = l->data;
-        const char *value = NULL, *value_md5=NULL;
-        char *c;
+        char *value = NULL, *value_md5=NULL, *value_md5_tag = NULL, *c;
         xmlnode *user_split_node, *user_split_node_hash;
 
         if(purple_account_user_split_get_reverse(split))
@@ -793,9 +801,13 @@ acc_sign_on_event(PurpleAccount *account
         }
         xmlnode_insert_child(acc, user_split_node);
         /* Normal MD5 node */
-        user_split_node_hash = xmlnode_new(g_strdup_printf("%s_hash", split->text));
+        value_md5_tag = g_strdup_printf("%s_hash", split->text);
+        user_split_node_hash = xmlnode_new(value_md5_tag);
         xmlnode_insert_data(user_split_node_hash, value_md5, -1);
         xmlnode_insert_child(acc, user_split_node_hash);
+
+        g_free(value_md5);
+        g_free(value_md5_tag);
     }
   }
 
@@ -823,6 +835,12 @@ acc_sign_on_event(PurpleAccount *account
     g_hash_table_insert(stats_acc_ht, id, (void *)acc);
   }
   schedule_stats_save();
+
+
+  /* Free OWNED objects */
+  g_free(username_dup);
+  g_slist_free(buddies_in_account);
+  g_free(len_str);
 }
 
 static void
@@ -960,6 +978,7 @@ send_stats()
   g_free(host);
   g_free(path);
   g_free(request);
+  g_free(pd_xml);
 
   return FALSE;
 }
@@ -1023,9 +1042,12 @@ init_stats(){
   g_file_get_contents(filename, &file_contents, &length, &error);
 
   /* Initialize basic data-strcutures */
-  stats_acc_ht = g_hash_table_new(g_str_hash, g_str_equal);
-  stats_plugins_ht = g_hash_table_new(g_str_hash, g_str_equal);
-  stats_uis_ht = g_hash_table_new(g_str_hash, g_str_equal);
+  stats_acc_ht = g_hash_table_new_full(
+      g_str_hash, g_str_equal, NULL, (GDestroyNotify)xmlnode_free);
+  stats_plugins_ht = g_hash_table_new_full(
+      g_str_hash, g_str_equal, NULL, (GDestroyNotify)xmlnode_free);
+  stats_uis_ht = g_hash_table_new_full(
+      g_str_hash, g_str_equal, NULL, (GDestroyNotify)xmlnode_free);;
 
   /* Check if the version is compatible with the plugin,
    * this should generally change when we install a new
@@ -1047,13 +1069,15 @@ init_stats(){
   } else {
 
     /* Populate the hash tables with account and plugin information */
+    char *stats_acc_xml_str;
 
     stats_acc_xml = xmlnode_get_child(root, "accounts");
     stats_plugins_xml = xmlnode_get_child(root, "plugins");
     cpuinfo_xml = xmlnode_get_child(root, "cpuinfo");
     stats_uis_xml = xmlnode_get_child(root, "uis");
 
-    purple_debug_info("STATS", "Accounts: %s", xmlnode_to_formatted_str(stats_acc_xml, NULL));
+    stats_acc_xml_str = xmlnode_to_formatted_str(stats_acc_xml, NULL);
+    purple_debug_info("STATS", "Accounts: %s", stats_acc_xml_str);
 
     start = xmlnode_get_child(stats_acc_xml, "account");
 
@@ -1083,7 +1107,7 @@ init_stats(){
           xmlnode_copy(start));
     }
 
-
+    g_free(stats_acc_xml_str);
   }
 
   /* It's a good idea to get all loaded plugins and insert them
@@ -1112,6 +1136,11 @@ init_stats(){
 
   g_list_foreach(loaded_accounts, (GFunc)acc_sign_on_event, NULL);
 
+  /* Free any owned objects */
+  xmlnode_free(start);
+  g_free(file_contents);
+  g_error_free(error);
+
   /* Return the structure for modification */
   return root;
 }
@@ -1225,8 +1254,15 @@ plugin_unload(PurplePlugin *plugin){
   if(send_handle) purple_timeout_remove(send_handle);
   purple_signals_disconnect_by_handle(plugin);
 
+  /* Free OWNED global variables */
+  xmlnode_free(root_stats);
+  xmlnode_free(cpuinfo_xml);
+  xmlnode_free(ui_info);
+  g_hash_table_destroy(stats_acc_ht);
+  g_hash_table_destroy(stats_plugins_ht);
+  g_hash_table_destroy(stats_uis_ht);
+
   return TRUE;
-
 }
 
 static PurplePluginPrefFrame *
@@ -1314,6 +1350,8 @@ static void
 init_plugin(PurplePlugin *plugin)
 {
 
+  gchar *uuid;
+
   /* Set up the preferences for the plugin */
   purple_prefs_add_none("/plugins/core/statscollector");
 
@@ -1328,8 +1366,11 @@ init_plugin(PurplePlugin *plugin)
    * it on startup
    */
   g_rand_new_with_seed(time(NULL));
-  purple_prefs_add_string("/plugins/core/statscollector/send-key", \
-      purple_uuid_random());
+  uuid = purple_uuid_random();
+  purple_prefs_add_string("/plugins/core/statscollector/send-key", uuid);
+
+  /* Free OWNED objects */
+  g_free(uuid);
 
 }
 



More information about the Commits mailing list