#include "services.h" #include #include long int quick_allocated = 0; static const char rcsid[] = "$Id: wrapper.c,v 1.1.1.1 1999/04/22 23:10:25 rain Exp $"; void *my_malloc_child(size_t size, int line, const char *file) { void *ptr; struct memory_ll *new; int which; #ifdef MALLOC_MAGIC_CHECK if (!(ptr = malloc(size + sizeof(long) + 1 + sizeof(long)))) { #else if (!(ptr = malloc(size))) { #endif #ifdef HAVE_STRERROR log("### MALLOC FAILED AT %s:%d (%d bytes) (%s)!", file, line, size, strerror(errno)); #else log("### MALLOC FAILED AT %s:%d (%d bytes) (%d)!", file, line, size, errno); #endif return NULL; } #ifdef MALLOC_MAGIC_CHECK ptr = add_magic(ptr, size); #endif new = malloc(sizeof(struct memory_ll)); new->size = size; #ifdef EBUG new->line = line; #ifdef HAVE_STRDUP new->file = strdup(file); #else new->file = malloc(strlen(file) + 1); strcpy(new->file, file); #endif #endif new->ptr = ptr; new->next = NULL; new->prev = NULL; quick_allocated += size; if (quick_allocated > stats.max_allocated) stats.max_allocated = quick_allocated; which = (int)ptr % MEM_HASH_SIZE; if (!memory[which]) memory[which] = new; else { new->next = memory[which]; memory[which]->prev = new; memory[which] = new; } #ifdef EBUG_WRAPPER log(" %p = malloc(%d): %s: line %d", ptr, size, file, line); #endif return ptr; } void my_free_child(void *ptr, int line, const char *file) { struct memory_ll *m; int which; #ifdef MALLOC_MAGIC_CHECK void *magicptr; #endif if (!ptr) { log("### WARNING ### Attempt to free a NULL pointer in %s: line %d", file, line); return; } if (!(m = find_memory_by_pointer(ptr))) { log("### WARNING ### Attempt to free unallocated pointer %p in %s: line %d", ptr, file, line); return; } #ifdef EBUG_WRAPPER log(" free(%p) [%d bytes]: %s: line %d", ptr, m->size, file, line); #endif quick_allocated -= m->size; which = (int)ptr % MEM_HASH_SIZE; #ifdef MALLOC_MAGIC_CHECK ptr -= sizeof(long); magicptr = ptr; if (*(long *)magicptr != MALLOC_MAGIC) { #ifdef EBUG log("### START MAGIC FAIL! (buffer underflow) free in %s: line %d, allocated in %s: line %d", file, line, m->file, m->line); #else log("### START MAGIC FAIL! (buffer underflow) free in %s: line %d", file, line); #endif return; } magicptr = ptr + sizeof(long) + m->size + 1; if (*(long *)magicptr != MALLOC_MAGIC) { #ifdef EBUG log("### END MAGIC FAIL! (buffer overflow) free in %s: line %d, allocated in %s: line %d", file, line, m->file, m->line); #else log("### END MAGIC FAIL! (buffer overflow) free in %s: line %d", file, line); #endif return; } #endif if (m->prev) { if ((m->prev->next = m->next)) m->next->prev = m->prev; } else { if ((memory[which] = m->next)) memory[which]->prev = NULL; } #ifdef EBUG free(m->file); #endif free(m); free(ptr); } void *my_realloc_child(void *ptr, size_t size, int line, const char *file) { struct memory_ll *m; void *newptr; int which; if (!(m = find_memory_by_pointer(ptr)) && ptr) { log("### WARNING ### Attempt to reallocate unallocated pointer %p in %s: line %d", ptr, file, line); return NULL; } if (!size) { my_free(ptr); return NULL; } #ifdef MALLOC_MAGIC_CHECK if (!(newptr = realloc(ptr - sizeof(long), size + sizeof(long) + 1 + sizeof(long)))) { #else if (!(newptr = realloc(ptr - sizeof(long), size))) { #endif #ifdef HAVE_STRERROR log("### REALLOC FAILED AT %s:%d %s", file, line, strerror(errno)); #else log("### REALLOC FAILED AT %s:%d (%d)", file, line, errno); #endif my_free_child(ptr, line, file); return NULL; } #ifdef MALLOC_MAGIC_CHECK newptr = add_magic(newptr, size); #endif #ifdef EBUG_WRAPPER log(" %p = realloc(%p, %d): %s: line %d", newptr, ptr, size, file, line); #endif which = (int)ptr % MEM_HASH_SIZE; if (m->prev) { if ((m->prev->next = m->next)) m->next->prev = m->prev; } else { if ((memory[which] = m->next)) memory[which]->prev = NULL; } which = (int)newptr % MEM_HASH_SIZE; if (!memory[which]) { memory[which] = m; memory[which]->next = NULL; memory[which]->prev = NULL; } else { m->next = memory[which]; m->prev = NULL; memory[which]->prev = m; memory[which] = m; } m->ptr = newptr; m->size = size; return newptr; } struct memory_ll *find_memory_by_pointer(void *ptr) { struct memory_ll *m; m = memory[(int)ptr % MEM_HASH_SIZE]; while (m) { if (m->ptr == ptr) return m; m = m->next; } return (struct memory_ll *)NULL; } size_t get_memory_usage(char *file) { struct memory_ll *m; size_t size = 0; int x; for (x = 0; x < MEM_HASH_SIZE; x++) { m = memory[x]; while (m) { #ifdef EBUG if (file) { if (match(file, m->file)) size += m->size; } else #endif size += m->size; m = m->next; } } return size; } long int get_memory_allocated(char *file) { struct memory_ll *m; long int count = 0; int x; for (x = 0; x < MEM_HASH_SIZE; x++) { m = memory[x]; while (m) { #ifdef EBUG if (file) { if (match(file, m->file)) count++; } else #endif count++; m = m->next; } } return count; } void log_memory_in_use(void) { struct memory_ll *m; int x; for (x = 0; x < MEM_HASH_SIZE; x++) { m = memory[x]; while (m) { #ifdef EBUG log("%5d bytes at %p (%s, line %d)", m->size, m->ptr, m->file, m->line); #else log("%5d bytes at %p", m->size, m->ptr); #endif m = m->next; } } } char *my_strdup_child(const char *string, int line, const char *file) { void *ptr; struct memory_ll *new; int which; #ifdef MALLOC_MAGIC_CHECK if (!(ptr = malloc(strlen(string) + 1 + sizeof(long) + 1 + sizeof(long)))) { #else #ifdef HAVE_STRDUP if (!(ptr = strdup(string))) { #else if (!(ptr = malloc(strlen(string) + 1))) #endif #endif #ifdef HAVE_STRERROR log("### STRDUP FAILED AT %s:%d (%d bytes) (%s)!", file, line, strlen(string) + 1, strerror(errno)); #else log("### STRDUP FAILED AT %s:%d (%d bytes) (%d)!", file, line, strlen(string) + 1, errno); #endif return NULL; } #ifndef HAVE_STRDUP strcpy(ptr, string); #endif #ifdef MALLOC_MAGIC_CHECK ptr = add_magic(ptr, strlen(string) + 1); strcpy(ptr, string); #endif new = malloc(sizeof(struct memory_ll)); new->size = strlen(string) + 1; #ifdef EBUG new->line = line; #ifdef HAVE_STRDUP new->file = strdup(file); #else new->file = malloc(strlen(file + 1)); strcpy(new->file, file); #endif #endif new->ptr = ptr; new->next = NULL; new->prev = NULL; quick_allocated += new->size; if (quick_allocated > stats.max_allocated) stats.max_allocated = quick_allocated; which = (int)ptr % MEM_HASH_SIZE; if (!memory[which]) memory[which] = new; else { new->next = memory[which]; memory[which]->prev = new; memory[which] = new; } #ifdef EBUG_WRAPPER log(" %p = strdup(%s): %s: line %d", ptr, string, file, line); #endif return ptr; } #ifdef MALLOC_MAGIC_CHECK void *add_magic(void *ptr, int size) { void *magicptr; if (!ptr) { log("(!) add_magic: ptr is NULL!"); return NULL; } *(long *)ptr = MALLOC_MAGIC; ptr += 4; magicptr = (ptr + size); *(char *)magicptr = 0; magicptr++; *(long *)magicptr = MALLOC_MAGIC; return ptr; } #endif