static int tmalloc_log_fd = STDERR_FILENO;
static int tmalloc_log_level = TM_LOG_TRACE;
static int tmalloc_abort_on_error = 0;
+static int tmalloc_wipe_on_free = 0;
static uint64_t tm_sentinel = 0x5a5a5a5a5a5a5a5aULL;
#define TM_SENTSZ (sizeof tm_sentinel)
* Called when a serious error is encountered:
*/
+static inline void tm_ht_dump(void);
+
static inline void tm_panic(void) {
if (tmalloc_abort_on_error) {
+ if (tmalloc_log_level >= TM_LOG_INFO)
+ tm_ht_dump();
log_str("Aborting.\n");
abort();
}
return res;
}
+static inline int tm_ht_update(void *addr, size_t size,
+ void *raddr, size_t rsize, void *caller) {
+ struct tm_info_struct *p;
+ uint32_t h;
+
+ h = tm_hash((uint64_t)addr);
+ for (p = tm_htab[h]; p; p = p->next) {
+ if (p->addr == addr) {
+ p->size = size;
+ p->raddr = raddr;
+ p->rsize = rsize;
+ p->caller = caller;
+ return 0;
+ }
+ }
+ log_str(TM_LOG_PFX"ERROR: attempt to update block at ");
+ log_hex((uint64_t)addr);
+ log_str(", not listed as allocated!\n");
+ tm_panic();
+ return -1;
+}
+
static inline int tm_ht_remove(void *addr, int wipe) {
struct tm_info_struct *p, *prev = NULL;
uint32_t h;
void *realloc(void *ptr, size_t size) {
void *caller = ret_address(0);
void *addr;
+ void *oaddr = ptr ? ptr - TM_SENTSZ : NULL;
size_t xsize = size + (TM_SENTSZ * 2);
TM_HT_LOCK();
- tm_ht_check(ptr);
- addr = __libc_realloc(ptr - TM_SENTSZ, xsize);
+ addr = __libc_realloc(oaddr, xsize);
if (addr) {
- tm_ht_remove(ptr, 0);
- memcpy(addr, &tm_sentinel, TM_SENTSZ);
+ if (addr == oaddr) {
+ tm_ht_update(ptr, size, addr, xsize, caller);
+ }
+ else {
+ if (ptr)
+ tm_ht_remove(ptr, 0);
+ tm_ht_insert(addr + TM_SENTSZ, size, addr, xsize, caller);
+ memcpy(addr, &tm_sentinel, TM_SENTSZ);
+ }
memcpy(addr + xsize - TM_SENTSZ, &tm_sentinel, sizeof tm_sentinel);
- tm_ht_insert(addr + TM_SENTSZ, size, addr, xsize, caller);
addr += TM_SENTSZ;
}
else if (tmalloc_log_level >= TM_LOG_WARNING) {
if (ptr) {
TM_HT_LOCK();
tm_ht_check(ptr);
- if (tm_ht_remove(ptr, 1) != 0) {
+ if (tm_ht_remove(ptr, tmalloc_wipe_on_free) != 0) {
log_str(TM_LOG_PFX"ERROR: possible double free(");
log_hex((uint64_t)ptr);
log_str("): *** HEAP IS VERY LIKELY CORRUPT! ***\n");
tmalloc_abort_on_error = a;
}
+void tmalloc_set_wipe_on_free(int w) {
+ tmalloc_wipe_on_free = w;
+}
+
void tmalloc_check(void) {
TM_HT_LOCK();
tm_ht_checkall();