Annotation of XML/xmlmemory.c, revision 1.1

1.1     ! daniel      1: /*
        !             2:  * memory.c:  libxml memory allocator wrapper.
        !             3:  *
        !             4:  * Daniel.Veillard@w3.org
        !             5:  */
        !             6: 
        !             7: #include <sys/types.h>
        !             8: #include <string.h>
        !             9: #include <stdio.h>
        !            10: #include <malloc.h>
        !            11: #include "xmlmemory.h"
        !            12: 
        !            13: #ifndef NO_XML_MEMORY
        !            14: 
        !            15: #ifdef xmlMalloc
        !            16: #undef xmlMalloc
        !            17: #endif
        !            18: #ifdef xmlRealloc
        !            19: #undef xmlRealloc
        !            20: #endif
        !            21: #ifdef xmlMemStrdup
        !            22: #undef xmlMemStrdup
        !            23: #endif
        !            24: extern void xmlMemoryDump(void);
        !            25: 
        !            26: /*
        !            27:  * Each of the blocks allocated begin with a header containing informations
        !            28:  */
        !            29: 
        !            30: #define MEMTAG 0x5aa5
        !            31: 
        !            32: #define MALLOC_TYPE 1
        !            33: #define REALLOC_TYPE 2
        !            34: #define STRDUP_TYPE 3
        !            35: 
        !            36: typedef struct memnod {
        !            37:     unsigned int   mh_tag;
        !            38:     unsigned int   mh_type;
        !            39:     unsigned long  mh_number;
        !            40:     size_t         mh_size;
        !            41: #ifdef MEM_LIST
        !            42:    struct memnod *mh_next;
        !            43:    struct memnod *mh_prev;
        !            44: #endif
        !            45:    const char    *mh_file;
        !            46:    unsigned int   mh_line;
        !            47: }  MEMHDR;
        !            48: 
        !            49: 
        !            50: #ifdef SUN4
        !            51: #define ALIGN_SIZE  16
        !            52: #else
        !            53: #define ALIGN_SIZE  sizeof(double)
        !            54: #endif
        !            55: #define HDR_SIZE    sizeof(MEMHDR)
        !            56: #define RESERVE_SIZE (((HDR_SIZE + (ALIGN_SIZE-1)) \
        !            57:                      / ALIGN_SIZE ) * ALIGN_SIZE)
        !            58: 
        !            59: 
        !            60: #define CLIENT_2_HDR(a) ((MEMHDR *) (((char *) (a)) - RESERVE_SIZE))
        !            61: #define HDR_2_CLIENT(a)    ((void *) (((char *) (a)) + RESERVE_SIZE))
        !            62: 
        !            63: 
        !            64: static unsigned long  debugMemSize = 0;
        !            65: static int block=0;
        !            66: #ifdef MEM_LIST
        !            67: static MEMHDR *memlist = NULL;
        !            68: #endif
        !            69: 
        !            70: void debugmem_tag_error(void *addr);
        !            71: #ifdef MEM_LIST
        !            72: void  debugmem_list_add(MEMHDR *);
        !            73: void debugmem_list_delete(MEMHDR *);
        !            74: #endif
        !            75: #define Mem_Tag_Err(a) debugmem_tag_error(a);
        !            76: 
        !            77: #ifndef TEST_POINT
        !            78: #define TEST_POINT
        !            79: #endif
        !            80: 
        !            81: /**
        !            82:  * xmlMallocLoc:
        !            83:  * @size:  an int specifying the size in byte to allocate.
        !            84:  * @file:  the file name or NULL
        !            85:  * @file:  the line number
        !            86:  *
        !            87:  * a malloc() equivalent, with logging of the allocation info.
        !            88:  *
        !            89:  * Returns a pointer to the allocated area or NULL in case of lack of memory.
        !            90:  */
        !            91: 
        !            92: void *
        !            93: xmlMallocLoc(int size, const char * file, int line)
        !            94: {
        !            95:     MEMHDR *p;
        !            96:     
        !            97: #ifdef DEBUG_MEMORY
        !            98:     fprintf(stderr, "Malloc(%d)\n",size);
        !            99: #endif
        !           100: 
        !           101:     TEST_POINT
        !           102:     
        !           103:     p = (MEMHDR *) malloc(RESERVE_SIZE+size);
        !           104: 
        !           105:     if (!p) {
        !           106:        fprintf(stderr, "xmlMalloc : Out of free space\n");
        !           107:        xmlMemoryDump();
        !           108:     }   
        !           109:     p->mh_tag = MEMTAG;
        !           110:     p->mh_number = ++block;
        !           111:     p->mh_size = size;
        !           112:     p->mh_type = MALLOC_TYPE;
        !           113:     p->mh_file = file;
        !           114:     p->mh_line = line;
        !           115:     debugMemSize += size;
        !           116: #ifdef MEM_LIST
        !           117:     debugmem_list_add(p);
        !           118: #endif
        !           119: 
        !           120: #ifdef DEBUG_MEMORY
        !           121:     fprintf(stderr, "Malloc(%d) Ok\n",size);
        !           122: #endif
        !           123:     
        !           124: 
        !           125:     TEST_POINT
        !           126: 
        !           127:     return(HDR_2_CLIENT(p));
        !           128: }
        !           129: 
        !           130: /**
        !           131:  * xmlMalloc:
        !           132:  * @size:  an int specifying the size in byte to allocate.
        !           133:  *
        !           134:  * a malloc() equivalent, with logging of the allocation info.
        !           135:  *
        !           136:  * Returns a pointer to the allocated area or NULL in case of lack of memory.
        !           137:  */
        !           138: 
        !           139: void *
        !           140: xmlMalloc(int size)
        !           141: {
        !           142:     return(xmlMallocLoc(size, "none", 0));
        !           143: }
        !           144: 
        !           145: /**
        !           146:  * xmlReallocLoc:
        !           147:  * @ptr:  the initial memory block pointer
        !           148:  * @size:  an int specifying the size in byte to allocate.
        !           149:  * @file:  the file name or NULL
        !           150:  * @file:  the line number
        !           151:  *
        !           152:  * a realloc() equivalent, with logging of the allocation info.
        !           153:  *
        !           154:  * Returns a pointer to the allocated area or NULL in case of lack of memory.
        !           155:  */
        !           156: 
        !           157: void *
        !           158: xmlReallocLoc(void *ptr,int size, const char * file, int line)
        !           159: {
        !           160:     MEMHDR *p;
        !           161:     unsigned long number;
        !           162: 
        !           163:     TEST_POINT
        !           164: 
        !           165:     p = CLIENT_2_HDR(ptr);
        !           166:     number = p->mh_number;
        !           167:     if (p->mh_tag != MEMTAG) {
        !           168:          Mem_Tag_Err(p);
        !           169:         goto error;
        !           170:     }
        !           171:     p->mh_tag = ~MEMTAG;
        !           172:     debugMemSize -= p->mh_size;
        !           173: #ifdef MEM_LIST
        !           174:     debugmem_list_delete(p);
        !           175: #endif
        !           176: 
        !           177:     p = (MEMHDR *) realloc(p,RESERVE_SIZE+size);
        !           178:     if (!p) {
        !           179:         goto error;
        !           180:     }
        !           181:     p->mh_tag = MEMTAG;
        !           182:     p->mh_number = number;
        !           183:     p->mh_type = REALLOC_TYPE;
        !           184:     p->mh_size = size;
        !           185:     p->mh_file = file;
        !           186:     p->mh_line = line;
        !           187:     debugMemSize += size;
        !           188: #ifdef MEM_LIST
        !           189:     debugmem_list_add(p);
        !           190: #endif
        !           191: 
        !           192:     TEST_POINT
        !           193: 
        !           194:     return(HDR_2_CLIENT(p));
        !           195:     
        !           196: error:    
        !           197:     return(NULL);
        !           198: }
        !           199: 
        !           200: /**
        !           201:  * xmlRealloc:
        !           202:  * @ptr:  the initial memory block pointer
        !           203:  * @size:  an int specifying the size in byte to allocate.
        !           204:  *
        !           205:  * a realloc() equivalent, with logging of the allocation info.
        !           206:  *
        !           207:  * Returns a pointer to the allocated area or NULL in case of lack of memory.
        !           208:  */
        !           209: 
        !           210: void *
        !           211: xmlRealloc(void *ptr,int size) {
        !           212:     return(xmlReallocLoc(ptr, size, "none", 0));
        !           213: }
        !           214: 
        !           215: /**
        !           216:  * xmlFree:
        !           217:  * @ptr:  the memory block pointer
        !           218:  *
        !           219:  * a free() equivalent, with error checking.
        !           220:  *
        !           221:  * Returns a pointer to the allocated area or NULL in case of lack of memory.
        !           222:  */
        !           223: 
        !           224: 
        !           225: void
        !           226: xmlFree(void *ptr)
        !           227: {
        !           228:     MEMHDR *p;
        !           229: 
        !           230:     TEST_POINT
        !           231: 
        !           232:     p = CLIENT_2_HDR(ptr);
        !           233:     if (p->mh_tag != MEMTAG) {
        !           234:          Mem_Tag_Err(p);
        !           235:          goto error;
        !           236:     }
        !           237:     p->mh_tag = ~MEMTAG;
        !           238:     debugMemSize -= p->mh_size;
        !           239: 
        !           240: #ifdef MEM_LIST
        !           241:     debugmem_list_delete(p);
        !           242: #endif
        !           243:     free(p);
        !           244: 
        !           245:     TEST_POINT
        !           246: 
        !           247:     return;
        !           248:     
        !           249: error:    
        !           250:     fprintf(stderr, "xmlFree(%X) error\n", (unsigned int) ptr);
        !           251:     return;
        !           252: }
        !           253: 
        !           254: /**
        !           255:  * xmlMemStrdupLoc:
        !           256:  * @ptr:  the initial string pointer
        !           257:  * @file:  the file name or NULL
        !           258:  * @file:  the line number
        !           259:  *
        !           260:  * a strdup() equivalent, with logging of the allocation info.
        !           261:  *
        !           262:  * Returns a pointer to the new string or NULL if allocation error occured.
        !           263:  */
        !           264: 
        !           265: char *
        !           266: xmlMemStrdupLoc(const char *str, const char *file, int line)
        !           267: {
        !           268:     char *s;
        !           269:     size_t size = strlen(str) + 1;
        !           270:     MEMHDR *p;
        !           271: 
        !           272:     TEST_POINT
        !           273: 
        !           274:     p = (MEMHDR *) malloc(RESERVE_SIZE+size);
        !           275:     if (!p) {
        !           276:         goto error;
        !           277:     }
        !           278:     p->mh_tag = MEMTAG;
        !           279:     p->mh_number = ++block;
        !           280:     p->mh_size = size;
        !           281:     p->mh_type = STRDUP_TYPE;
        !           282:     p->mh_file = file;
        !           283:     p->mh_line = line;
        !           284:     debugMemSize += size;
        !           285: #ifdef MEM_LIST
        !           286:     debugmem_list_add(p);
        !           287: #endif
        !           288:     s = HDR_2_CLIENT(p);
        !           289:     
        !           290:     if (s != NULL)
        !           291:         strcpy(s,str);
        !           292:     else
        !           293:         goto error;
        !           294:     
        !           295:     TEST_POINT
        !           296: 
        !           297:     return(s);
        !           298: 
        !           299: error:
        !           300:     return(NULL);
        !           301: }
        !           302: 
        !           303: /**
        !           304:  * xmlMemStrdup:
        !           305:  * @ptr:  the initial string pointer
        !           306:  *
        !           307:  * a strdup() equivalent, with logging of the allocation info.
        !           308:  *
        !           309:  * Returns a pointer to the new string or NULL if allocation error occured.
        !           310:  */
        !           311: 
        !           312: char *
        !           313: xmlMemStrdup(const char *str) {
        !           314:     return(xmlMemStrdupLoc(str, "none", 0));
        !           315: }
        !           316: 
        !           317: /**
        !           318:  * xmlMemUsed:
        !           319:  *
        !           320:  * returns the amount of memory currenly allocated
        !           321:  *
        !           322:  * Returns an int representing the amount of memory allocated.
        !           323:  */
        !           324: 
        !           325: int
        !           326: xmlMemUsed(void) {
        !           327:      return(debugMemSize);
        !           328: }
        !           329: 
        !           330: /**
        !           331:  * xmlMemDisplay:
        !           332:  * @fp:  a FILE descriptor used as the output file, if NULL, the result is
        !           333:  8       written to the file .memorylist
        !           334:  *
        !           335:  * show in-extenso the memory blocks allocated
        !           336:  */
        !           337: 
        !           338: void
        !           339: xmlMemDisplay(FILE *fp)
        !           340: {
        !           341: #ifdef MEM_LIST
        !           342:       MEMHDR *p;
        !           343:       int     idx;
        !           344:     
        !           345:       fprintf(fp,"      MEMORY ALLOCATED : %lu\n",debugMemSize);
        !           346:       fprintf(fp,"BLOCK  NUMBER   SIZE  TYPE\n");
        !           347:       idx = 0;
        !           348:       p = memlist;
        !           349:       while (p) {
        !           350:          fprintf(fp,"%-5u  %6lu %6u ",idx++,p->mh_number,p->mh_size);
        !           351:           switch (p->mh_type) {
        !           352:              case STRDUP_TYPE:fprintf(fp,"strdup()  in ");break;
        !           353:              case MALLOC_TYPE:fprintf(fp,"malloc()  in ");break;
        !           354:             case REALLOC_TYPE:fprintf(fp,"realloc() in ");break;
        !           355:                       default:fprintf(fp,"   ???    in ");break;
        !           356:           }
        !           357:          if (p->mh_file != NULL) fprintf(fp,"%s(%d)", p->mh_file, p->mh_line);
        !           358:           if (p->mh_tag != MEMTAG)
        !           359:              fprintf(fp,"  INVALID");
        !           360:           fprintf(fp,"\n");
        !           361:           p = p->mh_next;
        !           362:       }
        !           363: #else
        !           364:       fprintf(fp,"Memory list not compiled (MEM_LIST not defined !)\n");
        !           365: #endif
        !           366: }
        !           367: 
        !           368: #ifdef MEM_LIST
        !           369: 
        !           370: void debugmem_list_add(MEMHDR *p)
        !           371: {
        !           372:        p->mh_next = memlist;
        !           373:        p->mh_prev = NULL;
        !           374:        if (memlist) memlist->mh_prev = p;
        !           375:        memlist = p;
        !           376: #ifdef MEM_LIST_DEBUG
        !           377:        if (stderr)
        !           378:        Mem_Display(stderr);
        !           379: #endif
        !           380: }
        !           381: 
        !           382: void debugmem_list_delete(MEMHDR *p)
        !           383: {
        !           384:        if (p->mh_next)
        !           385:        p->mh_next->mh_prev = p->mh_prev;
        !           386:        if (p->mh_prev)
        !           387:        p->mh_prev->mh_next = p->mh_next;
        !           388:        else memlist = p->mh_next;
        !           389: #ifdef MEM_LIST_DEBUG
        !           390:        if (stderr)
        !           391:        Mem_Display(stderr);
        !           392: #endif
        !           393: }
        !           394: 
        !           395: #endif
        !           396: 
        !           397: /*
        !           398:  * debugmem_tag_error : internal error function.
        !           399:  */
        !           400:  
        !           401: void debugmem_tag_error(void *p)
        !           402: {
        !           403:        fprintf(stderr, "Memory tag error occurs :%p \n\t bye\n", p);
        !           404: #ifdef MEM_LIST
        !           405:        if (stderr)
        !           406:        xmlMemDisplay(stderr);
        !           407: #endif
        !           408: }
        !           409: 
        !           410: FILE *xmlMemoryDumpFile = NULL;
        !           411: 
        !           412: 
        !           413: /**
        !           414:  * xmlMemoryDump:
        !           415:  *
        !           416:  * Dump in-extenso the memory blocks allocated to the file .memorylist
        !           417:  */
        !           418: 
        !           419: void
        !           420: xmlMemoryDump(void)
        !           421: {
        !           422:     FILE *dump;
        !           423: 
        !           424:     dump = fopen(".memdump", "w");
        !           425:     if (dump == NULL) xmlMemoryDumpFile = stdout;
        !           426:     else xmlMemoryDumpFile = dump;
        !           427: 
        !           428:     xmlMemDisplay(xmlMemoryDumpFile);
        !           429: 
        !           430:     if (dump != NULL) fclose(dump);
        !           431: }
        !           432: 
        !           433: 
        !           434: /****************************************************************
        !           435:  *                                                             *
        !           436:  *             Initialization Routines                         *
        !           437:  *                                                             *
        !           438:  ****************************************************************/
        !           439: 
        !           440: /**
        !           441:  * xmlInitMemory:
        !           442:  *
        !           443:  * Initialize the memory layer.
        !           444:  */
        !           445: 
        !           446: 
        !           447: int
        !           448: xmlInitMemory(void)
        !           449: {
        !           450:      int ret;
        !           451:     
        !           452: #ifdef DEBUG_MEMORY
        !           453:      fprintf(stderr, "xmlInitMemory() Ok\n");
        !           454: #endif     
        !           455:      ret = 0;
        !           456:      return(ret);
        !           457: }
        !           458: 
        !           459: #endif /* ! NO_XML_MEMORY */

Webmaster