Estoy escribiendo un pequeño perfilador de memoria que usa el truco LD_PRELOAD. En general funciona bien para malloc y gratis. Desafortunadamente, no puedo rastrear operaciones IO como printf. Esas funciones se rastrean correctamente en las funciones malloc, pero no parece que hayan pasado a ser gratuitas. Aquí hay fragmentos de código:
void heaptracker_init(void) { ignore = false; // get original symbols libc_hooks.malloc = dlsym(RTLD_NEXT, "malloc"); check_error_dlfcn(libc_hooks.malloc); // for the other primitives as well ... // init list for storing information if ((alloc_list = list_init()) == NULL) return; // does write results from list if (atexit(heaptracker_destroy)) return; initialized = true; stopped = true; // for concurrent access on list ... if ((errno = pthread_mutex_init(&mutex, NULL)) != 0) { return; } stopped = false; }La rutina malloc almacena las asignaciones en una lista y realiza la asignación real.
void *malloc(size_t size) { if (!initialized) heaptracker_init(); void * (*libc_malloc)(size_t) = libc_hooks.malloc; void *p = libc_malloc(size); list_append(alloc_list, infos, p, size, stacktrace_length); return p; }La rutina libre se ve así:
void free(void *ptr) { if (!initialized) heaptracker_init(); if (pthread_mutex_lock(&mutex) != 0) return; // does remove list_remove(alloc_list, ptr); errno = pthread_mutex_unlock(&mutex); libc_hooks.free(ptr); }Para un pequeño programa de prueba como este:
int main() { printf("Hello World"); char *buffer = malloc(100); return 0; }El resultado esperado debe ser:
{ "type": "leak", "bytes": 100, "stacktrace": ["main"] }Mientras que la salida real es:
[ { "type": "leak", "bytes": 100, "stacktrace": ["main"] }, { "type": "leak", "bytes": 1024, "stacktrace": ["main", "_IO_printf", ..., "_IO_file_doallocate"] } ]