📄 xmlmemory.c.svn-base
字号:
if (s != NULL) strcpy(s,str); else goto error; TEST_POINT if (xmlMemTraceBlockAt == s) { xmlGenericError(xmlGenericErrorContext, "%p : Strdup() Ok\n", xmlMemTraceBlockAt); xmlMallocBreakpoint(); } return(s);error: return(NULL);}/** * xmlMemoryStrdup: * @str: the initial string pointer * * a strdup() equivalent, with logging of the allocation info. * * Returns a pointer to the new string or NULL if allocation error occurred. */char *xmlMemoryStrdup(const char *str) { return(xmlMemStrdupLoc(str, "none", 0));}/** * xmlMemUsed: * * Provides the amount of memory currently allocated * * Returns an int representing the amount of memory allocated. */intxmlMemUsed(void) { return(debugMemSize);}#ifdef MEM_LIST/** * xmlMemContentShow: * @fp: a FILE descriptor used as the output file * @p: a memory block header * * tries to show some content from the memory block */static voidxmlMemContentShow(FILE *fp, MEMHDR *p){ int i,j,len = p->mh_size; const char *buf = (const char *) HDR_2_CLIENT(p); if (p == NULL) { fprintf(fp, " NULL"); return; } for (i = 0;i < len;i++) { if (buf[i] == 0) break; if (!isprint((unsigned char) buf[i])) break; } if ((i < 4) && ((buf[i] != 0) || (i == 0))) { if (len >= 4) { MEMHDR *q; void *cur; for (j = 0;j < len -3;j += 4) { cur = *((void **) &buf[j]); q = CLIENT_2_HDR(cur); p = memlist; while (p != NULL) { if (p == q) break; p = p->mh_next; } if ((p != NULL) && (p == q)) { fprintf(fp, " pointer to #%lu at index %d", p->mh_number, j); return; } } } } else if ((i == 0) && (buf[i] == 0)) { fprintf(fp," null"); } else { if (buf[i] == 0) fprintf(fp," \"%.25s\"", buf); else { fprintf(fp," ["); for (j = 0;j < i;j++) fprintf(fp,"%c", buf[j]); fprintf(fp,"]"); } }}#endif/** * xmlMemDisplay: * @fp: a FILE descriptor used as the output file, if NULL, the result is * written to the file .memorylist * * show in-extenso the memory blocks allocated */voidxmlMemDisplay(FILE *fp){#ifdef MEM_LIST MEMHDR *p; unsigned idx; int nb = 0;#if defined(HAVE_LOCALTIME) && defined(HAVE_STRFTIME) time_t currentTime; char buf[500]; struct tm * tstruct; currentTime = time(NULL); tstruct = localtime(¤tTime); strftime(buf, sizeof(buf) - 1, "%I:%M:%S %p", tstruct); 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"); idx = 0; xmlMutexLock(xmlMemMutex); p = memlist; while (p) { 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," ??? in ");break; } if (p->mh_file != NULL) fprintf(fp,"%s(%d)", 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"); p = p->mh_next; } xmlMutexUnlock(xmlMemMutex);#else fprintf(fp,"Memory list not compiled (MEM_LIST not defined !)\n");#endif}#ifdef MEM_LISTstatic void debugmem_list_add(MEMHDR *p){ p->mh_next = memlist; p->mh_prev = NULL; if (memlist) memlist->mh_prev = p; memlist = p;#ifdef MEM_LIST_DEBUG if (stderr) Mem_Display(stderr);#endif}static void debugmem_list_delete(MEMHDR *p){ if (p->mh_next) p->mh_next->mh_prev = p->mh_prev; if (p->mh_prev) p->mh_prev->mh_next = p->mh_next; else memlist = p->mh_next;#ifdef MEM_LIST_DEBUG if (stderr) Mem_Display(stderr);#endif}#endif/* * debugmem_tag_error: * * internal error function. */ static void debugmem_tag_error(void *p){ xmlGenericError(xmlGenericErrorContext, "Memory tag error occurs :%p \n\t bye\n", p);#ifdef MEM_LIST if (stderr) xmlMemDisplay(stderr);#endif}#ifdef MEM_LISTstatic FILE *xmlMemoryDumpFile = NULL;#endif/** * xmlMemShow: * @fp: a FILE descriptor used as the output file * @nr: number of entries to dump * * show a show display of the memory allocated, and dump * the @nr last allocated areas which were not freed */voidxmlMemShow(FILE *fp, int nr ATTRIBUTE_UNUSED){#ifdef MEM_LIST MEMHDR *p;#endif if (fp != NULL) fprintf(fp," MEMORY ALLOCATED : %lu, MAX was %lu\n", debugMemSize, debugMaxMemSize);#ifdef MEM_LIST xmlMutexLock(xmlMemMutex); if (nr > 0) { fprintf(fp,"NUMBER SIZE TYPE WHERE\n"); p = memlist; while ((p) && nr > 0) { fprintf(fp,"%6lu %6lu ",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 MALLOC_ATOMIC_TYPE:fprintf(fp,"atomicmalloc() in ");break; case REALLOC_TYPE:fprintf(fp,"realloc() in ");break; case REALLOC_ATOMIC_TYPE:fprintf(fp,"atomicrealloc() in ");break; default:fprintf(fp," ??? in ");break; } if (p->mh_file != NULL) fprintf(fp,"%s(%d)", p->mh_file, p->mh_line); if (p->mh_tag != MEMTAG) fprintf(fp," INVALID"); xmlMemContentShow(fp, p); fprintf(fp,"\n"); nr--; p = p->mh_next; } } xmlMutexUnlock(xmlMemMutex);#endif /* MEM_LIST */ }/** * xmlMemoryDump: * * Dump in-extenso the memory blocks allocated to the file .memorylist */voidxmlMemoryDump(void){#ifdef MEM_LIST FILE *dump; if (debugMaxMemSize == 0) return; dump = fopen(".memdump", "w"); if (dump == NULL) xmlMemoryDumpFile = stderr; else xmlMemoryDumpFile = dump; xmlMemDisplay(xmlMemoryDumpFile); if (dump != NULL) fclose(dump);#endif /* MEM_LIST */}/**************************************************************** * * * Initialization Routines * * * ****************************************************************//** * xmlInitMemory: * * Initialize the memory layer. * * Returns 0 on success */intxmlInitMemory(void){#ifdef HAVE_STDLIB_H char *breakpoint;#endif /* This is really not good code (see Bug 130419). Suggestions for improvement will be welcome! */ if (xmlMemInitialized) return(-1); xmlMemInitialized = 1; xmlMemMutex = xmlNewMutex();#ifdef HAVE_STDLIB_H breakpoint = getenv("XML_MEM_BREAKPOINT"); if (breakpoint != NULL) { sscanf(breakpoint, "%ud", &xmlMemStopAtBlock); }#endif #ifdef HAVE_STDLIB_H breakpoint = getenv("XML_MEM_TRACE"); if (breakpoint != NULL) { sscanf(breakpoint, "%p", &xmlMemTraceBlockAt); }#endif #ifdef DEBUG_MEMORY xmlGenericError(xmlGenericErrorContext, "xmlInitMemory() Ok\n");#endif return(0);}/** * xmlCleanupMemory: * * Free up all the memory associated with memorys */voidxmlCleanupMemory(void) { if (xmlMemInitialized == 0) return; xmlFreeMutex(xmlMemMutex); xmlMemMutex = NULL; xmlMemInitialized = 0;}/** * xmlMemSetup: * @freeFunc: the free() function to use * @mallocFunc: the malloc() function to use * @reallocFunc: the realloc() function to use * @strdupFunc: the strdup() function to use * * Override the default memory access functions with a new set * This has to be called before any other libxml routines ! * * Should this be blocked if there was already some allocations * done ? * * Returns 0 on success */intxmlMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc, xmlReallocFunc reallocFunc, xmlStrdupFunc strdupFunc) { if (freeFunc == NULL) return(-1); if (mallocFunc == NULL) return(-1); if (reallocFunc == NULL) return(-1); if (strdupFunc == NULL) return(-1); xmlFree = freeFunc; xmlMalloc = mallocFunc; xmlMallocAtomic = mallocFunc; xmlRealloc = reallocFunc; xmlMemStrdup = strdupFunc; return(0);}/** * xmlMemGet: * @freeFunc: place to save the free() function in use * @mallocFunc: place to save the malloc() function in use * @reallocFunc: place to save the realloc() function in use * @strdupFunc: place to save the strdup() function in use * * Provides the memory access functions set currently in use * * Returns 0 on success */intxmlMemGet(xmlFreeFunc *freeFunc, xmlMallocFunc *mallocFunc, xmlReallocFunc *reallocFunc, xmlStrdupFunc *strdupFunc) { if (freeFunc != NULL) *freeFunc = xmlFree; if (mallocFunc != NULL) *mallocFunc = xmlMalloc; if (reallocFunc != NULL) *reallocFunc = xmlRealloc; if (strdupFunc != NULL) *strdupFunc = xmlMemStrdup; return(0);}/** * xmlGcMemSetup: * @freeFunc: the free() function to use * @mallocFunc: the malloc() function to use * @mallocAtomicFunc: the malloc() function to use for atomic allocations * @reallocFunc: the realloc() function to use * @strdupFunc: the strdup() function to use * * Override the default memory access functions with a new set * This has to be called before any other libxml routines ! * The mallocAtomicFunc is specialized for atomic block * allocations (i.e. of areas useful for garbage collected memory allocators * * Should this be blocked if there was already some allocations * done ? * * Returns 0 on success */intxmlGcMemSetup(xmlFreeFunc freeFunc, xmlMallocFunc mallocFunc, xmlMallocFunc mallocAtomicFunc, xmlReallocFunc reallocFunc, xmlStrdupFunc strdupFunc) { if (freeFunc == NULL) return(-1); if (mallocFunc == NULL) return(-1); if (mallocAtomicFunc == NULL) return(-1); if (reallocFunc == NULL) return(-1); if (strdupFunc == NULL) return(-1); xmlFree = freeFunc; xmlMalloc = mallocFunc; xmlMallocAtomic = mallocAtomicFunc; xmlRealloc = reallocFunc; xmlMemStrdup = strdupFunc; return(0);}/** * xmlGcMemGet: * @freeFunc: place to save the free() function in use * @mallocFunc: place to save the malloc() function in use * @mallocAtomicFunc: place to save the atomic malloc() function in use * @reallocFunc: place to save the realloc() function in use * @strdupFunc: place to save the strdup() function in use * * Provides the memory access functions set currently in use * The mallocAtomicFunc is specialized for atomic block * allocations (i.e. of areas useful for garbage collected memory allocators * * Returns 0 on success */intxmlGcMemGet(xmlFreeFunc *freeFunc, xmlMallocFunc *mallocFunc, xmlMallocFunc *mallocAtomicFunc, xmlReallocFunc *reallocFunc, xmlStrdupFunc *strdupFunc) { if (freeFunc != NULL) *freeFunc = xmlFree; if (mallocFunc != NULL) *mallocFunc = xmlMalloc; if (mallocAtomicFunc != NULL) *mallocAtomicFunc = xmlMallocAtomic; if (reallocFunc != NULL) *reallocFunc = xmlRealloc; if (strdupFunc != NULL) *strdupFunc = xmlMemStrdup; return(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -