How to use mtrace to detect memory leaks in executable in Linux ?

The mtrace() function installs hook functions for the memory- allocation functions malloc, realloc, memalign, free. These hook functions record tracing information about memory allocation and deallocation. The tracing information can be used to discover memory leaks and attempts to free nonallocated memory in a program.

We will create a simple program as below,

#include <stdio.h>
#include <stdlib.h>
#include <mcheck.h>

int main(int argc, char **argv) {
int *p;

// start the trace
mtrace();
p = (int *)malloc(sizeof(int));
*p = 2;

printf("contents of P is %d\n", *p);
return 0;
}

Note here: if we want to use mtrace to detect the memory leaks, our program should include header “mcheck.h” as done in above program. Then at the start of the program i.e. from main function call the “mtrace” function. [ shown in bold above ]

Once a program is written/modify to add “#include <mcheck.h>” and function call “mtrace()” , we need to compile this code with debug flag enabled from command line as,

$ gcc -g -o detect_memleaks detect_memleaks.c

After this we need to set the environment variable where we need to store the memory trace logs as below,

 $ export MALLOC_TRACE=./mem_trace.log

Now we are all set to run our executable as,

$ ./detect_memleaks

once the program execution is completed, it will create a log file mem_trace.log in present working directory, as set with MALLOC_TRACE.

if we do the cat to this log file, we will see something like below,

$ cat mem_leak.log 
= Start
@ ./detect_memleaks:[0x8048497] + 0x84ea378 0x4

The plus ( + ) in line after [0x8048497] indicates the memory allocation as we had done with p = (int *)malloc(sizeof(int)) in above program.

Now lets see how mtrace shows it in readable format,

$ mtrace mem_leak.log

Memory not freed:
-----------------
   Address     Size     Caller
0x084ea378      0x4  at 0x8048497

Here we see that there has been some memory leaks as shows by “Memory not freed” , note: we have not freed the memory we have allocated in our program with p = (int *)malloc(sizeof(int)) in above program, hence we have seen memory leaks, which we will now proceed to correct as below,

#include <stdio.h>
#include <stdlib.h>
#include <mcheck.h>

int main(int argc, char **argv) {
int *p;

// start the trace
mtrace();
p = (int *)malloc(sizeof(int));
*p = 2;

printf("contents of P is %d\n", *p);
free(p);
return 0;
}

So, here in above program, we freed the memory using free() as shows in above, now we will execute the program again,

$ gcc -g -o detect_memleaks detect_memleaks.c
$ cat mem_leak.log 
= Start
@ ./detect_memleaks:[0x80484c7] + 0x8526378 0x4
@ ./detect_memleaks:[0x80484f7] - 0x8526378

As we seen above now, there is trace for memory free also added with minus ( – ) in line ./detect_memleaks:[0x80484f7] – 0x8526378

Now, lets see how mtrace shows in human readable format,

$ mtrace mem_leak.log
No memory leaks.

SO, now after properly freeing the memory we could see that there are no more memory leaks.

Hope this helps, do comment your observations and share with others. 🙂

Leave a Comment