Sunday, October 30, 2016

Using leaks(1) to tackle memory leaks in macOS Sierra

I am going through Learn C The Hard Way trying to finally master C (I hope that will happen).

There is a program called Valgrind which is used to detect memory leaks in C programs. It works well on Linux and sometimes works with macOS. I had installed Valgrind when I was using El Capitan but the upgrade to Sierra made Valgrind useless. The book tells us that lldb is also a debugger but thats not really useful for detecting memory leaks. I tried reinstalling Valgrind but it would not install.

Alhamdulillaah, I found a macOS command line tool called leaks which mimics the functionality of Valgrind to some extent. eg. If I have an executable named exec, I will have to run it from the command line by setting MallocStackLogging = 1, like this:

~: pro$ MallocStackLogging=1 ./exec

And then, I have to run leaks command in another terminal tab by giving the leaks command the process PID as argument, like this:

~: pro$ leaks 19009

We can get the process PID from the activity monitor. In the above command it is assumed that the process PID is 19009.

But it has also to be ensured that the program doesn't quit before leaks can complete its analysis. So for that we should have an atexit() function call in our program which calls a function which makes the program wait.

The called function has to be of return type void. eg.

void exitFn(){
    while(1) sleep(60);
}

Then from within the main function of our program, we might call atexit like this:

atexit(exitFn);

This will ensure that our program waits while leaks is checking for memory leaks.