From f0d329f083305888573dff79f1f9634c3fd1e53a Mon Sep 17 00:00:00 2001 From: Peter Williams Date: Wed, 16 Aug 2000 14:49:16 +0000 Subject: Updates to the memory debugging stuff. svn path=/trunk/; revision=4853 --- mail/ChangeLog | 5 ++++ mail/message-thread.c | 66 ++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 57 insertions(+), 14 deletions(-) (limited to 'mail') diff --git a/mail/ChangeLog b/mail/ChangeLog index 1a4713082f..516b9ea488 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,8 @@ +2000-08-16 Peter Williams + + * message-thread.c (walk_containers): More (default disabled) + mem debugging here. + 2000-08-15 Peter Williams * message-thread.c (alloc_container): Add support for debugging diff --git a/mail/message-thread.c b/mail/message-thread.c index 938f143d49..34a6456015 100644 --- a/mail/message-thread.c +++ b/mail/message-thread.c @@ -42,7 +42,14 @@ #ifdef LEAKDEBUG -static GSList *allocedlist = NULL; +static GHashTable *allocedht = NULL; + +#define EXISTS (1 << 0) +#define WALKED (1 << 1) +#define FREED (1 << 2) + +#define GITP(x) GINT_TO_POINTER(x) +#define GPTI(x) GPOINTER_TO_INT(x) static struct _container * alloc_container (void) @@ -50,7 +57,11 @@ alloc_container (void) struct _container *c; c = g_new0 (struct _container, 1); - allocedlist = g_slist_prepend (allocedlist, c); + + if (!allocedht) + allocedht = g_hash_table_new (g_direct_hash, g_direct_equal); + + g_hash_table_insert (allocedht, c, GITP(EXISTS)); return c; } @@ -58,33 +69,59 @@ static void free_container (struct _container **c) { memset ((*c), 0, sizeof (struct _container)); - allocedlist = g_slist_remove (allocedlist, (*c)); + if (g_hash_table_lookup (allocedht, c) == NULL) + printf ("** threading mem debug: freeing unalloced entry %p?\n", (*c)); + g_hash_table_insert (allocedht, c, GITP(EXISTS|FREED)); g_free ((*c)); (*c) = NULL; } static void -print_containers (void) +cont_print (gpointer key, gpointer value, gpointer user) { - GSList *iter; + struct _container *c = (struct _container *) key; + + printf (" %p: %p %p %p %s %s %d %d : %s %s\n", + c, + c->next, c->parent, c->child, + c->message ? c->message->subject : "(null message)", + c->root_subject ? c->root_subject : "(null root-subject)", + c->re, c->order, + GPTI(value) & WALKED ? "walked" : "unwlkd", + GPTI(value) & FREED ? "freed" : "unfrd"); +} +static void +print_containers (void) +{ printf ("Containers currently unfreed:\n"); - for (iter = allocedlist; iter; iter = iter->next) { - struct _container *c = (struct _container *) iter->data; - printf (" %p: %p %p %p %s %s %d %d\n", - c, - c->next, c->parent, c->child, - c->message ? c->message->subject : "(null message)", - c->root_subject ? c->root_subject : "(null root-subject)", - c->re, c->order); - } + g_hash_table_foreach (allocedht, cont_print, NULL); printf ("End of list.\n"); } +static void +walk_containers (struct _container *head) +{ + gpointer flags; + + while (head) { + if (head->child) + walk_containers (head->child); + if ((flags = g_hash_table_lookup (allocedht, head)) == NULL) { + printf ("*** walk_containers : bad pointer %p\n", head); + } else { + g_hash_table_insert (allocedht, head, GITP(GPTI(flags)|WALKED)); + } + + head = head->next; + } +} + #else #define alloc_container() (g_new0 (struct _container, 1)) #define free_container(c) g_free (*(c)) #define print_containers() +#define walk_containers(c) #endif /* **************************************** */ @@ -621,6 +658,7 @@ static void cleanup_thread_messages (gpointer in_data, gpointer op_data, CamelEx thread_messages_data_t *data = (thread_messages_data_t *) op_data; (input->build) (input->ml, data->container); + walk_containers (data->container); thread_messages_free (data->container); print_containers(); -- cgit