Although there are many great tools to debug memory allocation errors, like Valgrind or Electric Fence, sometimes these tools aren’t available or it’s not feasible to use them. In this post I want to show you a debugging technique that doesn’t require any other software beside GNU C library. All of the examples were created and ran on a standard x86-64 machine.
GNU C library provides malloc(), free() and other related routines for dynamic memory allocation. Alongside malloc() and friends, glibc features two very interesting mechanisms to help finding common dynamic memory allocation errors.
Tracing memory allocation calls
Glibc features a tracing functionality for memory allocation debugging. It is enabled by setting a special environment variable and using mtrace() function.
The mtrace() function modifies the behavior of malloc functions family by installing hooks for malloc(), realloc() and free() functions, making all the calls to these routines traced and logged. MALLOC_TRACE environment variable should contain a valid file name to which the tracing data is written. If the file already exists it is overwritten (truncated). If the variable is not defined or does not contain a valid file path (i.e. file couldn’t be opened for writing) tracing functionality is disabled and no hooks are installed. The muntrace() function disables malloc tracing altogether. For security reasons, tracing is automatically disabled by the dynamic runtime linker for set-user-ID and set-group-ID programs.
Here’s an example program: