* Put a new memory leak checker into the server because it turns out that
authorArt Cancro <ajc@citadel.org>
Wed, 24 Mar 2004 17:07:11 +0000 (17:07 +0000)
committerArt Cancro <ajc@citadel.org>
Wed, 24 Mar 2004 17:07:11 +0000 (17:07 +0000)
  the third-party ones all suck.  :)  This one doesn't involve renaming
  all of the malloc() related functions, though.

citadel/ChangeLog
citadel/citserver.c
citadel/server.h
citadel/server_main.c
citadel/sysdep.c
citadel/sysdep_decls.h

index d2c7a1d278c6283270810b7ad9f17e968e192aae..0a949aef36eda430c94b36f1246c92b910ce6285 100644 (file)
@@ -1,4 +1,9 @@
  $Log$
+ Revision 614.99  2004/03/24 17:07:11  ajc
+ * Put a new memory leak checker into the server because it turns out that
+   the third-party ones all suck.  :)  This one doesn't involve renaming
+   all of the malloc() related functions, though.
+
  Revision 614.98  2004/03/24 15:04:06  ajc
  * stress.c: fix "wrong password" race condition by giving the very
    first worker thread time to finish creating the user account before the
@@ -5604,4 +5609,3 @@ Sat Jul 11 00:20:48 EDT 1998 Nathan Bryant <bryant@cs.usm.maine.edu>
 
 Fri Jul 10 1998 Art Cancro <ajc@uncensored.citadel.org>
        * Initial CVS import
-
index 4401376315545508f6c3727ac77d34a6001dee32..8fd945e5f3c3bdf6508671fd8e6780381c800de6 100644 (file)
@@ -142,6 +142,10 @@ void master_cleanup(void) {
        /* Do system-dependent stuff */
        sysdep_master_cleanup();
 
+#ifdef DEBUG_MEMORY_LEAKS
+       dump_heap();
+#endif
+
        /* Now go away. */
        lprintf(CTDL_NOTICE, "citserver: exiting.\n");
        fflush(stdout); fflush(stderr);
index c543de3b77abafd1207ac311ef8bd5d91df40ac1..d1ec072c822b0e3cf1073d594247f40be554f812 100644 (file)
@@ -212,6 +212,7 @@ enum {
        S_PUBLIC_CLIENTS,
        S_LDAP,
        S_FLOORCACHE,
+       S_DEBUGMEMLEAKS,
        MAX_SEMAPHORES
 };
 
index e2872df5d70a8b14ada4096c2564e24764aa42ab..8e784981877c29989dc49b22a09b500e74d93273 100644 (file)
@@ -256,6 +256,5 @@ int main(int argc, char **argv)
        end_critical_section(S_WORKER_LIST);
 
        master_cleanup();
-
        return(0);
 }
index 4dc376679a317f00b89cbb2a08b9d9a228da2f12..99629d7f1244062c0172e6b236b105ba3b9ceebd 100644 (file)
 #include "snprintf.h"
 #endif
 
+
+#ifdef DEBUG_MEMORY_LEAKS
+struct igheap {
+       struct igheap *next;
+       char file[32];
+       int line;
+       void *block;
+};
+
+struct igheap *igheap = NULL;
+#endif
+
+
 pthread_mutex_t Critters[MAX_SEMAPHORES];      /* Things needing locking */
 pthread_key_t MyConKey;                                /* TSD key for MyContext() */
 
@@ -236,9 +249,17 @@ void init_sysdep(void) {
 void begin_critical_section(int which_one)
 {
        /* lprintf(CTDL_DEBUG, "begin_critical_section(%d)\n", which_one); */
+
+
        /* ensure nobody ever tries to do a critical section within a
-          transaction; this could lead to deadlock. */
-       cdb_check_handles();
+               transaction; this could lead to deadlock. */
+#ifdef DEBUG_MEMORY_LEAKS
+       if (which_one != S_DEBUGMEMLEAKS) {
+#endif
+               cdb_check_handles();
+#ifdef DEBUG_MEMORY_LEAKS
+       }
+#endif
        pthread_mutex_lock(&Critters[which_one]);
 }
 
@@ -1148,3 +1169,110 @@ int SyslogFacility(char *name)
        return -1;
 }
 
+
+/********** MEM CHEQQER ***********/
+
+#ifdef DEBUG_MEMORY_LEAKS
+
+#undef malloc
+#undef realloc
+#undef strdup
+#undef free
+
+void *tracked_malloc(size_t size, char *file, int line) {
+       struct igheap *thisheap;
+       void *block;
+
+       block = malloc(size);
+       if (block == NULL) return(block);
+
+       thisheap = malloc(sizeof(struct igheap));
+       if (thisheap == NULL) {
+               free(block);
+               return(NULL);
+       }
+
+       thisheap->block = block;
+       strcpy(thisheap->file, file);
+       thisheap->line = line;
+       
+       begin_critical_section(S_DEBUGMEMLEAKS);
+       thisheap->next = igheap;
+       igheap = thisheap;
+       end_critical_section(S_DEBUGMEMLEAKS);
+
+       return(block);
+}
+
+
+void *tracked_realloc(void *ptr, size_t size, char *file, int line) {
+       struct igheap *thisheap;
+       void *block;
+
+       block = realloc(ptr, size);
+       if (block == NULL) return(block);
+
+       thisheap = malloc(sizeof(struct igheap));
+       if (thisheap == NULL) {
+               free(block);
+               return(NULL);
+       }
+
+       thisheap->block = block;
+       strcpy(thisheap->file, file);
+       thisheap->line = line;
+       
+       begin_critical_section(S_DEBUGMEMLEAKS);
+       thisheap->next = igheap;
+       igheap = thisheap;
+       end_critical_section(S_DEBUGMEMLEAKS);
+
+       return(block);
+}
+
+
+
+void tracked_free(void *ptr) {
+       struct igheap *thisheap;
+       struct igheap *trash;
+
+       free(ptr);
+
+       if (igheap == NULL) return;
+       begin_critical_section(S_DEBUGMEMLEAKS);
+       for (thisheap = igheap; thisheap != NULL; thisheap = thisheap->next) {
+               if (thisheap->next != NULL) {
+                       if (thisheap->next->block == ptr) {
+                               trash = thisheap->next;
+                               thisheap->next = thisheap->next->next;
+                               free(trash);
+                       }
+               }
+       }
+       if (igheap->block == ptr) {
+               trash = igheap;
+               igheap = igheap->next;
+               free(trash);
+       }
+       end_critical_section(S_DEBUGMEMLEAKS);
+}
+
+char *tracked_strdup(const char *s, char *file, int line) {
+       char *ptr;
+
+       if (s == NULL) return(NULL);
+       ptr = tracked_malloc(strlen(s) + 1, file, line);
+       if (ptr == NULL) return(NULL);
+       strncpy(ptr, s, strlen(s));
+       return(ptr);
+}
+
+void dump_heap(void) {
+       struct igheap *thisheap;
+
+       for (thisheap = igheap; thisheap != NULL; thisheap = thisheap->next) {
+               lprintf(CTDL_DEBUG, "%30s : %d\n", thisheap->file, thisheap->line);
+       }
+}
+
+#endif /*  DEBUG_MEMORY_LEAKS */
index a83c14816f7e5f5ec3fac172b3246e18c3578990..008031e4a3b094e7e33b1997a99e8bbbefeab711 100644 (file)
@@ -1,5 +1,14 @@
 /* $Id$ */
 
+
+/*
+ * Uncomment this #define if you are a Citadel developer tracking
+ * down memory leaks in the server.  Do NOT do this on a production
+ * system because it definitely incurs a lot of additional overhead.
+ */
+/* #define DEBUG_MEMORY_LEAKS */
+
+
 #include <pthread.h>
 #include "sysdep.h"
 #include "server.h"
@@ -72,3 +81,16 @@ extern struct worker_node {
 
 extern int SyslogFacility(char *name);
 extern int syslog_facility;
+
+#ifdef DEBUG_MEMORY_LEAKS
+#define malloc(x) tracked_malloc(x, __FILE__, __LINE__)
+#define realloc(x,y) tracked_realloc(x, y, __FILE__, __LINE__)
+#undef strdup
+#define strdup(x) tracked_strdup(x, __FILE__, __LINE__)
+#define free(x) tracked_free(x)
+void *tracked_malloc(size_t size, char *file, int line);
+void *tracked_realloc(void *ptr, size_t size, char *file, int line);
+void tracked_free(void *ptr);
+char *tracked_strdup(const char *s, char *file, int line);
+void dump_heap(void);
+#endif