Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenxmlmemory.cGo to the documentation of this file.00001 /* 00002 * xmlmemory.c: libxml memory allocator wrapper. 00003 * 00004 * daniel@veillard.com 00005 */ 00006 00007 #define IN_LIBXML 00008 #include "libxml.h" 00009 00010 #include <string.h> 00011 00012 #ifdef HAVE_SYS_TYPES_H 00013 #include <sys/types.h> 00014 #endif 00015 00016 #ifdef HAVE_TIME_H 00017 #include <time.h> 00018 #endif 00019 00020 #ifdef HAVE_STDLIB_H 00021 #include <stdlib.h> 00022 #else 00023 #ifdef HAVE_MALLOC_H 00024 #include <malloc.h> 00025 #endif 00026 #endif 00027 00028 #ifdef HAVE_CTYPE_H 00029 #include <ctype.h> 00030 #endif 00031 00032 /* #define DEBUG_MEMORY */ 00033 00040 #ifdef DEBUG_MEMORY_LOCATION 00041 #ifndef MEM_LIST 00042 #define MEM_LIST /* keep a list of all the allocated memory blocks */ 00043 #endif 00044 #endif 00045 00046 #include <libxml/globals.h> /* must come before xmlmemory.h */ 00047 #include <libxml/xmlmemory.h> 00048 #include <libxml/xmlerror.h> 00049 #include <libxml/threads.h> 00050 00051 static int xmlMemInitialized = 0; 00052 static unsigned long debugMemSize = 0; 00053 static unsigned long debugMemBlocks = 0; 00054 static unsigned long debugMaxMemSize = 0; 00055 static xmlMutexPtr xmlMemMutex = NULL; 00056 00057 void xmlMallocBreakpoint(void); 00058 00059 /************************************************************************ 00060 * * 00061 * Macros, variables and associated types * 00062 * * 00063 ************************************************************************/ 00064 00065 #if !defined(LIBXML_THREAD_ENABLED) && !defined(LIBXML_THREAD_ALLOC_ENABLED) 00066 #ifdef xmlMalloc 00067 #undef xmlMalloc 00068 #endif 00069 #ifdef xmlRealloc 00070 #undef xmlRealloc 00071 #endif 00072 #ifdef xmlMemStrdup 00073 #undef xmlMemStrdup 00074 #endif 00075 #endif 00076 00077 /* 00078 * Each of the blocks allocated begin with a header containing informations 00079 */ 00080 00081 #define MEMTAG 0x5aa5 00082 00083 #define MALLOC_TYPE 1 00084 #define REALLOC_TYPE 2 00085 #define STRDUP_TYPE 3 00086 #define MALLOC_ATOMIC_TYPE 4 00087 #define REALLOC_ATOMIC_TYPE 5 00088 00089 typedef struct memnod { 00090 unsigned int mh_tag; 00091 unsigned int mh_type; 00092 unsigned long mh_number; 00093 size_t mh_size; 00094 #ifdef MEM_LIST 00095 struct memnod *mh_next; 00096 struct memnod *mh_prev; 00097 #endif 00098 const char *mh_file; 00099 unsigned int mh_line; 00100 } MEMHDR; 00101 00102 00103 #ifdef SUN4 00104 #define ALIGN_SIZE 16 00105 #else 00106 #define ALIGN_SIZE sizeof(double) 00107 #endif 00108 #define HDR_SIZE sizeof(MEMHDR) 00109 #define RESERVE_SIZE (((HDR_SIZE + (ALIGN_SIZE-1)) \ 00110 / ALIGN_SIZE ) * ALIGN_SIZE) 00111 00112 00113 #define CLIENT_2_HDR(a) ((MEMHDR *) (((char *) (a)) - RESERVE_SIZE)) 00114 #define HDR_2_CLIENT(a) ((void *) (((char *) (a)) + RESERVE_SIZE)) 00115 00116 00117 static unsigned int block=0; 00118 static unsigned int xmlMemStopAtBlock = 0; 00119 static void *xmlMemTraceBlockAt = NULL; 00120 #ifdef MEM_LIST 00121 static MEMHDR *memlist = NULL; 00122 #endif 00123 00124 static void debugmem_tag_error(void *addr); 00125 #ifdef MEM_LIST 00126 static void debugmem_list_add(MEMHDR *); 00127 static void debugmem_list_delete(MEMHDR *); 00128 #endif 00129 #define Mem_Tag_Err(a) debugmem_tag_error(a); 00130 00131 #ifndef TEST_POINT 00132 #define TEST_POINT 00133 #endif 00134 00143 void 00144 xmlMallocBreakpoint(void) { 00145 xmlGenericError(xmlGenericErrorContext, 00146 "xmlMallocBreakpoint reached on block %d\n", xmlMemStopAtBlock); 00147 } 00148 00160 void * 00161 xmlMallocLoc(size_t size, const char * file, int line) 00162 { 00163 MEMHDR *p; 00164 void *ret; 00165 00166 if (!xmlMemInitialized) xmlInitMemory(); 00167 #ifdef DEBUG_MEMORY 00168 xmlGenericError(xmlGenericErrorContext, 00169 "Malloc(%d)\n",size); 00170 #endif 00171 00172 TEST_POINT 00173 00174 p = (MEMHDR *) malloc(RESERVE_SIZE+size); 00175 00176 if (!p) { 00177 xmlGenericError(xmlGenericErrorContext, 00178 "xmlMallocLoc : Out of free space\n"); 00179 xmlMemoryDump(); 00180 return(NULL); 00181 } 00182 p->mh_tag = MEMTAG; 00183 p->mh_size = size; 00184 p->mh_type = MALLOC_TYPE; 00185 p->mh_file = file; 00186 p->mh_line = line; 00187 xmlMutexLock(xmlMemMutex); 00188 p->mh_number = ++block; 00189 debugMemSize += size; 00190 debugMemBlocks++; 00191 if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize; 00192 #ifdef MEM_LIST 00193 debugmem_list_add(p); 00194 #endif 00195 xmlMutexUnlock(xmlMemMutex); 00196 00197 #ifdef DEBUG_MEMORY 00198 xmlGenericError(xmlGenericErrorContext, 00199 "Malloc(%d) Ok\n",size); 00200 #endif 00201 00202 if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint(); 00203 00204 ret = HDR_2_CLIENT(p); 00205 00206 if (xmlMemTraceBlockAt == ret) { 00207 xmlGenericError(xmlGenericErrorContext, 00208 "%p : Malloc(%ld) Ok\n", xmlMemTraceBlockAt, size); 00209 xmlMallocBreakpoint(); 00210 } 00211 00212 TEST_POINT 00213 00214 return(ret); 00215 } 00216 00228 void * 00229 xmlMallocAtomicLoc(size_t size, const char * file, int line) 00230 { 00231 MEMHDR *p; 00232 void *ret; 00233 00234 if (!xmlMemInitialized) xmlInitMemory(); 00235 #ifdef DEBUG_MEMORY 00236 xmlGenericError(xmlGenericErrorContext, 00237 "Malloc(%d)\n",size); 00238 #endif 00239 00240 TEST_POINT 00241 00242 p = (MEMHDR *) malloc(RESERVE_SIZE+size); 00243 00244 if (!p) { 00245 xmlGenericError(xmlGenericErrorContext, 00246 "xmlMallocLoc : Out of free space\n"); 00247 xmlMemoryDump(); 00248 return(NULL); 00249 } 00250 p->mh_tag = MEMTAG; 00251 p->mh_size = size; 00252 p->mh_type = MALLOC_ATOMIC_TYPE; 00253 p->mh_file = file; 00254 p->mh_line = line; 00255 xmlMutexLock(xmlMemMutex); 00256 p->mh_number = ++block; 00257 debugMemSize += size; 00258 debugMemBlocks++; 00259 if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize; 00260 #ifdef MEM_LIST 00261 debugmem_list_add(p); 00262 #endif 00263 xmlMutexUnlock(xmlMemMutex); 00264 00265 #ifdef DEBUG_MEMORY 00266 xmlGenericError(xmlGenericErrorContext, 00267 "Malloc(%d) Ok\n",size); 00268 #endif 00269 00270 if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint(); 00271 00272 ret = HDR_2_CLIENT(p); 00273 00274 if (xmlMemTraceBlockAt == ret) { 00275 xmlGenericError(xmlGenericErrorContext, 00276 "%p : Malloc(%ld) Ok\n", xmlMemTraceBlockAt, size); 00277 xmlMallocBreakpoint(); 00278 } 00279 00280 TEST_POINT 00281 00282 return(ret); 00283 } 00293 void * 00294 xmlMemMalloc(size_t size) 00295 { 00296 return(xmlMallocLoc(size, "none", 0)); 00297 } 00298 00311 void * 00312 xmlReallocLoc(void *ptr,size_t size, const char * file, int line) 00313 { 00314 MEMHDR *p; 00315 unsigned long number; 00316 #ifdef DEBUG_MEMORY 00317 size_t oldsize; 00318 #endif 00319 00320 if (ptr == NULL) 00321 return(xmlMallocLoc(size, file, line)); 00322 00323 if (!xmlMemInitialized) xmlInitMemory(); 00324 TEST_POINT 00325 00326 p = CLIENT_2_HDR(ptr); 00327 number = p->mh_number; 00328 if (xmlMemStopAtBlock == number) xmlMallocBreakpoint(); 00329 if (p->mh_tag != MEMTAG) { 00330 Mem_Tag_Err(p); 00331 goto error; 00332 } 00333 p->mh_tag = ~MEMTAG; 00334 xmlMutexLock(xmlMemMutex); 00335 debugMemSize -= p->mh_size; 00336 debugMemBlocks--; 00337 #ifdef DEBUG_MEMORY 00338 oldsize = p->mh_size; 00339 #endif 00340 #ifdef MEM_LIST 00341 debugmem_list_delete(p); 00342 #endif 00343 xmlMutexUnlock(xmlMemMutex); 00344 00345 p = (MEMHDR *) realloc(p,RESERVE_SIZE+size); 00346 if (!p) { 00347 goto error; 00348 } 00349 if (xmlMemTraceBlockAt == ptr) { 00350 xmlGenericError(xmlGenericErrorContext, 00351 "%p : Realloced(%ld -> %ld) Ok\n", 00352 xmlMemTraceBlockAt, p->mh_size, size); 00353 xmlMallocBreakpoint(); 00354 } 00355 p->mh_tag = MEMTAG; 00356 p->mh_number = number; 00357 p->mh_type = REALLOC_TYPE; 00358 p->mh_size = size; 00359 p->mh_file = file; 00360 p->mh_line = line; 00361 xmlMutexLock(xmlMemMutex); 00362 debugMemSize += size; 00363 debugMemBlocks++; 00364 if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize; 00365 #ifdef MEM_LIST 00366 debugmem_list_add(p); 00367 #endif 00368 xmlMutexUnlock(xmlMemMutex); 00369 00370 TEST_POINT 00371 00372 #ifdef DEBUG_MEMORY 00373 xmlGenericError(xmlGenericErrorContext, 00374 "Realloced(%d to %d) Ok\n", oldsize, size); 00375 #endif 00376 return(HDR_2_CLIENT(p)); 00377 00378 error: 00379 return(NULL); 00380 } 00381 00392 void * 00393 xmlMemRealloc(void *ptr,size_t size) { 00394 return(xmlReallocLoc(ptr, size, "none", 0)); 00395 } 00396 00403 void 00404 xmlMemFree(void *ptr) 00405 { 00406 MEMHDR *p; 00407 char *target; 00408 #ifdef DEBUG_MEMORY 00409 size_t size; 00410 #endif 00411 00412 if (ptr == NULL) 00413 return; 00414 00415 if (ptr == (void *) -1) { 00416 xmlGenericError(xmlGenericErrorContext, 00417 "trying to free pointer from freed area\n"); 00418 goto error; 00419 } 00420 00421 if (xmlMemTraceBlockAt == ptr) { 00422 xmlGenericError(xmlGenericErrorContext, 00423 "%p : Freed()\n", xmlMemTraceBlockAt); 00424 xmlMallocBreakpoint(); 00425 } 00426 00427 TEST_POINT 00428 00429 target = (char *) ptr; 00430 00431 p = CLIENT_2_HDR(ptr); 00432 if (p->mh_tag != MEMTAG) { 00433 Mem_Tag_Err(p); 00434 goto error; 00435 } 00436 if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint(); 00437 p->mh_tag = ~MEMTAG; 00438 memset(target, -1, p->mh_size); 00439 xmlMutexLock(xmlMemMutex); 00440 debugMemSize -= p->mh_size; 00441 debugMemBlocks--; 00442 #ifdef DEBUG_MEMORY 00443 size = p->mh_size; 00444 #endif 00445 #ifdef MEM_LIST 00446 debugmem_list_delete(p); 00447 #endif 00448 xmlMutexUnlock(xmlMemMutex); 00449 00450 free(p); 00451 00452 TEST_POINT 00453 00454 #ifdef DEBUG_MEMORY 00455 xmlGenericError(xmlGenericErrorContext, 00456 "Freed(%d) Ok\n", size); 00457 #endif 00458 00459 return; 00460 00461 error: 00462 xmlGenericError(xmlGenericErrorContext, 00463 "xmlMemFree(%lX) error\n", (unsigned long) ptr); 00464 xmlMallocBreakpoint(); 00465 return; 00466 } 00467 00479 char * 00480 xmlMemStrdupLoc(const char *str, const char *file, int line) 00481 { 00482 char *s; 00483 size_t size = strlen(str) + 1; 00484 MEMHDR *p; 00485 00486 if (!xmlMemInitialized) xmlInitMemory(); 00487 TEST_POINT 00488 00489 p = (MEMHDR *) malloc(RESERVE_SIZE+size); 00490 if (!p) { 00491 goto error; 00492 } 00493 p->mh_tag = MEMTAG; 00494 p->mh_size = size; 00495 p->mh_type = STRDUP_TYPE; 00496 p->mh_file = file; 00497 p->mh_line = line; 00498 xmlMutexLock(xmlMemMutex); 00499 p->mh_number = ++block; 00500 debugMemSize += size; 00501 debugMemBlocks++; 00502 if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize; 00503 #ifdef MEM_LIST 00504 debugmem_list_add(p); 00505 #endif 00506 xmlMutexUnlock(xmlMemMutex); 00507 00508 s = (char *) HDR_2_CLIENT(p); 00509 00510 if (xmlMemStopAtBlock == p->mh_number) xmlMallocBreakpoint(); 00511 00512 if (s != NULL) 00513 strcpy(s,str); 00514 else 00515 goto error; 00516 00517 TEST_POINT 00518 00519 if (xmlMemTraceBlockAt == s) { 00520 xmlGenericError(xmlGenericErrorContext, 00521 "%p : Strdup() Ok\n", xmlMemTraceBlockAt); 00522 xmlMallocBreakpoint(); 00523 } 00524 00525 return(s); 00526 00527 error: 00528 return(NULL); 00529 } 00530 00540 char * 00541 xmlMemoryStrdup(const char *str) { 00542 return(xmlMemStrdupLoc(str, "none", 0)); 00543 } 00544 00553 int 00554 xmlMemUsed(void) { 00555 return(debugMemSize); 00556 } 00557 00566 int 00567 xmlMemBlocks(void) { 00568 return(debugMemBlocks); 00569 } 00570 00571 #ifdef MEM_LIST 00572 00580 static void 00581 xmlMemContentShow(FILE *fp, MEMHDR *p) 00582 { 00583 int i,j,k,len = p->mh_size; 00584 const char *buf = (const char *) HDR_2_CLIENT(p); 00585 00586 if (p == NULL) { 00587 fprintf(fp, " NULL"); 00588 return; 00589 } 00590 00591 for (i = 0;i < len;i++) { 00592 if (buf[i] == 0) break; 00593 if (!isprint((unsigned char) buf[i])) break; 00594 } 00595 if ((i < 4) && ((buf[i] != 0) || (i == 0))) { 00596 if (len >= 4) { 00597 MEMHDR *q; 00598 void *cur; 00599 00600 for (j = 0;(j < len -3) && (j < 40);j += 4) { 00601 cur = *((void **) &buf[j]); 00602 q = CLIENT_2_HDR(cur); 00603 p = memlist; 00604 k = 0; 00605 while (p != NULL) { 00606 if (p == q) break; 00607 p = p->mh_next; 00608 if (k++ > 100) break; 00609 } 00610 if ((p != NULL) && (p == q)) { 00611 fprintf(fp, " pointer to #%lu at index %d", 00612 p->mh_number, j); 00613 return; 00614 } 00615 } 00616 } 00617 } else if ((i == 0) && (buf[i] == 0)) { 00618 fprintf(fp," null"); 00619 } else { 00620 if (buf[i] == 0) fprintf(fp," \"%.25s\"", buf); 00621 else { 00622 fprintf(fp," ["); 00623 for (j = 0;j < i;j++) 00624 fprintf(fp,"%c", buf[j]); 00625 fprintf(fp,"]"); 00626 } 00627 } 00628 } 00629 #endif 00630 00641 void 00642 xmlMemDisplayLast(FILE *fp, long nbBytes) 00643 { 00644 #ifdef MEM_LIST 00645 MEMHDR *p; 00646 unsigned idx; 00647 int nb = 0; 00648 #endif 00649 FILE *old_fp = fp; 00650 00651 if (nbBytes <= 0) 00652 return; 00653 00654 if (fp == NULL) { 00655 fp = fopen(".memorylist", "w"); 00656 if (fp == NULL) 00657 return; 00658 } 00659 00660 #ifdef MEM_LIST 00661 fprintf(fp," Last %li MEMORY ALLOCATED : %lu, MAX was %lu\n", 00662 nbBytes, debugMemSize, debugMaxMemSize); 00663 fprintf(fp,"BLOCK NUMBER SIZE TYPE\n"); 00664 idx = 0; 00665 xmlMutexLock(xmlMemMutex); 00666 p = memlist; 00667 while ((p) && (nbBytes > 0)) { 00668 fprintf(fp,"%-5u %6lu %6lu ",idx++,p->mh_number, 00669 (unsigned long)p->mh_size); 00670 switch (p->mh_type) { 00671 case STRDUP_TYPE:fprintf(fp,"strdup() in ");break; 00672 case MALLOC_TYPE:fprintf(fp,"malloc() in ");break; 00673 case REALLOC_TYPE:fprintf(fp,"realloc() in ");break; 00674 case MALLOC_ATOMIC_TYPE:fprintf(fp,"atomicmalloc() in ");break; 00675 case REALLOC_ATOMIC_TYPE:fprintf(fp,"atomicrealloc() in ");break; 00676 default: 00677 fprintf(fp,"Unknown memory block, may be corrupted"); 00678 xmlMutexUnlock(xmlMemMutex); 00679 if (old_fp == NULL) 00680 fclose(fp); 00681 return; 00682 } 00683 if (p->mh_file != NULL) fprintf(fp,"%s(%u)", p->mh_file, p->mh_line); 00684 if (p->mh_tag != MEMTAG) 00685 fprintf(fp," INVALID"); 00686 nb++; 00687 if (nb < 100) 00688 xmlMemContentShow(fp, p); 00689 else 00690 fprintf(fp," skip"); 00691 00692 fprintf(fp,"\n"); 00693 nbBytes -= (unsigned long)p->mh_size; 00694 p = p->mh_next; 00695 } 00696 xmlMutexUnlock(xmlMemMutex); 00697 #else 00698 fprintf(fp,"Memory list not compiled (MEM_LIST not defined !)\n"); 00699 #endif 00700 if (old_fp == NULL) 00701 fclose(fp); 00702 } 00703 00712 void 00713 xmlMemDisplay(FILE *fp) 00714 { 00715 #ifdef MEM_LIST 00716 MEMHDR *p; 00717 unsigned idx; 00718 int nb = 0; 00719 #if defined(HAVE_LOCALTIME) && defined(HAVE_STRFTIME) 00720 time_t currentTime; 00721 char buf[500]; 00722 struct tm * tstruct; 00723 #endif 00724 #endif 00725 FILE *old_fp = fp; 00726 00727 if (fp == NULL) { 00728 fp = fopen(".memorylist", "w"); 00729 if (fp == NULL) 00730 return; 00731 } 00732 00733 #ifdef MEM_LIST 00734 #if defined(HAVE_LOCALTIME) && defined(HAVE_STRFTIME) 00735 currentTime = time(NULL); 00736 tstruct = localtime(¤tTime); 00737 strftime(buf, sizeof(buf) - 1, "%I:%M:%S %p", tstruct); 00738 fprintf(fp," %s\n\n", buf); 00739 #endif 00740 00741 00742 fprintf(fp," MEMORY ALLOCATED : %lu, MAX was %lu\n", 00743 debugMemSize, debugMaxMemSize); 00744 fprintf(fp,"BLOCK NUMBER SIZE TYPE\n"); 00745 idx = 0; 00746 xmlMutexLock(xmlMemMutex); 00747 p = memlist; 00748 while (p) { 00749 fprintf(fp,"%-5u %6lu %6lu ",idx++,p->mh_number, 00750 (unsigned long)p->mh_size); 00751 switch (p->mh_type) { 00752 case STRDUP_TYPE:fprintf(fp,"strdup() in ");break; 00753 case MALLOC_TYPE:fprintf(fp,"malloc() in ");break; 00754 case REALLOC_TYPE:fprintf(fp,"realloc() in ");break; 00755 case MALLOC_ATOMIC_TYPE:fprintf(fp,"atomicmalloc() in ");break; 00756 case REALLOC_ATOMIC_TYPE:fprintf(fp,"atomicrealloc() in ");break; 00757 default: 00758 fprintf(fp,"Unknown memory block, may be corrupted"); 00759 xmlMutexUnlock(xmlMemMutex); 00760 if (old_fp == NULL) 00761 fclose(fp); 00762 return; 00763 } 00764 if (p->mh_file != NULL) fprintf(fp,"%s(%u)", p->mh_file, p->mh_line); 00765 if (p->mh_tag != MEMTAG) 00766 fprintf(fp," INVALID"); 00767 nb++; 00768 if (nb < 100) 00769 xmlMemContentShow(fp, p); 00770 else 00771 fprintf(fp," skip"); 00772 00773 fprintf(fp,"\n"); 00774 p = p->mh_next; 00775 } 00776 xmlMutexUnlock(xmlMemMutex); 00777 #else 00778 fprintf(fp,"Memory list not compiled (MEM_LIST not defined !)\n"); 00779 #endif 00780 if (old_fp == NULL) 00781 fclose(fp); 00782 } 00783 00784 #ifdef MEM_LIST 00785 00786 static void debugmem_list_add(MEMHDR *p) 00787 { 00788 p->mh_next = memlist; 00789 p->mh_prev = NULL; 00790 if (memlist) memlist->mh_prev = p; 00791 memlist = p; 00792 #ifdef MEM_LIST_DEBUG 00793 if (stderr) 00794 Mem_Display(stderr); 00795 #endif 00796 } 00797 00798 static void debugmem_list_delete(MEMHDR *p) 00799 { 00800 if (p->mh_next) 00801 p->mh_next->mh_prev = p->mh_prev; 00802 if (p->mh_prev) 00803 p->mh_prev->mh_next = p->mh_next; 00804 else memlist = p->mh_next; 00805 #ifdef MEM_LIST_DEBUG 00806 if (stderr) 00807 Mem_Display(stderr); 00808 #endif 00809 } 00810 00811 #endif 00812 00813 /* 00814 * debugmem_tag_error: 00815 * 00816 * internal error function. 00817 */ 00818 00819 static void debugmem_tag_error(void *p) 00820 { 00821 xmlGenericError(xmlGenericErrorContext, 00822 "Memory tag error occurs :%p \n\t bye\n", p); 00823 #ifdef MEM_LIST 00824 if (stderr) 00825 xmlMemDisplay(stderr); 00826 #endif 00827 } 00828 00829 #ifdef MEM_LIST 00830 static FILE *xmlMemoryDumpFile = NULL; 00831 #endif 00832 00842 void 00843 xmlMemShow(FILE *fp, int nr ATTRIBUTE_UNUSED) 00844 { 00845 #ifdef MEM_LIST 00846 MEMHDR *p; 00847 #endif 00848 00849 if (fp != NULL) 00850 fprintf(fp," MEMORY ALLOCATED : %lu, MAX was %lu\n", 00851 debugMemSize, debugMaxMemSize); 00852 #ifdef MEM_LIST 00853 xmlMutexLock(xmlMemMutex); 00854 if (nr > 0) { 00855 fprintf(fp,"NUMBER SIZE TYPE WHERE\n"); 00856 p = memlist; 00857 while ((p) && nr > 0) { 00858 fprintf(fp,"%6lu %6lu ",p->mh_number,(unsigned long)p->mh_size); 00859 switch (p->mh_type) { 00860 case STRDUP_TYPE:fprintf(fp,"strdup() in ");break; 00861 case MALLOC_TYPE:fprintf(fp,"malloc() in ");break; 00862 case MALLOC_ATOMIC_TYPE:fprintf(fp,"atomicmalloc() in ");break; 00863 case REALLOC_TYPE:fprintf(fp,"realloc() in ");break; 00864 case REALLOC_ATOMIC_TYPE:fprintf(fp,"atomicrealloc() in ");break; 00865 default:fprintf(fp," ??? in ");break; 00866 } 00867 if (p->mh_file != NULL) 00868 fprintf(fp,"%s(%u)", p->mh_file, p->mh_line); 00869 if (p->mh_tag != MEMTAG) 00870 fprintf(fp," INVALID"); 00871 xmlMemContentShow(fp, p); 00872 fprintf(fp,"\n"); 00873 nr--; 00874 p = p->mh_next; 00875 } 00876 } 00877 xmlMutexUnlock(xmlMemMutex); 00878 #endif /* MEM_LIST */ 00879 } 00880 00887 void 00888 xmlMemoryDump(void) 00889 { 00890 #ifdef MEM_LIST 00891 FILE *dump; 00892 00893 if (debugMaxMemSize == 0) 00894 return; 00895 dump = fopen(".memdump", "w"); 00896 if (dump == NULL) 00897 xmlMemoryDumpFile = stderr; 00898 else xmlMemoryDumpFile = dump; 00899 00900 xmlMemDisplay(xmlMemoryDumpFile); 00901 00902 if (dump != NULL) fclose(dump); 00903 #endif /* MEM_LIST */ 00904 } 00905 00906 00907 /**************************************************************** 00908 * * 00909 * Initialization Routines * 00910 * * 00911 ****************************************************************/ 00912 00920 int 00921 xmlInitMemory(void) 00922 { 00923 #ifdef HAVE_STDLIB_H 00924 char *breakpoint; 00925 #endif 00926 #ifdef DEBUG_MEMORY 00927 xmlGenericError(xmlGenericErrorContext, 00928 "xmlInitMemory()\n"); 00929 #endif 00930 /* 00931 This is really not good code (see Bug 130419). Suggestions for 00932 improvement will be welcome! 00933 */ 00934 if (xmlMemInitialized) return(-1); 00935 xmlMemInitialized = 1; 00936 xmlMemMutex = xmlNewMutex(); 00937 00938 #ifdef HAVE_STDLIB_H 00939 breakpoint = getenv("XML_MEM_BREAKPOINT"); 00940 if (breakpoint != NULL) { 00941 sscanf(breakpoint, "%ud", &xmlMemStopAtBlock); 00942 } 00943 #endif 00944 #ifdef HAVE_STDLIB_H 00945 breakpoint = getenv("XML_MEM_TRACE"); 00946 if (breakpoint != NULL) { 00947 sscanf(breakpoint, "%p", &xmlMemTraceBlockAt); 00948 } 00949 #endif 00950 00951 #ifdef DEBUG_MEMORY 00952 xmlGenericError(xmlGenericErrorContext, 00953 "xmlInitMemory() Ok\n"); 00954 #endif 00955 return(0); 00956 } 00957 00964 void 00965 xmlCleanupMemory(void) { 00966 #ifdef DEBUG_MEMORY 00967 xmlGenericError(xmlGenericErrorContext, 00968 "xmlCleanupMemory()\n"); 00969 #endif 00970 if (xmlMemInitialized == 0) 00971 return; 00972 00973 xmlFreeMutex(xmlMemMutex); 00974 xmlMemMutex = NULL; 00975 xmlMemInitialized = 0; 00976 #ifdef DEBUG_MEMORY 00977 xmlGenericError(xmlGenericErrorContext, 00978 "xmlCleanupMemory() Ok\n"); 00979 #endif 00980 } 00981 00997 int 00998 xmlMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc, 00999 xmlReallocFunc reallocFunc, xmlStrdupFunc strdupFunc) { 01000 #ifdef DEBUG_MEMORY 01001 xmlGenericError(xmlGenericErrorContext, 01002 "xmlMemSetup()\n"); 01003 #endif 01004 if (freeFunc == NULL) 01005 return(-1); 01006 if (mallocFunc == NULL) 01007 return(-1); 01008 if (reallocFunc == NULL) 01009 return(-1); 01010 if (strdupFunc == NULL) 01011 return(-1); 01012 xmlFree = freeFunc; 01013 xmlMalloc = mallocFunc; 01014 xmlMallocAtomic = mallocFunc; 01015 xmlRealloc = reallocFunc; 01016 xmlMemStrdup = strdupFunc; 01017 #ifdef DEBUG_MEMORY 01018 xmlGenericError(xmlGenericErrorContext, 01019 "xmlMemSetup() Ok\n"); 01020 #endif 01021 return(0); 01022 } 01023 01035 int 01036 xmlMemGet(xmlFreeFunc *freeFunc, xmlMallocFunc *mallocFunc, 01037 xmlReallocFunc *reallocFunc, xmlStrdupFunc *strdupFunc) { 01038 if (freeFunc != NULL) *freeFunc = xmlFree; 01039 if (mallocFunc != NULL) *mallocFunc = xmlMalloc; 01040 if (reallocFunc != NULL) *reallocFunc = xmlRealloc; 01041 if (strdupFunc != NULL) *strdupFunc = xmlMemStrdup; 01042 return(0); 01043 } 01044 01063 int 01064 xmlGcMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc, 01065 xmlMallocFunc mallocAtomicFunc, xmlReallocFunc reallocFunc, 01066 xmlStrdupFunc strdupFunc) { 01067 #ifdef DEBUG_MEMORY 01068 xmlGenericError(xmlGenericErrorContext, 01069 "xmlGcMemSetup()\n"); 01070 #endif 01071 if (freeFunc == NULL) 01072 return(-1); 01073 if (mallocFunc == NULL) 01074 return(-1); 01075 if (mallocAtomicFunc == NULL) 01076 return(-1); 01077 if (reallocFunc == NULL) 01078 return(-1); 01079 if (strdupFunc == NULL) 01080 return(-1); 01081 xmlFree = freeFunc; 01082 xmlMalloc = mallocFunc; 01083 xmlMallocAtomic = mallocAtomicFunc; 01084 xmlRealloc = reallocFunc; 01085 xmlMemStrdup = strdupFunc; 01086 #ifdef DEBUG_MEMORY 01087 xmlGenericError(xmlGenericErrorContext, 01088 "xmlGcMemSetup() Ok\n"); 01089 #endif 01090 return(0); 01091 } 01092 01107 int 01108 xmlGcMemGet(xmlFreeFunc *freeFunc, xmlMallocFunc *mallocFunc, 01109 xmlMallocFunc *mallocAtomicFunc, xmlReallocFunc *reallocFunc, 01110 xmlStrdupFunc *strdupFunc) { 01111 if (freeFunc != NULL) *freeFunc = xmlFree; 01112 if (mallocFunc != NULL) *mallocFunc = xmlMalloc; 01113 if (mallocAtomicFunc != NULL) *mallocAtomicFunc = xmlMallocAtomic; 01114 if (reallocFunc != NULL) *reallocFunc = xmlRealloc; 01115 if (strdupFunc != NULL) *strdupFunc = xmlMemStrdup; 01116 return(0); 01117 } 01118 01119 #define bottom_xmlmemory 01120 #include "elfgcchack.h" Generated on Tue May 15 04:59:10 2012 for ReactOS by
1.6.3
|