diff options
Diffstat (limited to 'libglusterfs')
| -rw-r--r-- | libglusterfs/src/mem-pool.c | 136 | ||||
| -rw-r--r-- | libglusterfs/src/mem-pool.h | 21 | 
2 files changed, 103 insertions, 54 deletions
diff --git a/libglusterfs/src/mem-pool.c b/libglusterfs/src/mem-pool.c index 3bba30fc72e..0f9d792c0f1 100644 --- a/libglusterfs/src/mem-pool.c +++ b/libglusterfs/src/mem-pool.c @@ -49,12 +49,13 @@ gf_mem_set_acct_info (xlator_t *xl, char **alloc_ptr, size_t size,  		      uint32_t type, const char *typestr)  { -        char    *ptr = NULL; +        void              *ptr    = NULL; +        struct mem_header *header = NULL;          if (!alloc_ptr)                  return -1; -        ptr = (char *) (*alloc_ptr); +        ptr = *alloc_ptr;          GF_ASSERT (xl != NULL); @@ -78,18 +79,18 @@ gf_mem_set_acct_info (xlator_t *xl, char **alloc_ptr, size_t size,          }          UNLOCK(&xl->mem_acct.rec[type].lock); -        *(uint32_t *)(ptr) = type; -        ptr = ptr + 4; -        memcpy (ptr, &size, sizeof(size_t)); -        ptr += sizeof (size_t); -        memcpy (ptr, &xl, sizeof(xlator_t *)); -        ptr += sizeof (xlator_t *); -        *(uint32_t *)(ptr) = GF_MEM_HEADER_MAGIC; -        ptr = ptr + 4; -        ptr = ptr + 8; //padding +        header = (struct mem_header *) ptr; +        header->type = type; +        header->size = size; +        header->xlator = xl; +        header->magic = GF_MEM_HEADER_MAGIC; + +        ptr += sizeof (struct mem_header); + +        /* data follows in this gap of 'size' bytes */          *(uint32_t *) (ptr + size) = GF_MEM_TRAILER_MAGIC; -        *alloc_ptr = (void *)ptr; +        *alloc_ptr = ptr;          return 0;  } @@ -148,11 +149,11 @@ __gf_malloc (size_t size, uint32_t type, const char *typestr)  void *  __gf_realloc (void *ptr, size_t size)  { -        size_t          tot_size = 0; -        char            *orig_ptr = NULL; -        xlator_t        *xl = NULL; -        uint32_t        type = 0; -        char            *new_ptr; +        uint32_t           type = 0; +        size_t             tot_size = 0; +        xlator_t          *xl = NULL; +        char              *new_ptr; +        struct mem_header *header = NULL;          if (!THIS->ctx->mem_acct_enable)                  return REALLOC (ptr, size); @@ -161,17 +162,14 @@ __gf_realloc (void *ptr, size_t size)          tot_size = size + GF_MEM_HEADER_SIZE + GF_MEM_TRAILER_SIZE; -        orig_ptr = (char *)ptr - 8 - 4; - -        GF_ASSERT (*(uint32_t *)orig_ptr == GF_MEM_HEADER_MAGIC); +        header = (struct mem_header *) (ptr - GF_MEM_HEADER_SIZE); -        orig_ptr = orig_ptr - sizeof(xlator_t *); -        xl = *((xlator_t **)orig_ptr); +        GF_ASSERT (header->magic == GF_MEM_HEADER_MAGIC); -        orig_ptr = (char *)ptr - GF_MEM_HEADER_SIZE; -        type = *(uint32_t *)orig_ptr; +        xl = (xlator_t *) header->xlator; +        type = header->type; -        new_ptr = realloc (orig_ptr, tot_size); +        new_ptr = realloc (header, tot_size);          if (!new_ptr) {                  gf_msg_nomem ("", GF_LOG_ALERT, tot_size);                  return NULL; @@ -228,13 +226,53 @@ gf_asprintf (char **string_ptr, const char *format, ...)          return rv;  } +#ifdef DEBUG +void +__gf_mem_invalidate (void *ptr) +{ +        struct mem_header *header = ptr; +        void              *end    = NULL; + +        struct mem_invalid inval = { +                .magic = GF_MEM_INVALID_MAGIC, +                .xlator = header->xlator, +                .type = header->type, +                .size = header->size, +                .baseaddr = ptr + GF_MEM_HEADER_SIZE, +        }; + +        /* calculate the last byte of the allocated area */ +        end = ptr + GF_MEM_HEADER_SIZE + inval.size + GF_MEM_TRAILER_SIZE; + +        /* overwrite the old mem_header */ +        memcpy (ptr, &inval, sizeof (inval)); +        ptr += sizeof (inval); + +        /* zero out remaining (old) mem_header bytes) */ +        memset (ptr, 0x00, sizeof (*header) - sizeof (inval)); +        ptr += sizeof (*header) - sizeof (inval); + +        /* zero out the first byte of data */ +        *(uint32_t *)(ptr) = 0x00; +        ptr += 1; + +        /* repeated writes of invalid structurein data area */ +        while ((ptr + (sizeof (inval))) < (end - 1)) { +                memcpy (ptr, &inval, sizeof (inval)); +                ptr += sizeof (inval); +        } + +        /* fill out remaining data area with 0xff */ +        memset (ptr, 0xff, end - ptr); +} +#endif /* DEBUG */ +  void  __gf_free (void *free_ptr)  { -        size_t          req_size = 0; -        char            *ptr = NULL; -        uint32_t        type = 0; -        xlator_t        *xl = NULL; +        void              *ptr = NULL; +        xlator_t          *xl = NULL; +        struct mem_header *header = NULL;          if (!THIS->ctx->mem_acct_enable) {                  FREE (free_ptr); @@ -244,47 +282,39 @@ __gf_free (void *free_ptr)          if (!free_ptr)                  return; -        ptr = (char *)free_ptr - 8 - 4; +        ptr = free_ptr - GF_MEM_HEADER_SIZE; +        header = (struct mem_header *) ptr;          //Possible corruption, assert here -        GF_ASSERT (GF_MEM_HEADER_MAGIC == *(uint32_t *)ptr); - -        *(uint32_t *)ptr = 0; - -        ptr = ptr - sizeof(xlator_t *); -        memcpy (&xl, ptr, sizeof(xlator_t *)); +        GF_ASSERT (GF_MEM_HEADER_MAGIC == header->magic);          //gf_free expects xl to be available -        GF_ASSERT (xl != NULL); +        GF_ASSERT (header->xlator != NULL); +        xl = header->xlator;          if (!xl->mem_acct.rec) { -                ptr = (char *)free_ptr - GF_MEM_HEADER_SIZE;                  goto free;          } - -        ptr = ptr - sizeof(size_t); -        memcpy (&req_size, ptr, sizeof (size_t)); -        ptr = ptr - 4; -        type = *(uint32_t *)ptr; -          // This points to a memory overrun          GF_ASSERT (GF_MEM_TRAILER_MAGIC == -                *(uint32_t *)((char *)free_ptr + req_size)); - -        *(uint32_t *) ((char *)free_ptr + req_size) = 0; +                *(uint32_t *)((char *)free_ptr + header->size)); -        LOCK (&xl->mem_acct.rec[type].lock); +        LOCK (&xl->mem_acct.rec[header->type].lock);          { -                xl->mem_acct.rec[type].size -= req_size; -                xl->mem_acct.rec[type].num_allocs--; +                xl->mem_acct.rec[header->type].size -= header->size; +                xl->mem_acct.rec[header->type].num_allocs--;                  /* If all the instaces are freed up then ensure typestr is                   * set to NULL */ -                if (!xl->mem_acct.rec[type].num_allocs) -                        xl->mem_acct.rec[type].typestr = NULL; +                if (!xl->mem_acct.rec[header->type].num_allocs) +                        xl->mem_acct.rec[header->type].typestr = NULL;          } -        UNLOCK (&xl->mem_acct.rec[type].lock); +        UNLOCK (&xl->mem_acct.rec[header->type].lock);  free: +#ifdef DEBUG +        __gf_mem_invalidate (ptr); +#endif +          FREE (ptr);  } diff --git a/libglusterfs/src/mem-pool.h b/libglusterfs/src/mem-pool.h index 2bbb45ae8a7..81fb579a0ab 100644 --- a/libglusterfs/src/mem-pool.h +++ b/libglusterfs/src/mem-pool.h @@ -31,10 +31,10 @@  #include <cmocka.h>  #endif -#define GF_MEM_HEADER_SIZE  (4 + sizeof (size_t) + sizeof (xlator_t *) + 4 + 8)  #define GF_MEM_TRAILER_SIZE 8  #define GF_MEM_HEADER_MAGIC  0xCAFEBABE  #define GF_MEM_TRAILER_MAGIC 0xBAADF00D +#define GF_MEM_INVALID_MAGIC 0xDEADC0DE  struct mem_acct {          uint32_t            num_types; @@ -51,6 +51,25 @@ struct mem_acct_rec {          gf_lock_t       lock;  }; +struct mem_header { +        uint32_t  type; +        size_t    size; +        void     *xlator; +        uint32_t  magic; +        int       padding[8]; +}; + +#define GF_MEM_HEADER_SIZE  (sizeof (struct mem_header)) + +#ifdef DEBUG +struct mem_invalid { +        uint32_t  magic; +        void     *xlator; +        uint32_t  type; +        size_t    size; +        void     *baseaddr; +}; +#endif  void *  __gf_calloc (size_t cnt, size_t size, uint32_t type, const char *typestr);  | 
