char *mhandle_strdup(const char *s, char *at) { char *ptr; void *eff_ptr; unsigned long size = strlen(s) + 1; unsigned long eff_size; mhandle_init(); /* Allocate */ size = strlen(s) + 1; eff_size = size + MHANDLE_CORRUPT_TOTAL; eff_ptr = malloc(eff_size); if (!eff_ptr) mhandle_out_of_memory(at); /* Copy string and mark corruption */ ptr = eff_ptr + MHANDLE_CORRUPT_RANGE; memcpy(ptr, s, size); mhandle_mark_corrupt(eff_ptr, eff_size); /* Record pointer and return */ mhandle_hash_table_insert(ptr, size, at, 1); return ptr; }
static void mhandle_hash_table_grow(void) { int old_size, i; struct mhandle_item_t *old_ht; /* create new hash table */ old_size = mhandle_hash_table_size; old_ht = mhandle_hash_table; mhandle_hash_table_size = mhandle_hash_table_size * 2; mhandle_hash_table = (struct mhandle_item_t *) calloc(mhandle_hash_table_size, sizeof(struct mhandle_item_t)); if (!mhandle_hash_table) mhandle_out_of_memory("lib mhandle (resizing hash table)"); /* put elements into new hash table */ for (i = 0; i < old_size; i++) { if (old_ht[i].active && !old_ht[i].removed) { mhandle_hash_table_count--; mhandle_mem_used -= old_ht[i].size; mhandle_hash_table_insert(old_ht[i].ptr, old_ht[i].size, old_ht[i].at, old_ht[i].corrupt_info); } } free(old_ht); }
void *mhandle_calloc(unsigned long nmemb, unsigned long size, char *at) { void *ptr; void *eff_ptr; unsigned long total; unsigned long eff_total; mhandle_init(); /* Effective size */ total = nmemb * size; eff_total = total + MHANDLE_CORRUPT_TOTAL; /* Allocate */ eff_ptr = calloc(1, eff_total); if (!eff_ptr) mhandle_out_of_memory(at); /* Mark corruption */ ptr = eff_ptr + MHANDLE_CORRUPT_RANGE; mhandle_mark_corrupt(eff_ptr, eff_total); /* Record pointer and return */ mhandle_hash_table_insert(ptr, total, at, 1); return ptr; }
void *mhandle_realloc(void *ptr, unsigned long size, char *at) { void *eff_ptr; unsigned long eff_size; struct mhandle_item_t *item; /* Equivalent to malloc for NULL pointer */ if (!ptr) return mhandle_malloc(size, at); /* Equivalent to free for size zero */ if (!size) { mhandle_free(ptr, at); return NULL; } /* Reallocate */ mhandle_init(); /* Search pointer */ item = mhandle_hash_table_get(ptr); if (!item) { fprintf(stderr, "\n%s: realloc: invalid pointer %p\n", at, ptr); abort(); } /* Reallocation not supported for pointers registered externally, i.e., * those that don't have corruption information. */ if (!item->corrupt_info) { fprintf(stderr, "\n%s: realloc: not supported for pointers not allocated\n" "\twith malloc/calloc/realloc/strdup (%p)", at, ptr); abort(); } /* Effective sizes */ eff_ptr = ptr - MHANDLE_CORRUPT_RANGE; eff_size = item->size + MHANDLE_CORRUPT_TOTAL; /* Check corruption and remove old pointer */ mhandle_check_corrupt(eff_ptr, eff_size, at); mhandle_hash_table_remove(ptr, at); /* Reallocate */ eff_size = size + MHANDLE_CORRUPT_TOTAL; eff_ptr = realloc(eff_ptr, eff_size); if (!eff_ptr) mhandle_out_of_memory(at); /* Mark corruption */ ptr = eff_ptr + MHANDLE_CORRUPT_RANGE; mhandle_mark_corrupt(eff_ptr, eff_size); /* Record pointer and return */ mhandle_hash_table_insert(ptr, size, at, 1); return ptr; }
void *__xstrdup(const char *s, char *at) { void *ptr; ptr = strdup(s); if (!ptr) mhandle_out_of_memory(at); return ptr; }
void *__xrealloc(void *ptr, size_t size, char *at) { void *new_ptr; new_ptr = realloc(ptr, size); if (!new_ptr) mhandle_out_of_memory(at); return new_ptr; }
void *__xcalloc(size_t nmemb, size_t size, char *at) { void *ptr; ptr = calloc(nmemb, size); if (!ptr) mhandle_out_of_memory(at); return ptr; }
static void mhandle_init(void) { /* Already initialized */ if (mhandle_initialized) return; mhandle_initialized = 1; /* Initialize hash table */ mhandle_hash_table = calloc(MHANDLE_HASH_TABLE_SIZE, sizeof(struct mhandle_item_t)); mhandle_hash_table_size = MHANDLE_HASH_TABLE_SIZE; mhandle_hash_table_count = 0; if (!mhandle_hash_table) mhandle_out_of_memory("mhandle_init"); }
void *mhandle_malloc(unsigned long size, char *at) { void *ptr; void *eff_ptr; unsigned long eff_size; mhandle_init(); /* Allocate */ eff_size = size + MHANDLE_CORRUPT_TOTAL; eff_ptr = malloc(eff_size); if (!eff_ptr) mhandle_out_of_memory(at); /* Mark corruption */ ptr = eff_ptr + MHANDLE_CORRUPT_RANGE; mhandle_mark_corrupt(eff_ptr, eff_size); /* Record pointer and return */ mhandle_hash_table_insert(ptr, size, at, 1); return ptr; }