Detecting memory leaks by overloading malloc

Let us see how to detect leaks by overriding the malloc and free implementations in GNU “libc.so” library

Consider the below program which leaks memory,

#include<stdio.h>
int main()
{
void *ptr1 = malloc(10);
void* ptr2 = malloc(50);
void* ptr3 = malloc(70);
void* ptr4 = malloc(123);
//do something
free(ptr3);
free(ptr1);
return 0;
}

When we compile and run the executable, it will run fine, but it will leak memory referenced by ptr2 and ptr4. To find out such leaks in our code we can overload the implementation of malloc() and free() in libc.so file as follows.

Write the following source code in alloc.c file
#include<sys/types.h>
#include<stdio.h>
#include<dlfcn.h>
void* malloc(int size)
{
void* (*fptr)(int);
void* handle = (void*) -1l;
fptr = (void * (*)())dlsym(handle, “malloc”);
if (fptr == NULL)
{
printf(“Error in locating\n”);
return NULL;
}
void*ret  = (*fptr)(size);
printf(“Allocated ptr %x %d\n”, ret, size);
return ret;
}
void free(void* ptr)
{
void (*fptr)(void*);
void* handle = (void*) -1; //tells dlsym to locate the next symbol
fptr = (void (*)(void*))dlsym(handle, “free”);
if (fptr == NULL)
{
printf(“Error in locating\n”);
return;
}
(*fptr)(ptr);
printf(“Deallocated ptr %x\n”, ptr);
return;
}

compile the above code and create shared library libsample.so as follows

$gcc -fPIC  -c alloc.c
$gcc -shared -Wl,-soname,libsample.so -o libsample.so alloc.o -lc -ld
fPIC flag instructs the compiler to produce position independent code, so that it shall be used for creating dynamic libraries.

After this set the environment variable, LD_LIBRARY_PATH to include the path where libsample.so library is created.
$export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH

run the executable file
$LD_PRELAD=libsample.so ./a.out
Allocated ptr 82cd008 10
Allocated ptr 82cd018 50
Allocated ptr 82cd050 70
Allocated ptr 82cd0a0 123
Deallocated ptr 82cd050
Deallocated ptr 82cd008

From the above output, by verifying pointer values we can figure out that two allocations are leaked.

The same technique can be used if you wish to extend functionalities provided by any GNU functions by creating wrapper library for the functions which need to be extended.  This will not require any client code changes(code which calls malloc and free in our case) but still the functionality is extended for the client applications.

Syntax for dynamic loading functions can be found at this url

Further Reading

http://www.ibm.com/developerworks/linux/library/l-glibc.html