libxml2 r3760 - in trunk: . include/libxml



Author: veillard
Date: Wed Jul 30 12:58:11 2008
New Revision: 3760
URL: http://svn.gnome.org/viewvc/libxml2?rev=3760&view=rev

Log:
* include/libxml/xmlmemory.h xmlmemory.c: add xmlMemDisplayLast to
  help debug incremental memory leaks, and some cleanups
* runxmlconf.c: use that new call and avoid ever touching the
  system catalog in the regression tests
Daniel


Modified:
   trunk/ChangeLog
   trunk/include/libxml/xmlmemory.h
   trunk/runxmlconf.c
   trunk/xmlmemory.c

Modified: trunk/include/libxml/xmlmemory.h
==============================================================================
--- trunk/include/libxml/xmlmemory.h	(original)
+++ trunk/include/libxml/xmlmemory.h	Wed Jul 30 12:58:11 2008
@@ -20,7 +20,7 @@
  *
  * DEBUG_MEMORY replaces the allocator with a collect and debug
  * shell to the libc allocator.
- * DEBUG_MEMORY should only be activated when debugging 
+ * DEBUG_MEMORY should only be activated when debugging
  * libxml i.e. if libxml has been configured with --with-debug-mem too.
  */
 /* #define DEBUG_MEMORY_FREED */
@@ -35,7 +35,7 @@
 /**
  * DEBUG_MEMORY_LOCATION:
  *
- * DEBUG_MEMORY_LOCATION should be activated only when debugging 
+ * DEBUG_MEMORY_LOCATION should be activated only when debugging
  * libxml i.e. if libxml has been configured with --with-debug-mem too.
  */
 #ifdef DEBUG_MEMORY_LOCATION
@@ -105,18 +105,18 @@
 			 xmlMallocFunc mallocFunc,
 			 xmlReallocFunc reallocFunc,
 			 xmlStrdupFunc strdupFunc);
-XMLPUBFUN int XMLCALL     
+XMLPUBFUN int XMLCALL
 	xmlMemGet	(xmlFreeFunc *freeFunc,
 			 xmlMallocFunc *mallocFunc,
 			 xmlReallocFunc *reallocFunc,
 			 xmlStrdupFunc *strdupFunc);
-XMLPUBFUN int XMLCALL     
+XMLPUBFUN int XMLCALL
 	xmlGcMemSetup	(xmlFreeFunc freeFunc,
 			 xmlMallocFunc mallocFunc,
 			 xmlMallocFunc mallocAtomicFunc,
 			 xmlReallocFunc reallocFunc,
 			 xmlStrdupFunc strdupFunc);
-XMLPUBFUN int XMLCALL     
+XMLPUBFUN int XMLCALL
 	xmlGcMemGet	(xmlFreeFunc *freeFunc,
 			 xmlMallocFunc *mallocFunc,
 			 xmlMallocFunc *mallocAtomicFunc,
@@ -126,42 +126,44 @@
 /*
  * Initialization of the memory layer.
  */
-XMLPUBFUN int XMLCALL	
+XMLPUBFUN int XMLCALL
 	xmlInitMemory	(void);
 
-/* 
+/*
  * Cleanup of the memory layer.
  */
-XMLPUBFUN void XMLCALL                
+XMLPUBFUN void XMLCALL
                 xmlCleanupMemory        (void);
 /*
  * These are specific to the XML debug memory wrapper.
  */
-XMLPUBFUN int XMLCALL	
+XMLPUBFUN int XMLCALL
 	xmlMemUsed	(void);
-XMLPUBFUN int XMLCALL	
+XMLPUBFUN int XMLCALL
 	xmlMemBlocks	(void);
-XMLPUBFUN void XMLCALL	
+XMLPUBFUN void XMLCALL
 	xmlMemDisplay	(FILE *fp);
-XMLPUBFUN void XMLCALL	
+XMLPUBFUN void XMLCALL
+	xmlMemDisplayLast(FILE *fp, long nbBytes);
+XMLPUBFUN void XMLCALL
 	xmlMemShow	(FILE *fp, int nr);
-XMLPUBFUN void XMLCALL	
+XMLPUBFUN void XMLCALL
 	xmlMemoryDump	(void);
-XMLPUBFUN void * XMLCALL	
+XMLPUBFUN void * XMLCALL
 	xmlMemMalloc	(size_t size);
-XMLPUBFUN void * XMLCALL	
+XMLPUBFUN void * XMLCALL
 	xmlMemRealloc	(void *ptr,size_t size);
-XMLPUBFUN void XMLCALL	
+XMLPUBFUN void XMLCALL
 	xmlMemFree	(void *ptr);
-XMLPUBFUN char * XMLCALL	
+XMLPUBFUN char * XMLCALL
 	xmlMemoryStrdup	(const char *str);
-XMLPUBFUN void * XMLCALL  
+XMLPUBFUN void * XMLCALL
 	xmlMallocLoc	(size_t size, const char *file, int line);
-XMLPUBFUN void * XMLCALL	
+XMLPUBFUN void * XMLCALL
 	xmlReallocLoc	(void *ptr, size_t size, const char *file, int line);
-XMLPUBFUN void * XMLCALL	
+XMLPUBFUN void * XMLCALL
 	xmlMallocAtomicLoc (size_t size, const char *file, int line);
-XMLPUBFUN char * XMLCALL	
+XMLPUBFUN char * XMLCALL
 	xmlMemStrdupLoc	(const char *str, const char *file, int line);
 
 

Modified: trunk/runxmlconf.c
==============================================================================
--- trunk/runxmlconf.c	(original)
+++ trunk/runxmlconf.c	Wed Jul 30 12:58:11 2008
@@ -125,38 +125,14 @@
 
 /*
  * We need to trap calls to the resolver to not account memory for the catalog
- * which is shared to the current running test. We also don't want to have
- * network downloads modifying tests.
+ * and not rely on any external resources.
  */
 static xmlParserInputPtr
 testExternalEntityLoader(const char *URL, const char *ID,
 			 xmlParserCtxtPtr ctxt) {
     xmlParserInputPtr ret;
-    int i;
 
-    for (i = 0;i < nb_entities;i++) {
-        if (!strcmp(testEntitiesName[i], URL)) {
-	    ret = xmlNewStringInputStream(ctxt,
-	                (const xmlChar *) testEntitiesValue[i]);
-	    if (ret != NULL) {
-	        ret->filename = (const char *)
-		                xmlStrdup((xmlChar *)testEntitiesName[i]);
-	    }
-	    return(ret);
-	}
-    }
-    if (checkTestFile(URL)) {
-	ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
-    } else {
-	int memused = xmlMemUsed();
-	ret = xmlNoNetExternalEntityLoader(URL, ID, ctxt);
-	extraMemoryFromResolver += xmlMemUsed() - memused;
-    }
-#if 0
-    if (ret == NULL) {
-        fprintf(stderr, "Failed to find resource %s\n", URL);
-    }
-#endif
+    ret = xmlNewInputFromFile(ctxt, (const char *) URL);
 
     return(ret);
 }
@@ -377,6 +353,7 @@
         test_log("test %s : %s leaked %d bytes\n",
 	         id, filename, final - mem);
         nb_leaks++;
+	xmlMemDisplayLast(logfile, final - mem);
     }
     nb_tests++;
 

Modified: trunk/xmlmemory.c
==============================================================================
--- trunk/xmlmemory.c	(original)
+++ trunk/xmlmemory.c	Wed Jul 30 12:58:11 2008
@@ -34,7 +34,7 @@
 /**
  * MEM_LIST:
  *
- * keep track of all allocated blocks for error reporting 
+ * keep track of all allocated blocks for error reporting
  * Always build the memory list !
  */
 #ifdef DEBUG_MEMORY_LOCATION
@@ -162,7 +162,7 @@
 {
     MEMHDR *p;
     void *ret;
-    
+
     if (!xmlMemInitialized) xmlInitMemory();
 #ifdef DEBUG_MEMORY
     xmlGenericError(xmlGenericErrorContext,
@@ -170,7 +170,7 @@
 #endif
 
     TEST_POINT
-    
+
     p = (MEMHDR *) malloc(RESERVE_SIZE+size);
 
     if (!p) {
@@ -178,7 +178,7 @@
 		"xmlMallocLoc : Out of free space\n");
 	xmlMemoryDump();
 	return(NULL);
-    }   
+    }
     p->mh_tag = MEMTAG;
     p->mh_size = size;
     p->mh_type = MALLOC_TYPE;
@@ -193,12 +193,12 @@
     debugmem_list_add(p);
 #endif
     xmlMutexUnlock(xmlMemMutex);
-    
+
 #ifdef DEBUG_MEMORY
     xmlGenericError(xmlGenericErrorContext,
 	    "Malloc(%d) Ok\n",size);
 #endif
-    
+
     if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint();
 
     ret = HDR_2_CLIENT(p);
@@ -230,7 +230,7 @@
 {
     MEMHDR *p;
     void *ret;
-    
+
     if (!xmlMemInitialized) xmlInitMemory();
 #ifdef DEBUG_MEMORY
     xmlGenericError(xmlGenericErrorContext,
@@ -238,7 +238,7 @@
 #endif
 
     TEST_POINT
-    
+
     p = (MEMHDR *) malloc(RESERVE_SIZE+size);
 
     if (!p) {
@@ -246,7 +246,7 @@
 		"xmlMallocLoc : Out of free space\n");
 	xmlMemoryDump();
 	return(NULL);
-    }   
+    }
     p->mh_tag = MEMTAG;
     p->mh_size = size;
     p->mh_type = MALLOC_ATOMIC_TYPE;
@@ -266,7 +266,7 @@
     xmlGenericError(xmlGenericErrorContext,
 	    "Malloc(%d) Ok\n",size);
 #endif
-    
+
     if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint();
 
     ret = HDR_2_CLIENT(p);
@@ -341,7 +341,7 @@
     debugmem_list_delete(p);
 #endif
     xmlMutexUnlock(xmlMemMutex);
-    
+
     p = (MEMHDR *) realloc(p,RESERVE_SIZE+size);
     if (!p) {
 	 goto error;
@@ -374,8 +374,8 @@
 	    "Realloced(%d to %d) Ok\n", oldsize, size);
 #endif
     return(HDR_2_CLIENT(p));
-    
-error:    
+
+error:
     return(NULL);
 }
 
@@ -455,10 +455,10 @@
     xmlGenericError(xmlGenericErrorContext,
 	    "Freed(%d) Ok\n", size);
 #endif
-    
+
     return;
-    
-error:    
+
+error:
     xmlGenericError(xmlGenericErrorContext,
 	    "xmlMemFree(%lX) error\n", (unsigned long) ptr);
     xmlMallocBreakpoint();
@@ -504,16 +504,16 @@
     debugmem_list_add(p);
 #endif
     xmlMutexUnlock(xmlMemMutex);
-    
+
     s = (char *) HDR_2_CLIENT(p);
-    
+
     if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint();
 
     if (s != NULL)
       strcpy(s,str);
     else
       goto error;
-    
+
     TEST_POINT
 
     if (xmlMemTraceBlockAt == s) {
@@ -617,7 +617,7 @@
     } else if ((i == 0) && (buf[i] == 0)) {
         fprintf(fp," null");
     } else {
-        if (buf[i] == 0) fprintf(fp," \"%.25s\"", buf); 
+        if (buf[i] == 0) fprintf(fp," \"%.25s\"", buf);
 	else {
             fprintf(fp," [");
 	    for (j = 0;j < i;j++)
@@ -629,6 +629,79 @@
 #endif
 
 /**
+ * xmlMemDisplayLast:
+ * @fp:  a FILE descriptor used as the output file, if NULL, the result is
+ *       written to the file .memorylist
+ * @nbBytes: the amount of memory to dump
+ *
+ * the last nbBytes of memory allocated and not freed, useful for dumping
+ * the memory left allocated between two places at runtime.
+ */
+
+void
+xmlMemDisplayLast(FILE *fp, long nbBytes)
+{
+#ifdef MEM_LIST
+    MEMHDR *p;
+    unsigned idx;
+    int     nb = 0;
+#endif
+    FILE *old_fp = fp;
+
+    if (nbBytes <= 0)
+        return;
+
+    if (fp == NULL) {
+	fp = fopen(".memorylist", "w");
+	if (fp == NULL)
+	    return;
+    }
+
+#ifdef MEM_LIST
+    fprintf(fp,"   Last %li MEMORY ALLOCATED : %lu, MAX was %lu\n",
+            nbBytes, debugMemSize, debugMaxMemSize);
+    fprintf(fp,"BLOCK  NUMBER   SIZE  TYPE\n");
+    idx = 0;
+    xmlMutexLock(xmlMemMutex);
+    p = memlist;
+    while ((p) && (nbBytes > 0)) {
+	  fprintf(fp,"%-5u  %6lu %6lu ",idx++,p->mh_number,
+		  (unsigned long)p->mh_size);
+        switch (p->mh_type) {
+           case STRDUP_TYPE:fprintf(fp,"strdup()  in ");break;
+           case MALLOC_TYPE:fprintf(fp,"malloc()  in ");break;
+           case REALLOC_TYPE:fprintf(fp,"realloc() in ");break;
+           case MALLOC_ATOMIC_TYPE:fprintf(fp,"atomicmalloc()  in ");break;
+           case REALLOC_ATOMIC_TYPE:fprintf(fp,"atomicrealloc() in ");break;
+           default:
+	        fprintf(fp,"Unknown memory block, may be corrupted");
+		xmlMutexUnlock(xmlMemMutex);
+		if (old_fp == NULL)
+		    fclose(fp);
+		return;
+        }
+	if (p->mh_file != NULL) fprintf(fp,"%s(%u)", p->mh_file, p->mh_line);
+        if (p->mh_tag != MEMTAG)
+	      fprintf(fp,"  INVALID");
+        nb++;
+	if (nb < 100)
+	    xmlMemContentShow(fp, p);
+	else
+	    fprintf(fp," skip");
+
+        fprintf(fp,"\n");
+	nbBytes -= (unsigned long)p->mh_size;
+        p = p->mh_next;
+    }
+    xmlMutexUnlock(xmlMemMutex);
+#else
+    fprintf(fp,"Memory list not compiled (MEM_LIST not defined !)\n");
+#endif
+    if (old_fp == NULL)
+	fclose(fp);
+}
+
+/**
  * xmlMemDisplay:
  * @fp:  a FILE descriptor used as the output file, if NULL, the result is
  *       written to the file .memorylist
@@ -665,7 +738,7 @@
     fprintf(fp,"      %s\n\n", buf);
 #endif
 
-    
+
     fprintf(fp,"      MEMORY ALLOCATED : %lu, MAX was %lu\n",
             debugMemSize, debugMaxMemSize);
     fprintf(fp,"BLOCK  NUMBER   SIZE  TYPE\n");
@@ -742,7 +815,7 @@
  *
  * internal error function.
  */
- 
+
 static void debugmem_tag_error(void *p)
 {
      xmlGenericError(xmlGenericErrorContext,
@@ -802,7 +875,7 @@
 	}
     }
     xmlMutexUnlock(xmlMemMutex);
-#endif /* MEM_LIST */    
+#endif /* MEM_LIST */
 }
 
 /**
@@ -849,11 +922,11 @@
 {
 #ifdef HAVE_STDLIB_H
      char *breakpoint;
-#endif     
+#endif
 #ifdef DEBUG_MEMORY
      xmlGenericError(xmlGenericErrorContext,
 	     "xmlInitMemory()\n");
-#endif     
+#endif
     /*
      This is really not good code (see Bug 130419).  Suggestions for
      improvement will be welcome!
@@ -867,18 +940,18 @@
      if (breakpoint != NULL) {
          sscanf(breakpoint, "%ud", &xmlMemStopAtBlock);
      }
-#endif     
+#endif
 #ifdef HAVE_STDLIB_H
      breakpoint = getenv("XML_MEM_TRACE");
      if (breakpoint != NULL) {
          sscanf(breakpoint, "%p", &xmlMemTraceBlockAt);
      }
-#endif     
-    
+#endif
+
 #ifdef DEBUG_MEMORY
      xmlGenericError(xmlGenericErrorContext,
 	     "xmlInitMemory() Ok\n");
-#endif     
+#endif
      return(0);
 }
 
@@ -893,7 +966,7 @@
 #ifdef DEBUG_MEMORY
      xmlGenericError(xmlGenericErrorContext,
 	     "xmlCleanupMemory()\n");
-#endif     
+#endif
     if (xmlMemInitialized == 0)
         return;
 
@@ -903,7 +976,7 @@
 #ifdef DEBUG_MEMORY
      xmlGenericError(xmlGenericErrorContext,
 	     "xmlCleanupMemory() Ok\n");
-#endif     
+#endif
 }
 
 /**
@@ -927,7 +1000,7 @@
 #ifdef DEBUG_MEMORY
      xmlGenericError(xmlGenericErrorContext,
 	     "xmlMemSetup()\n");
-#endif     
+#endif
     if (freeFunc == NULL)
 	return(-1);
     if (mallocFunc == NULL)
@@ -944,7 +1017,7 @@
 #ifdef DEBUG_MEMORY
      xmlGenericError(xmlGenericErrorContext,
 	     "xmlMemSetup() Ok\n");
-#endif     
+#endif
     return(0);
 }
 
@@ -994,7 +1067,7 @@
 #ifdef DEBUG_MEMORY
      xmlGenericError(xmlGenericErrorContext,
 	     "xmlGcMemSetup()\n");
-#endif     
+#endif
     if (freeFunc == NULL)
 	return(-1);
     if (mallocFunc == NULL)
@@ -1013,7 +1086,7 @@
 #ifdef DEBUG_MEMORY
      xmlGenericError(xmlGenericErrorContext,
 	     "xmlGcMemSetup() Ok\n");
-#endif     
+#endif
     return(0);
 }
 



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