Imported Upstream version 0.19.7
[platform/upstream/gettext.git] / gnulib-local / lib / libxml / xmlmemory.c
index 362a0b0..f24fd6d 100644 (file)
@@ -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
@@ -58,7 +58,7 @@ void xmlMallocBreakpoint(void);
 
 /************************************************************************
  *                                                                     *
- *             Macros, variables and associated types                  *
+ *             Macros, variables and associated types                  *
  *                                                                     *
  ************************************************************************/
 
@@ -162,7 +162,7 @@ xmlMallocLoc(size_t size, const char * file, int line)
 {
     MEMHDR *p;
     void *ret;
-    
+
     if (!xmlMemInitialized) xmlInitMemory();
 #ifdef DEBUG_MEMORY
     xmlGenericError(xmlGenericErrorContext,
@@ -170,7 +170,7 @@ xmlMallocLoc(size_t size, const char * file, int line)
 #endif
 
     TEST_POINT
-    
+
     p = (MEMHDR *) malloc(RESERVE_SIZE+size);
 
     if (!p) {
@@ -178,7 +178,7 @@ xmlMallocLoc(size_t size, const char * file, int line)
                "xmlMallocLoc : Out of free space\n");
        xmlMemoryDump();
        return(NULL);
-    }   
+    }
     p->mh_tag = MEMTAG;
     p->mh_size = size;
     p->mh_type = MALLOC_TYPE;
@@ -193,19 +193,20 @@ xmlMallocLoc(size_t size, const char * file, int line)
     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);
 
     if (xmlMemTraceBlockAt == ret) {
        xmlGenericError(xmlGenericErrorContext,
-                       "%p : Malloc(%d) Ok\n", xmlMemTraceBlockAt, size);
+                       "%p : Malloc(%lu) Ok\n", xmlMemTraceBlockAt,
+                       (long unsigned)size);
        xmlMallocBreakpoint();
     }
 
@@ -230,7 +231,7 @@ xmlMallocAtomicLoc(size_t size, const char * file, int line)
 {
     MEMHDR *p;
     void *ret;
-    
+
     if (!xmlMemInitialized) xmlInitMemory();
 #ifdef DEBUG_MEMORY
     xmlGenericError(xmlGenericErrorContext,
@@ -238,7 +239,7 @@ xmlMallocAtomicLoc(size_t size, const char * file, int line)
 #endif
 
     TEST_POINT
-    
+
     p = (MEMHDR *) malloc(RESERVE_SIZE+size);
 
     if (!p) {
@@ -246,7 +247,7 @@ xmlMallocAtomicLoc(size_t size, const char * file, int line)
                "xmlMallocLoc : Out of free space\n");
        xmlMemoryDump();
        return(NULL);
-    }   
+    }
     p->mh_tag = MEMTAG;
     p->mh_size = size;
     p->mh_type = MALLOC_ATOMIC_TYPE;
@@ -266,14 +267,15 @@ xmlMallocAtomicLoc(size_t size, const char * file, int line)
     xmlGenericError(xmlGenericErrorContext,
            "Malloc(%d) Ok\n",size);
 #endif
-    
+
     if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint();
 
     ret = HDR_2_CLIENT(p);
 
     if (xmlMemTraceBlockAt == ret) {
        xmlGenericError(xmlGenericErrorContext,
-                       "%p : Malloc(%d) Ok\n", xmlMemTraceBlockAt, size);
+                       "%p : Malloc(%lu) Ok\n", xmlMemTraceBlockAt,
+                       (long unsigned)size);
        xmlMallocBreakpoint();
     }
 
@@ -311,7 +313,7 @@ xmlMemMalloc(size_t size)
 void *
 xmlReallocLoc(void *ptr,size_t size, const char * file, int line)
 {
-    MEMHDR *p;
+    MEMHDR *p, *tmp;
     unsigned long number;
 #ifdef DEBUG_MEMORY
     size_t oldsize;
@@ -341,15 +343,18 @@ xmlReallocLoc(void *ptr,size_t size, const char * file, int line)
     debugmem_list_delete(p);
 #endif
     xmlMutexUnlock(xmlMemMutex);
-    
-    p = (MEMHDR *) realloc(p,RESERVE_SIZE+size);
-    if (!p) {
+
+    tmp = (MEMHDR *) realloc(p,RESERVE_SIZE+size);
+    if (!tmp) {
+        free(p);
         goto error;
     }
+    p = tmp;
     if (xmlMemTraceBlockAt == ptr) {
        xmlGenericError(xmlGenericErrorContext,
-                       "%p : Realloced(%d -> %d) Ok\n",
-                       xmlMemTraceBlockAt, p->mh_size, size);
+                       "%p : Realloced(%lu -> %lu) Ok\n",
+                       xmlMemTraceBlockAt, (long unsigned)p->mh_size,
+                       (long unsigned)size);
        xmlMallocBreakpoint();
     }
     p->mh_tag = MEMTAG;
@@ -374,8 +379,8 @@ xmlReallocLoc(void *ptr,size_t size, const char * file, int line)
            "Realloced(%d to %d) Ok\n", oldsize, size);
 #endif
     return(HDR_2_CLIENT(p));
-    
-error:    
+
+error:
     return(NULL);
 }
 
@@ -409,6 +414,9 @@ xmlMemFree(void *ptr)
     size_t size;
 #endif
 
+    if (ptr == NULL)
+       return;
+
     if (ptr == (void *) -1) {
        xmlGenericError(xmlGenericErrorContext,
            "trying to free pointer from freed area\n");
@@ -452,10 +460,10 @@ xmlMemFree(void *ptr)
     xmlGenericError(xmlGenericErrorContext,
            "Freed(%d) Ok\n", size);
 #endif
-    
+
     return;
-    
-error:    
+
+error:
     xmlGenericError(xmlGenericErrorContext,
            "xmlMemFree(%lX) error\n", (unsigned long) ptr);
     xmlMallocBreakpoint();
@@ -501,16 +509,13 @@ xmlMemStrdupLoc(const char *str, const char *file, int line)
     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;
-    
+    strcpy(s,str);
+
     TEST_POINT
 
     if (xmlMemTraceBlockAt == s) {
@@ -549,7 +554,12 @@ xmlMemoryStrdup(const char *str) {
 
 int
 xmlMemUsed(void) {
-     return(debugMemSize);
+    int res;
+
+    xmlMutexLock(xmlMemMutex);
+    res = debugMemSize;
+    xmlMutexUnlock(xmlMemMutex);
+    return(res);
 }
 
 /**
@@ -562,7 +572,12 @@ xmlMemUsed(void) {
 
 int
 xmlMemBlocks(void) {
-     return(debugMemBlocks);
+    int res;
+
+    xmlMutexLock(xmlMemMutex);
+    res = debugMemBlocks;
+    xmlMutexUnlock(xmlMemMutex);
+    return(res);
 }
 
 #ifdef MEM_LIST
@@ -577,13 +592,15 @@ xmlMemBlocks(void) {
 static void
 xmlMemContentShow(FILE *fp, MEMHDR *p)
 {
-    int i,j,k,len = p->mh_size;
-    const char *buf = (const char *) HDR_2_CLIENT(p);
+    int i,j,k,len;
+    const char *buf;
 
     if (p == NULL) {
        fprintf(fp, " NULL");
        return;
     }
+    len = p->mh_size;
+    buf = (const char *) HDR_2_CLIENT(p);
 
     for (i = 0;i < len;i++) {
         if (buf[i] == 0) break;
@@ -614,7 +631,7 @@ xmlMemContentShow(FILE *fp, MEMHDR *p)
     } 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++)
@@ -626,6 +643,79 @@ xmlMemContentShow(FILE *fp, MEMHDR *p)
 #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
@@ -662,7 +752,7 @@ xmlMemDisplay(FILE *fp)
     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");
@@ -739,7 +829,7 @@ static void debugmem_list_delete(MEMHDR *p)
  *
  * internal error function.
  */
+
 static void debugmem_tag_error(void *p)
 {
      xmlGenericError(xmlGenericErrorContext,
@@ -799,7 +889,7 @@ xmlMemShow(FILE *fp, int nr ATTRIBUTE_UNUSED)
        }
     }
     xmlMutexUnlock(xmlMemMutex);
-#endif /* MEM_LIST */    
+#endif /* MEM_LIST */
 }
 
 /**
@@ -846,11 +936,11 @@ xmlInitMemory(void)
 {
 #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!
@@ -864,18 +954,18 @@ xmlInitMemory(void)
      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);
 }
 
@@ -890,7 +980,7 @@ xmlCleanupMemory(void) {
 #ifdef DEBUG_MEMORY
      xmlGenericError(xmlGenericErrorContext,
             "xmlCleanupMemory()\n");
-#endif     
+#endif
     if (xmlMemInitialized == 0)
         return;
 
@@ -900,7 +990,7 @@ xmlCleanupMemory(void) {
 #ifdef DEBUG_MEMORY
      xmlGenericError(xmlGenericErrorContext,
             "xmlCleanupMemory() Ok\n");
-#endif     
+#endif
 }
 
 /**
@@ -924,7 +1014,7 @@ xmlMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc,
 #ifdef DEBUG_MEMORY
      xmlGenericError(xmlGenericErrorContext,
             "xmlMemSetup()\n");
-#endif     
+#endif
     if (freeFunc == NULL)
        return(-1);
     if (mallocFunc == NULL)
@@ -941,7 +1031,7 @@ xmlMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc,
 #ifdef DEBUG_MEMORY
      xmlGenericError(xmlGenericErrorContext,
             "xmlMemSetup() Ok\n");
-#endif     
+#endif
     return(0);
 }
 
@@ -991,7 +1081,7 @@ xmlGcMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc,
 #ifdef DEBUG_MEMORY
      xmlGenericError(xmlGenericErrorContext,
             "xmlGcMemSetup()\n");
-#endif     
+#endif
     if (freeFunc == NULL)
        return(-1);
     if (mallocFunc == NULL)
@@ -1010,7 +1100,7 @@ xmlGcMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc,
 #ifdef DEBUG_MEMORY
      xmlGenericError(xmlGenericErrorContext,
             "xmlGcMemSetup() Ok\n");
-#endif     
+#endif
     return(0);
 }