Detecting Leaks with LeakSanitizer

LeakSanitizer is a useful tool that helps you track down memory leaks in your C programs. To use LeakSanitizer, you have to pass in some additional options to your program compilation. While the tool was originally implemented in the clang compiler, it is also available for gcc on MathLAN machines. Apple users can use LeakSanitizer on their machines as well, but you will need to install a newer version of LLVM (which includes clang) on your mac than the one that is provided by Apple. I use the homebrew package manager to do this, but there are alternatives.

To use LeakSanitizer, you compile your program with the added option -fsanitize=leak. Usually you’ll want to do this in conjunction with the -g flag. We’ll compile a simple example program to see LeakSanitizer in action. First, let’s look at the code in leak.c:

#include <stdlib.h>

int main() {
  int* p = malloc(sizeof(int));
  return 0;
}

Obviously this program has a leak, since it never calls free. To test this program with LeakSanitizer we’ll compile it, and then run it as we normally would.

$ clang -g -fsanitize=leak -o leak leak.c
$ ./leak

=================================================================
==2257==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 4 byte(s) in 1 object(s) allocated from:
    #0 0x4078ff in __interceptor_malloc (/home/curtsinger/leak+0x4078ff)
    #1 0x427bea in main /home/curtsinger/leak.c:4:12
    #2 0x7f788f42f2b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)

SUMMARY: LeakSanitizer: 4 byte(s) leaked in 1 allocation(s).

This output tells us that we leaked a single 4-byte object, and then gives us a backtrace from the point where this object was allocated. A backtrace is just the sequence of function calls that led to the point where the allocation was called. The top item is a special version of malloc that LeakSanitizer adds to our program to track allocated memory, but the line below that points us to the code in leak.c that allocated the leaked object.

Using LeakSanitizer with CSC 213 Makefiles

The Makefile code provided with most CSC 213 labs hides some of the compiler options, so you’ll had to enable LeakSanitizer in a slightly different way for labs or assignments. The main rules for make are defined in a common.mk file at the root of each lab. Then, in each directory there is a Makefile with a standard form. Here’s one from assignment 2:

ROOT = .
TARGETS = test-uniquelist

include $(ROOT)/common.mk

To build the test-uniquelist program with LeakSanitizer, just add one line to Makefile so you have the following file contents:

ROOT = .
TARGETS = test-uniquelist
CFLAGS = -g -fsanitize=leak

include $(ROOT)/common.mk

If you run make clean and then make, you should have a LeakSanitizer version of your program ready to test. Keep in mind, you generally do not want to run your program with LeakSanitizer all the time. This is a useful testing tool, but not something you should enable all the time.