IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 38491


Ignore:
Timestamp:
Jun 19, 2015, 8:58:57 AM (11 years ago)
Author:
eugene
Message:

fixing compile time switch : OHANA_MEMORY; adding testing features to ohana_allocate: freed state, compile-time options to save the freed blocks and blocks before reallocation; catch double free attempt; poison freed memory blocks; include freed and dropped block in memtest if saved

Location:
branches/eam_branches/ipp-20150616/Ohana/src/libohana
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/ipp-20150616/Ohana/src/libohana/include/ohana_allocate.h

    r38441 r38491  
    2929void  real_free (void *in);
    3030
    31 # define ohana_memcheck(X) ohana_memcheck_func (X);
     31# define ohana_memcheck(X) ohana_memcheck_func (X)
    3232# define ohana_memdump(X) ohana_memdump_func (X);
    3333
     
    5656# else  /* below: not OHANA_MEMORY */
    5757
    58 # define ohana_memcheck(X) TRUE
     58int   ohana_memcheck_noop (int mode);
     59
     60# define ohana_memcheck(X) ohana_memcheck_noop (X)
    5961# define ohana_memdump(X) /* NOP */
    6062void  real_free (void *in);
  • branches/eam_branches/ipp-20150616/Ohana/src/libohana/src/ohana_allocate.c

    r38441 r38491  
    44# include <stdint.h>
    55# include <pthread.h>
     6# include <string.h>
     7
     8# define TEST_SAVE_FREE_BLOCKS 1
     9# define TEST_SAVE_DROP_BLOCKS 1
    610
    711# undef OHANA_MEMORY
     
    2327  const char *func;           // func (re)allocated
    2428  int line;                   // line (re)allocated
     29  int freed;                  // memory has been freed
     30  int dummy;                  // need to put endblock on the endpost
    2531  uint32_t endblock;          // endpost marker
    2632} Memblock;
    2733
    2834static Memblock *lastBlock = NULL;
     35
     36# if (TEST_SAVE_FREE_BLOCKS)
     37static Memblock *freeBlock = NULL;
     38# endif
     39
     40# if (TEST_SAVE_DROP_BLOCKS)
     41static Memblock *dropBlock = NULL;
     42# endif
    2943
    3044static pthread_mutex_t memBlockListMutex = PTHREAD_MUTEX_INITIALIZER;
     
    6983  new->line = line;
    7084  new->func = func;
     85  new->freed = FALSE;
     86
     87  // to be clean, zero out the memory
     88  // memset (ptr, 0, new->size);
    7189
    7290  // new memblock becomes the 'lastBlock':
     
    99117void *ohana_realloc (const char *file, int line, const char *func, void *in, size_t Nelem, size_t esize) {
    100118
    101   void *ptr;                  // actual user memory allocated
    102119  Memblock *old;              // original memblock associated with user memory
    103120  Memblock *new;              // new memblock associated with user memory
     
    106123  // just allocate if not previously allocated
    107124  if (!in) {
    108     ptr = ohana_malloc (file, line, func, Nelem, esize);
     125    void *ptr = ohana_malloc (file, line, func, Nelem, esize);
    109126    return ptr;
    110127  }
     
    131148  int isLast = (old == lastBlock);
    132149
     150  // ask for new memory
     151
     152# if (TEST_SAVE_DROP_BLOCKS)
     153  // XXX for a test, we are going to always alloc a new block, copy the old data to the new block
     154  // poison the old block, then free it
     155  new = (Memblock *) malloc (sizeof(Memblock) + size + sizeof(void *));
     156  if (new == NULL) ohana_memabort ("failed to reallocate memory (%s, %d, %s)\n", file, line, func);
     157  void *ptr_new = (char *) (new + 1);
     158  void *ptr_old = (char *) (old + 1);
     159  size_t copy_bytes = old->size < size ? old->size : size;
     160  memcpy (ptr_new, ptr_old, copy_bytes);
     161  memset (ptr_old, 0x7f, old->size);
     162  new->nextBlock = old->nextBlock;
     163  new->prevBlock = old->prevBlock;
     164# else
    133165  // ask for new memory
    134166  // total size is : memblock + data + endpost
    135167  new = (Memblock *) realloc (old, sizeof(Memblock) + size + sizeof(void *));
    136168  if (new == NULL) ohana_memabort ("failed to reallocate memory (%s, %d, %s)\n", file, line, func);
    137   ptr = (char *) (new + 1);
     169  void *ptr_new = (char *) (new + 1);
     170# endif
    138171 
    139   // give the realloc location:
     172  // set the end-post values
     173  new->startblock = OHANA_MEMMAGIC;
     174  new->endblock = OHANA_MEMMAGIC;
     175  *(uint32_t *)(ptr_new + size) = OHANA_MEMMAGIC;
     176
     177  // set the memory metadata
    140178  new->size = size;
    141179  new->file = file;
    142180  new->line = line;
    143181  new->func = func;
     182  new->freed = FALSE;
    144183
    145184  // update the endpost (the others were set originally
    146   *(uint32_t *)(ptr + size) = OHANA_MEMMAGIC;
     185  *(uint32_t *)(ptr_new + size) = OHANA_MEMMAGIC;
    147186
    148187  // need to reset lastBlock in case we moved
     
    159198  }
    160199 
     200  // XXX FOR TESTING, save the realloc blocks
     201# if (TEST_SAVE_DROP_BLOCKS)
     202  if (dropBlock) {
     203    dropBlock->nextBlock = old;
     204  }
     205  old->nextBlock = NULL;
     206  old->prevBlock = dropBlock;
     207  dropBlock = old;
     208# endif
     209
    161210  pthread_mutex_unlock(&memBlockListMutex);
    162211
    163   return (ptr);
     212  return (ptr_new);
    164213}
    165214
     
    181230
    182231  ref = (Memblock *) in - 1;
     232
     233  if (ref->freed) ohana_memabort ("memory already freed (%s, %d, %s [%d bytes])\n", ref->file, ref->line, ref->func, ref->size);
     234  ref->freed = TRUE;
    183235
    184236  // fprintf (stderr, "  file: %s, line: %d, func: %s, size: %zd, addr: %zx\n",
     
    190242  Memblock *prevBlock = ref->prevBlock;
    191243
     244  // remove this memBlock from the list
    192245  if (nextBlock) {
    193246    nextBlock->prevBlock = prevBlock;
     
    200253  }
    201254 
     255  // XXX FOR TESTING, save the freed blocks
     256# if (TEST_SAVE_FREE_BLOCKS)
     257  if (freeBlock) {
     258    freeBlock->nextBlock = ref;
     259  }
     260  ref->nextBlock = NULL;
     261  ref->prevBlock = freeBlock;
     262  freeBlock = ref;
     263# endif
     264
     265  // pointer to the start of the user memory
     266  void *ptr = (char *)(ref + 1);
     267  memset (ptr, 0x77, ref->size);
     268
    202269  pthread_mutex_unlock(&memBlockListMutex);
    203270 
     271# if (!TEST_SAVE_FREE_BLOCKS)
    204272  free (ref);
     273# endif
    205274
    206275  return;
     276}
     277
     278int ohana_memcheck_noop (int allmemory) {
     279  return TRUE;
    207280}
    208281
     
    220293  size_t Ntotal = 0;
    221294  size_t Nbytes = 0;
     295  int status = TRUE;
    222296
    223297  while (thisBlock) {
     
    250324    thisBlock = thisBlock->prevBlock;
    251325  }
     326  fprintf (stderr, "%zd memory blocks allocated (%zd bytes total), %zd good, %zd bad\n", Ntotal, Nbytes, Ngood, Nbad);
     327  if (Nbad) status = FALSE;
     328
     329# if (TEST_SAVE_FREE_BLOCKS)
    252330 
    253   fprintf (stderr, "%zd memory blocks allocated (%zd bytes total), %zd good, %zd bad\n", Ntotal, Nbytes, Ngood, Nbad);
    254 
    255   if (Nbad) return FALSE;
    256   return TRUE;
     331  thisBlock = freeBlock;
     332
     333  size_t Ngood_free  = 0;
     334  size_t Nbad_free   = 0;
     335  size_t Ntotal_free = 0;
     336  size_t Nbytes_free = 0;
     337
     338  while (thisBlock) {
     339
     340    int i;
     341    int good = TRUE;
     342   
     343    if (thisBlock->startblock != OHANA_MEMMAGIC) good = FALSE;
     344    if (thisBlock->endblock != OHANA_MEMMAGIC) good = FALSE;
     345
     346    // pointer to the end of the user memory
     347    char *ptr = (char *)(thisBlock + 1) + thisBlock->size;
     348    uint32_t endpost = *(uint32_t *)ptr;
     349    if (endpost != OHANA_MEMMAGIC) good = FALSE;
     350
     351    // pointer to the start of the user memory
     352    ptr = (char *)(thisBlock + 1);
     353    for (i = 0; i < thisBlock->size; i++, ptr++) {
     354      if (*ptr != 0x77) good = FALSE;
     355    }
     356
     357    // XXX keep checking even if memory is corrupted?
     358    if (!good) {
     359      if (Nbad_free < 1) {
     360        fprintf (stderr, "memory corruption\n");
     361      }
     362      if (Nbad_free < 100) {
     363        fprintf (stderr, "  file: %s, line: %d, func: %s\n", thisBlock->file, thisBlock->line, thisBlock->func);
     364      }
     365      Nbad_free ++;
     366    } else {
     367      Ngood_free ++;
     368    }
     369    Ntotal_free ++;
     370    Nbytes_free += thisBlock->size;
     371
     372    thisBlock = thisBlock->prevBlock;
     373  }
     374  fprintf (stderr, "%zd memory blocks freed     (%zd bytes total), %zd good, %zd bad\n", Ntotal_free, Nbytes_free, Ngood_free, Nbad_free);
     375  if (Nbad_free) status = FALSE;
     376
     377# endif
     378 
     379# if (TEST_SAVE_DROP_BLOCKS)
     380  thisBlock = dropBlock;
     381
     382  size_t Ngood_drop  = 0;
     383  size_t Nbad_drop   = 0;
     384  size_t Ntotal_drop = 0;
     385  size_t Nbytes_drop = 0;
     386
     387  while (thisBlock) {
     388
     389    int i;
     390    int good = TRUE;
     391   
     392    if (thisBlock->startblock != OHANA_MEMMAGIC) good = FALSE;
     393    if (thisBlock->endblock != OHANA_MEMMAGIC) good = FALSE;
     394
     395    // pointer to the end of the user memory
     396    char *ptr = (char *)(thisBlock + 1) + thisBlock->size;
     397    uint32_t endpost = *(uint32_t *)ptr;
     398    if (endpost != OHANA_MEMMAGIC) good = FALSE;
     399
     400    // pointer to the start of the user memory
     401    ptr = (char *)(thisBlock + 1);
     402    for (i = 0; i < thisBlock->size; i++, ptr++) {
     403      if (*ptr != 0x7f) good = FALSE;
     404    }
     405
     406    // XXX keep checking even if memory is corrupted?
     407    if (!good) {
     408      if (Nbad_drop < 1) {
     409        fprintf (stderr, "memory corruption\n");
     410      }
     411      if (Nbad_drop < 100) {
     412        fprintf (stderr, "  file: %s, line: %d, func: %s\n", thisBlock->file, thisBlock->line, thisBlock->func);
     413      }
     414      Nbad_drop ++;
     415    } else {
     416      Ngood_drop ++;
     417    }
     418    Ntotal_drop ++;
     419    Nbytes_drop += thisBlock->size;
     420
     421    thisBlock = thisBlock->prevBlock;
     422  }
     423  fprintf (stderr, "%zd memory blocks dropped   (%zd bytes total), %zd good, %zd bad\n", Ntotal_drop, Nbytes_drop, Ngood_drop, Nbad_drop);
     424  if (Nbad_drop) status = FALSE;
     425# endif
     426 
     427  return status;
    257428}
    258429
Note: See TracChangeset for help on using the changeset viewer.