"Fossies" - the Fresh Open Source Software Archive

Member "rpm2html-1.11.2/memory.c" (5 Oct 2010, 10300 Bytes) of package /linux/privat/rpm2html-1.11.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "memory.c" see the Fossies "Dox" file reference documentation.

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