⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmlmemory.c

📁 SIP 1.5.0源代码
💻 C
字号:
/* * memory.c:  libxml memory allocator wrapper. * * Daniel.Veillard@w3.org */#include "global.h"#ifdef WIN32#include "win32config.h"#else#include "config.h"#endif#include <stdio.h>#include <string.h>#ifdef HAVE_SYS_TYPES_H#include <sys/types.h>#endif#ifdef HAVE_TIME_H#include <time.h>#endif#ifdef HAVE_MALLOC_H#include <malloc.h>#endif#ifdef HAVE_STDLIB_H#include <stdlib.h>#endif#ifdef HAVE_CTYPE_H#include <ctype.h>#endif#include <libxml/xmlmemory.h>#ifdef xmlMalloc#undef xmlMalloc#endif#ifdef xmlRealloc#undef xmlRealloc#endif#ifdef xmlMemStrdup#undef xmlMemStrdup#endif/* * Each of the blocks allocated begin with a header containing informations */#define MEMTAG 0x5aa5#define MALLOC_TYPE 1#define REALLOC_TYPE 2#define STRDUP_TYPE 3typedef struct memnod {    unsigned int   mh_tag;    unsigned int   mh_type;    unsigned long  mh_number;    size_t         mh_size;#ifdef MEM_LIST   struct memnod *mh_next;   struct memnod *mh_prev;#endif   const char    *mh_file;   unsigned int   mh_line;}  MEMHDR;#ifdef SUN4#define ALIGN_SIZE  16#else#define ALIGN_SIZE  sizeof(double)#endif#define HDR_SIZE    sizeof(MEMHDR)#define RESERVE_SIZE (((HDR_SIZE + (ALIGN_SIZE-1)) \		      / ALIGN_SIZE ) * ALIGN_SIZE)#define CLIENT_2_HDR(a) ((MEMHDR *) (((char *) (a)) - RESERVE_SIZE))#define HDR_2_CLIENT(a)    ((void *) (((char *) (a)) + RESERVE_SIZE))static unsigned long  debugMemSize = 0;static unsigned long  debugMaxMemSize = 0;static int block=0;int xmlMemStopAtBlock = 0;int xmlMemInitialized = 0;#ifdef MEM_LISTstatic MEMHDR *memlist = NULL;#endifvoid debugmem_tag_error(void *addr);#ifdef MEM_LISTvoid  debugmem_list_add(MEMHDR *);void debugmem_list_delete(MEMHDR *);#endif#define Mem_Tag_Err(a) debugmem_tag_error(a);#ifndef TEST_POINT#define TEST_POINT#endif/** * xmlMallocBreakpoint: * * Breakpoint to use in conjunction with xmlMemStopAtBlock. When the block * number reaches the specified value this function is called. One need to add a breakpoint * to it to get the context in which the given block is allocated. */voidxmlMallocBreakpoint(void) {    fprintf(stderr, "xmlMallocBreakpoint reached on block %d\n", xmlMemStopAtBlock);}/** * xmlMallocLoc: * @size:  an int specifying the size in byte to allocate. * @file:  the file name or NULL  @file:  the line number * * a malloc() equivalent, with logging of the allocation info. * * Returns a pointer to the allocated area or NULL in case of lack of memory. */void *xmlMallocLoc(int size, const char * file, int line){    MEMHDR *p;        if (!xmlMemInitialized) xmlInitMemory();#ifdef DEBUG_MEMORY    fprintf(stderr, "Malloc(%d)\n",size);#endif    TEST_POINT        p = (MEMHDR *) malloc(RESERVE_SIZE+size);    if (!p) {	fprintf(stderr, "xmlMalloc : Out of free space\n");	xmlMemoryDump();	return(NULL);    }       p->mh_tag = MEMTAG;    p->mh_number = ++block;    p->mh_size = size;    p->mh_type = MALLOC_TYPE;    p->mh_file = file;    p->mh_line = line;    debugMemSize += size;    if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize;#ifdef MEM_LIST    debugmem_list_add(p);#endif#ifdef DEBUG_MEMORY    fprintf(stderr, "Malloc(%d) Ok\n",size);#endif        if (xmlMemStopAtBlock == block) xmlMallocBreakpoint();    TEST_POINT    return(HDR_2_CLIENT(p));}/** * xmlMemMalloc: * @size:  an int specifying the size in byte to allocate. * * a malloc() equivalent, with logging of the allocation info. * * Returns a pointer to the allocated area or NULL in case of lack of memory. */void *xmlMemMalloc(int size){    return(xmlMallocLoc(size, "none", 0));}/** * xmlReallocLoc: * @ptr:  the initial memory block pointer * @size:  an int specifying the size in byte to allocate. * @file:  the file name or NULL * @file:  the line number * * a realloc() equivalent, with logging of the allocation info. * * Returns a pointer to the allocated area or NULL in case of lack of memory. */void *xmlReallocLoc(void *ptr,int size, const char * file, int line){    MEMHDR *p;    unsigned long number;    if (!xmlMemInitialized) xmlInitMemory();    TEST_POINT    p = CLIENT_2_HDR(ptr);    number = p->mh_number;    if (p->mh_tag != MEMTAG) {       Mem_Tag_Err(p);	 goto error;    }    p->mh_tag = ~MEMTAG;    debugMemSize -= p->mh_size;#ifdef MEM_LIST    debugmem_list_delete(p);#endif    p = (MEMHDR *) realloc(p,RESERVE_SIZE+size);    if (!p) {	 goto error;    }    p->mh_tag = MEMTAG;    p->mh_number = number;    p->mh_type = REALLOC_TYPE;    p->mh_size = size;    p->mh_file = file;    p->mh_line = line;    debugMemSize += size;    if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize;#ifdef MEM_LIST    debugmem_list_add(p);#endif    TEST_POINT    return(HDR_2_CLIENT(p));    error:        return(NULL);}/** * xmlMemRealloc: * @ptr:  the initial memory block pointer * @size:  an int specifying the size in byte to allocate. * * a realloc() equivalent, with logging of the allocation info. * * Returns a pointer to the allocated area or NULL in case of lack of memory. */void *xmlMemRealloc(void *ptr,int size) {    return(xmlReallocLoc(ptr, size, "none", 0));}/** * xmlMemFree: * @ptr:  the memory block pointer * * a free() equivalent, with error checking. */voidxmlMemFree(void *ptr){    MEMHDR *p;    TEST_POINT    p = CLIENT_2_HDR(ptr);    if (p->mh_tag != MEMTAG) {       Mem_Tag_Err(p);       goto error;    }    p->mh_tag = ~MEMTAG;    debugMemSize -= p->mh_size;#ifdef MEM_LIST    debugmem_list_delete(p);#endif    free(p);    TEST_POINT    return;    error:        fprintf(stderr, "xmlFree(%X) error\n", (unsigned int) ptr);    return;}/** * xmlMemStrdupLoc: * @ptr:  the initial string pointer * @file:  the file name or NULL * @file:  the line number * * a strdup() equivalent, with logging of the allocation info. * * Returns a pointer to the new string or NULL if allocation error occured. */char *xmlMemStrdupLoc(const char *str, const char *file, int line){    char *s;    size_t size = strlen(str) + 1;    MEMHDR *p;    if (!xmlMemInitialized) xmlInitMemory();    TEST_POINT    p = (MEMHDR *) malloc(RESERVE_SIZE+size);    if (!p) {      goto error;    }    p->mh_tag = MEMTAG;    p->mh_number = ++block;    p->mh_size = size;    p->mh_type = STRDUP_TYPE;    p->mh_file = file;    p->mh_line = line;    debugMemSize += size;    if (debugMemSize > debugMaxMemSize) debugMaxMemSize = debugMemSize;#ifdef MEM_LIST    debugmem_list_add(p);#endif    s = HDR_2_CLIENT(p);        if (xmlMemStopAtBlock == block) xmlMallocBreakpoint();    if (s != NULL)      strcpy(s,str);    else      goto error;        TEST_POINT    return(s);error:    return(NULL);}/** * xmlMemoryStrdup: * @ptr:  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 occured. */char *xmlMemoryStrdup(const char *str) {    return(xmlMemStrdupLoc(str, "none", 0));}/** * xmlMemUsed: * * returns the amount of memory currenly 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 */voidxmlMemContentShow(FILE *fp, MEMHDR *p){    int i,j,len = p->mh_size;    const char *buf = HDR_2_CLIENT(p);    for (i = 0;i < len;i++) {        if (buf[i] == 0) break;	if (!isprint(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 == 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/** * 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){#ifdef MEM_LIST    MEMHDR *p;#endif    if (fp != NULL)	fprintf(fp,"      MEMORY ALLOCATED : %lu, MAX was %lu\n",		debugMemSize, debugMaxMemSize);#ifdef MEM_LIST    if (nr > 0) {	fprintf(fp,"NUMBER   SIZE  TYPE   WHERE\n");	p = memlist;	while ((p) && nr > 0) {	      fprintf(fp,"%6lu %6u ",p->mh_number,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;			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;	}    }#endif /* MEM_LIST */    }/** * 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;    int     idx;#if defined(HAVE_LOCALTIME) && defined(HAVE_STRFTIME)    time_t currentTime;    char buf[500];    struct tm * tstruct;    currentTime = time(NULL);    tstruct = localtime(&currentTime);    strftime(buf, sizeof(buf) - 1, "%c", 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;    p = memlist;    while (p) {	  fprintf(fp,"%-5u  %6lu %6u ",idx++,p->mh_number,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;                    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");        p = p->mh_next;    }#else    fprintf(fp,"Memory list not compiled (MEM_LIST not defined !)\n");#endif}#ifdef MEM_LISTvoid 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}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. */ void debugmem_tag_error(void *p){     fprintf(stderr, "Memory tag error occurs :%p \n\t bye\n", p);#ifdef MEM_LIST     if (stderr)     xmlMemDisplay(stderr);#endif}FILE *xmlMemoryDumpFile = NULL;/** * xmlMemoryDump: * * Dump in-extenso the memory blocks allocated to the file .memorylist */voidxmlMemoryDump(void){#if defined(DEBUG_MEMORY_LOCATION) | defined(DEBUG_MEMORY)    FILE *dump;    dump = fopen(".memdump", "w");    if (dump == NULL) xmlMemoryDumpFile = stdout;    else xmlMemoryDumpFile = dump;    xmlMemDisplay(xmlMemoryDumpFile);    if (dump != NULL) fclose(dump);#endif}/**************************************************************** *								* *		Initialization Routines				* *								* ****************************************************************/#if defined(DEBUG_MEMORY_LOCATION) | defined(DEBUG_MEMORY)xmlFreeFunc xmlFree = (xmlFreeFunc) xmlMemFree;xmlMallocFunc xmlMalloc = (xmlMallocFunc) xmlMemMalloc;xmlReallocFunc xmlRealloc = (xmlReallocFunc) xmlMemRealloc;xmlStrdupFunc xmlMemStrdup = (xmlStrdupFunc) xmlMemoryStrdup;#elsexmlFreeFunc xmlFree = (xmlFreeFunc) free;xmlMallocFunc xmlMalloc = (xmlMallocFunc) malloc;xmlReallocFunc xmlRealloc = (xmlReallocFunc) realloc;xmlStrdupFunc xmlMemStrdup = (xmlStrdupFunc) strdup;#endif/** * xmlInitMemory: * * Initialize the memory layer. * * Returns 0 on success */static int xmlInitMemoryDone = 0;intxmlInitMemory(void){     int ret;     #ifdef HAVE_STDLIB_H     char *breakpoint;#endif          if (xmlInitMemoryDone) return(-1);#ifdef HAVE_STDLIB_H     breakpoint = getenv("XML_MEM_BREAKPOINT");     if (breakpoint != NULL) {         sscanf(breakpoint, "%d", &xmlMemStopAtBlock);     }#endif         #ifdef DEBUG_MEMORY     fprintf(stderr, "xmlInitMemory() Ok\n");#endif          ret = 0;     return(ret);}/** * 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;    xmlRealloc = reallocFunc;    xmlMemStrdup = strdupFunc;    return(0);}/** * xmlMemGet: * @freeFunc: the free() function in use * @mallocFunc: the malloc() function in use * @reallocFunc: the realloc() function in use * @strdupFunc: the strdup() function in use * * Return 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);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -