#define _GNU_SOURCE
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <pthread.h> #include <dlfcn.h>
typedef struct MemBlock { void *ptr; size_t size; const char *file; int line; struct MemBlock *next; } MemBlock;
static MemBlock *mem_list = NULL; static pthread_mutex_t mem_mutex = PTHREAD_MUTEX_INITIALIZER;
static void *(*real_malloc)(size_t) = NULL; static void (*real_free)(void *) = NULL;
void add_mem_block(void *ptr, size_t size, const char *file, int line) { if (!real_malloc) { real_malloc = malloc; } pthread_mutex_lock(&mem_mutex); MemBlock *new_block = (MemBlock *)real_malloc(sizeof(MemBlock)); new_block->ptr = ptr; new_block->size = size; new_block->file = file; new_block->line = line; new_block->next = mem_list; mem_list = new_block; pthread_mutex_unlock(&mem_mutex); }
void remove_mem_block(void *ptr) { pthread_mutex_lock(&mem_mutex); MemBlock *current = mem_list; MemBlock *previous = NULL; while (current) { if (current->ptr == ptr) { if (previous) { previous->next = current->next; } else { mem_list = current->next; } real_free(current); pthread_mutex_unlock(&mem_mutex); return; } previous = current; current = current->next; } pthread_mutex_unlock(&mem_mutex); }
void *malloc_hook(size_t size, const char *file, int line) { void *ptr = real_malloc(size); if (ptr) { add_mem_block(ptr, size, file, line); } return ptr; }
void free_hook(void *ptr, const char *file, int line) { if (ptr) { remove_mem_block(ptr); real_free(ptr); } }
void check_memory_leaks() { pthread_mutex_lock(&mem_mutex); MemBlock *current = mem_list; while (current) { fprintf(stderr, "Memory leak detected: %p (%zu bytes) allocated at %s:%d\n", current->ptr, current->size, current->file, current->line); current = current->next; } pthread_mutex_unlock(&mem_mutex); }
#define malloc(size) malloc_hook(size, __FILE__, __LINE__) #define free(ptr) free_hook(ptr, __FILE__, __LINE__)
int main() { real_malloc = (void *(*)(size_t))dlsym(RTLD_NEXT, "malloc"); real_free = (void (*)(void *))dlsym(RTLD_NEXT, "free");
char *leak = (char *)malloc(10); char *no_leak = (char *)malloc(20); free(no_leak);
check_memory_leaks();
return 0; }
|