From bcff59bacbddd46e37ee9a6144137159e56ebc10 Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Fri, 28 Oct 2022 14:07:44 -0400 Subject: [PATCH] Store memory info in the allocated block, not as a separate block. This will eventually enable us to get memory information in O(1) time. Right now, we're still O(n) because MemoryInfoGet() still has to check to see if the allocation is known or not. --- src/Memory.c | 152 +++++++++++++++++++++++-------------------- src/Telodendria.c | 11 +++- src/include/Memory.h | 3 +- 3 files changed, 92 insertions(+), 74 deletions(-) diff --git a/src/Memory.c b/src/Memory.c index aec5d51..ce2ed4d 100644 --- a/src/Memory.c +++ b/src/Memory.c @@ -32,7 +32,6 @@ struct MemoryInfo size_t size; const char *file; int line; - void *pointer; MemoryInfo *next; MemoryInfo *prev; @@ -46,30 +45,20 @@ static void *hookArgs = NULL; void * MemoryAllocate(size_t size, const char *file, int line) { - void *p; MemoryInfo *a; pthread_mutex_lock(&lock); - p = malloc(size); - if (!p) - { - pthread_mutex_unlock(&lock); - return NULL; - } - - a = malloc(sizeof(MemoryInfo)); + a = malloc(sizeof(MemoryInfo) + size); if (!a) { - free(p); pthread_mutex_unlock(&lock); return NULL; } - a->size = size; + a->size = sizeof(MemoryInfo) + size; a->file = file; a->line = line; - a->pointer = p; a->next = NULL; a->prev = lastAllocation; @@ -86,7 +75,7 @@ MemoryAllocate(size_t size, const char *file, int line) } pthread_mutex_unlock(&lock); - return p; + return MemoryInfoGetPointer(a); } void * @@ -95,34 +84,55 @@ MemoryReallocate(void *p, size_t size) MemoryInfo *a; void *new = NULL; + a = MemoryInfoGet(p); + + if (!a) + { + if (hook) + { + hook(MEMORY_BAD_POINTER, NULL, hookArgs); + } + pthread_mutex_unlock(&lock); + return NULL; + } + pthread_mutex_lock(&lock); - a = lastAllocation; - while (a) + new = realloc(a, sizeof(MemoryInfo) + size); + if (!new) { - if (a->pointer == p) - { - new = realloc(p, size); - if (new) - { - a->pointer = new; - a->size = size; + pthread_mutex_unlock(&lock); + return NULL; + } + a = new; + a->size = sizeof(MemoryInfo) + size; - if (hook) - { - hook(MEMORY_REALLOCATE, a, hookArgs); - } - } + if (a->prev) + { + a->prev->next = a; + } + else + { + lastAllocation = a; + } - break; - } + if (a->next) + { + a->next->prev = a; + } + else + { + lastAllocation = a; + } - a = a->prev; + if (hook) + { + hook(MEMORY_REALLOCATE, a, hookArgs); } pthread_mutex_unlock(&lock); - return new; + return MemoryInfoGetPointer(a); } void @@ -132,44 +142,42 @@ MemoryFree(void *p) pthread_mutex_lock(&lock); - a = lastAllocation; - - while (a) + a = MemoryInfoGet(p); + if (!a) { - if (a->pointer == p) + if (hook) { - if (a->prev) - { - a->prev->next = a->next; - } - else - { - lastAllocation = a->next; - } - - if (a->next) - { - a->next->prev = a->prev; - } - else - { - lastAllocation = a->prev; - } - - if (hook) - { - hook(MEMORY_FREE, a, hookArgs); - } - - free(a); - free(p); - - break; + hook(MEMORY_BAD_POINTER, NULL, hookArgs); } - - a = a->prev; + pthread_mutex_unlock(&lock); + return; } + if (a->prev) + { + a->prev->next = a->next; + } + else + { + lastAllocation = a->next; + } + + if (a->next) + { + a->next->prev = a->prev; + } + else + { + lastAllocation = a->prev; + } + + if (hook) + { + hook(MEMORY_FREE, a, hookArgs); + } + + free(a); + pthread_mutex_unlock(&lock); } @@ -205,9 +213,7 @@ MemoryFreeAll(void) { MemoryInfo *prev = a->prev; - free(a->pointer); free(a); - a = prev; } @@ -221,12 +227,18 @@ MemoryInfoGet(void *p) { MemoryInfo *a; - pthread_mutex_lock(&lock); + if (!p) + { + return NULL; + } + + p = &(((MemoryInfo *) p)[-1]); a = lastAllocation; + while (a) { - if (a->pointer == p) + if (a == p) { break; } @@ -278,7 +290,7 @@ MemoryInfoGetPointer(MemoryInfo * a) return NULL; } - return a->pointer; + return &(a[1]); } void diff --git a/src/Telodendria.c b/src/Telodendria.c index f11407e..a3b9640 100644 --- a/src/Telodendria.c +++ b/src/Telodendria.c @@ -57,6 +57,9 @@ TelodendriaMemoryHook(MemoryAction a, MemoryInfo * i, void *args) case MEMORY_FREE: action = "Freed"; break; + case MEMORY_BAD_POINTER: + Log(lc, LOG_WARNING, "Bad pointer passed into a memory function."); + return; default: action = "Unknown operation on"; break; @@ -76,9 +79,9 @@ TelodendriaMemoryIterator(MemoryInfo * i, void *args) /* We haven't freed the logger memory yet */ if (MemoryInfoGetPointer(i) != lc) { - Log(lc, LOG_DEBUG, "%lu bytes of memory at %p leaked from %s:%d", - MemoryInfoGetSize(i), MemoryInfoGetPointer(i), - MemoryInfoGetFile(i), MemoryInfoGetLine(i)); + Log(lc, LOG_WARNING, "%s:%d: %lu bytes of memory at %p leaked.", + MemoryInfoGetFile(i), MemoryInfoGetLine(i), + MemoryInfoGetSize(i), MemoryInfoGetPointer(i)); } } @@ -148,6 +151,8 @@ main(int argc, char **argv) MatrixHttpHandlerArgs matrixArgs; + memset(&matrixArgs, 0, sizeof(matrixArgs)); + lc = LogConfigCreate(); if (!lc) diff --git a/src/include/Memory.h b/src/include/Memory.h index 933d3f5..95ef7bd 100644 --- a/src/include/Memory.h +++ b/src/include/Memory.h @@ -30,7 +30,8 @@ typedef enum MemoryAction { MEMORY_ALLOCATE, MEMORY_REALLOCATE, - MEMORY_FREE + MEMORY_FREE, + MEMORY_BAD_POINTER } MemoryAction; #define Malloc(x) MemoryAllocate(x, __FILE__, __LINE__)