allocator interposition (LD_PRELOAD)
/ el-dee-PEE-relode /
Suppose a building has a switchboard, and every internal phone call to the word malloc gets routed to whoever currently answers that line. Normally the standard C library answers. But what if, without rewiring the building, you could slip in and answer that line yourself — so every call meant for the built-in malloc reaches your code instead? On Linux that is allocator interposition: you load your own malloc/free first, and because of how dynamic linking resolves names, the whole program (and the libraries it uses) call yours instead of the system's, with no recompilation.
The usual mechanism is the LD_PRELOAD environment variable. When you set LD_PRELOAD to point at a shared library and then run a program, the dynamic linker loads that library before all the others. Because symbol resolution takes the first definition it finds, your library's malloc() and free() are found before glibc's, so every call to malloc() anywhere in the process binds to your version — this is symbol interposition. Your replacement is free to do anything: it might be a whole alternative allocator (this is exactly how you swap in tcmalloc or jemalloc by preload), or a thin wrapper that records every allocation and free for leak detection, fills freed memory with a poison pattern to catch use-after-free, or counts and times calls for profiling. The standard line $ LD_PRELOAD=./mymalloc.so ./app is all it takes.
Why it is so useful: it lets you change or instrument a program's memory behaviour from the outside, without touching or even having its source — perfect for debugging, profiling, and dropping in a faster allocator on a binary you cannot rebuild. The honest caveats: a correct interposing malloc is surprisingly tricky (it must satisfy alignment and the malloc(0) rule, and must not call malloc() during its own startup, a chicken-and-egg trap); LD_PRELOAD is a Linux/glibc mechanism (other systems have their own, and statically linked binaries cannot be preloaded at all); and it is ignored for set-user-id programs for security. Interposition is a sharp tool, not a no-op.
/* mymalloc.c: a wrapper that counts allocations, then forwards */ #define _GNU_SOURCE #include <dlfcn.h> static size_t count; void *malloc(size_t n) { static void *(*real)(size_t); if (!real) real = dlsym(RTLD_NEXT, "malloc"); /* the real one */ count++; return real(n); } /* $ gcc -shared -fPIC mymalloc.c -ldl -o mymalloc.so */ /* $ LD_PRELOAD=./mymalloc.so ./app <- app now calls ours */
Preload a library defining malloc and the linker binds the whole program to it -- no recompile, source not needed.
Interposition works only for dynamically linked binaries and is ignored for set-user-id programs; a statically linked executable has malloc baked in and cannot be preloaded.