Bug #928 and memprof friendlyness.



Hi everyone,

before we celebrate the first anniversary of this bug, here is a proposal for
a solution. Clearly now with memprof around, there is some interest in getting
all bogus references out of programs to find memory leaks. That of course
makes programs a little (in some cases even a lot) slower. That's why, it
doesn't seem like a good solution to always be memprof friendly. 

Thus I defined a macro G_MEMPROF_FRIENDLY and changed all places (at least, I
think, that I found all places), where unused memory is put into some kind of
queue for later reusing it, such that all references are set to NULL. The
patch is attached.

We could now add a switch to configure (--enable-memprof-friendly) to make it
easier to use. 

What do you all think?

Bye,
Sebastian
-- 
Sebastian Wilhelmi                   |            här ovanför alla molnen
mailto:wilhelmi@ira.uka.de           |     är himmlen så förunderligt blå
http://goethe.ira.uka.de/~wilhelmi   |
Index: ghash.c
===================================================================
RCS file: /cvs/gnome/glib/ghash.c,v
retrieving revision 1.17
diff -u -b -B -r1.17 ghash.c
--- ghash.c	1999/02/24 06:13:35	1.17
+++ ghash.c	2000/03/13 13:33:21
@@ -380,6 +380,12 @@
 static void
 g_hash_node_destroy (GHashNode *hash_node)
 {
+
+#ifdef G_MEMPROF_FRIENDLY
+  hash_node->key = NULL;
+  hash_node->value = NULL;
+#endif /* G_MEMPROF_FRIENDLY */
+
   G_LOCK (g_hash_global);
   hash_node->next = node_free_list;
   node_free_list = hash_node;
@@ -394,7 +400,18 @@
       GHashNode *node = hash_node;
   
       while (node->next)
+	{
+#ifdef G_MEMPROF_FRIENDLY
+	  node->key = NULL;
+	  node->value = NULL;
+#endif /* G_MEMPROF_FRIENDLY */
         node = node->next;
+	}
+
+#ifdef G_MEMPROF_FRIENDLY
+      node->key = NULL;
+      node->value = NULL;
+#endif /* G_MEMPROF_FRIENDLY */
   
       G_LOCK (g_hash_global);
       node->next = node_free_list;
Index: glist.c
===================================================================
RCS file: /cvs/gnome/glib/glist.c,v
retrieving revision 1.14
diff -u -b -B -r1.14 glist.c
--- glist.c	1999/08/17 17:41:01	1.14
+++ glist.c	2000/03/13 13:33:21
@@ -78,7 +78,7 @@
 g_list_push_allocator(GAllocator *allocator)
 {
   G_LOCK (current_allocator);
-  g_list_validate_allocator ( allocator );
+  g_list_validate_allocator (allocator);
   allocator->last = current_allocator;
   current_allocator = allocator;
   G_UNLOCK (current_allocator);
@@ -151,9 +151,23 @@
 {
   if (list)
     {
+      GList *last_node = list;
+
+#ifdef G_MEMPROF_FRIENDLY
+      while (last_node->next)
+        {
+          last_node->data = NULL;
+          last_node->prev = NULL;
+          last_node = last_node->next;
+        }
+      last_node->data = NULL
+      last_node->prev = NULL
+#else /* !G_MEMPROF_FRIENDLY */
       list->data = list->next;  
+#endif /* G_MEMPROF_FRIENDLY */
+
       G_LOCK (current_allocator);
-      list->next = current_allocator->free_lists;
+      last_node->next = current_allocator->free_lists;
       current_allocator->free_lists = list;
       G_UNLOCK (current_allocator);
     }
@@ -165,6 +179,11 @@
   if (list)
     {
       list->data = NULL;  
+
+#ifdef G_MEMPROF_FRIENDLY
+      list->prev = NULL;  
+#endif /* G_MEMPROF_FRIENDLY */
+
       G_LOCK (current_allocator);
       list->next = current_allocator->free_lists;
       current_allocator->free_lists = list;
Index: gmain.c
===================================================================
RCS file: /cvs/gnome/glib/gmain.c,v
retrieving revision 1.33
diff -u -b -B -r1.33 gmain.c
--- gmain.c	2000/03/01 09:44:09	1.33
+++ gmain.c	2000/03/13 13:33:21
@@ -1184,6 +1184,10 @@
 	  else
 	    poll_records = pollrec->next;
 
+#ifdef G_MEMPROF_FRIENDLY
+	  pollrec->fd = NULL;  
+#endif /* G_MEMPROF_FRIENDLY */
+
 	  pollrec->next = poll_free_list;
 	  poll_free_list = pollrec;
 
Index: gmem.c
===================================================================
RCS file: /cvs/gnome/glib/gmem.c,v
retrieving revision 1.16
diff -u -b -B -r1.16 gmem.c
--- gmem.c	1999/09/17 09:02:48	1.16
+++ gmem.c	2000/03/13 13:33:21
@@ -715,6 +715,10 @@
 
   rmem_chunk = (GRealMemChunk*) mem_chunk;
   
+#ifdef G_MEMPROF_FRIENDLY
+  memset (mem, 0, rmem_chunk->atom_size);
+#endif /* G_MEMPROF_FRIENDLY */
+
   /* Don't do anything if this is an ALLOC_ONLY chunk
    */
   if (rmem_chunk->type == G_ALLOC_AND_FREE)
Index: gnode.c
===================================================================
RCS file: /cvs/gnome/glib/gnode.c,v
retrieving revision 1.12
diff -u -b -B -r1.12 gnode.c
--- gnode.c	2000/03/01 09:44:09	1.12
+++ gnode.c	2000/03/13 13:33:21
@@ -82,7 +82,7 @@
 g_node_push_allocator (GAllocator *allocator)
 {
   G_LOCK (current_allocator);
-  g_node_validate_allocator ( allocator );
+  g_node_validate_allocator (allocator);
   allocator->last = current_allocator;
   current_allocator = allocator;
   G_UNLOCK (current_allocator);
@@ -148,6 +148,14 @@
     {
       if (parent->children)
 	g_nodes_free (parent->children);
+
+#ifdef G_MEMPROF_FRIENDLY
+      parent->data = NULL;
+      parent->prev = NULL;
+      parent->parent = NULL;
+      parent->children = NULL;
+#endif /* G_MEMPROF_FRIENDLY */
+
       if (parent->next)
 	parent = parent->next;
       else
Index: gqueue.c
===================================================================
RCS file: /cvs/gnome/glib/gqueue.c,v
retrieving revision 1.4
diff -u -b -B -r1.4 gqueue.c
--- gqueue.c	1999/07/24 18:50:55	1.4
+++ gqueue.c	2000/03/13 13:33:21
@@ -64,6 +64,11 @@
 
   g_list_free (queue->head);
 
+#ifdef G_MEMPROF_FRIENDLY
+  queue->head = NULL;
+  queue->tail = NULL;
+#endif /* G_MEMPROF_FRIENDLY */
+
   G_LOCK (queue_memchunk);
   g_trash_stack_push (&free_queue_nodes, queue);
   G_UNLOCK (queue_memchunk);
Index: gslist.c
===================================================================
RCS file: /cvs/gnome/glib/gslist.c,v
retrieving revision 1.13
diff -u -b -B -r1.13 gslist.c
--- gslist.c	2000/03/01 09:44:09	1.13
+++ gslist.c	2000/03/13 13:33:21
@@ -151,9 +151,21 @@
 {
   if (list)
     {
+      GSList *last_node = list;
+  
+#ifdef G_MEMPROF_FRIENDLY
+      while (last_node->next)
+	{
+	  last_node->data = NULL;
+	  last_node = last_node->next;
+	}
+      last_node->data = NULL
+#else /* !G_MEMPROF_FRIENDLY */
       list->data = list->next;
+#endif /* G_MEMPROF_FRIENDLY */
+	
       G_LOCK (current_allocator);
-      list->next = current_allocator->free_lists;
+      last_node->next = current_allocator->free_lists;
       current_allocator->free_lists = list;
       G_UNLOCK (current_allocator);
     }
Index: gtree.c
===================================================================
RCS file: /cvs/gnome/glib/gtree.c,v
retrieving revision 1.10
diff -u -b -B -r1.10 gtree.c
--- gtree.c	1999/02/24 06:13:56	1.10
+++ gtree.c	2000/03/13 13:33:21
@@ -135,6 +135,13 @@
     {
       g_tree_node_destroy (node->right);
       g_tree_node_destroy (node->left);
+
+#ifdef G_MEMPROF_FRIENDLY
+      node->left = NULL;
+      node->key = NULL;
+      node->value = NULL;
+#endif /* G_MEMPROF_FRIENDLY */
+
       G_LOCK (g_tree_global);
       node->right = node_free_list;
       node_free_list = node;
@@ -395,6 +402,12 @@
 	  new_root->balance = node->balance;
 	  node = g_tree_node_restore_right_balance (new_root, old_balance);
 	}
+
+#ifdef G_MEMPROF_FRIENDLY
+      garbage->left = NULL;
+      garbage->key = NULL;
+      garbage->value = NULL;
+#endif /* G_MEMPROF_FRIENDLY */
 
       G_LOCK (g_tree_global);
       garbage->right = node_free_list;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]