EECS 280 Tutorials
Leaking Checking
This tutorial explains how to check for memory leaks in C/C++ programs. We’ll use the address sanitizer on WSL and Linux and the leaks
tool on macOS.
Quick start
WSL or Linux: Add the compiler flag -fsanitize=address
in the Makefile
. Compile and run.
CXXFLAGS ?= -Wall -Werror -pedantic -g --std=c++17 -Wno-sign-compare -Wno-comment
# primer-spec-highlight-start
CXXFLAGS += -fsanitize=address
# primer-spec-highlight-end
$ make main.exe
$ ./main.exe
macOS: Compile and run with the leaks
tool. Not compatible with the address sanitizer (remove compiler flag -fsanitize=address
).
$ make main.exe
$ MallocStackLogging=1 leaks -quiet -atExit -- ./main.exe
Prerequisites
This tutorial relies on command line tools. If you haven’t installed CLI tools on your machine yet, follow one of these tutorials first.
macOS | Windows | Linux |
We’re also assuming you are familiar with a text editor or IDE. If you haven’t already done so, follow one of these tutorials.
VS Code (recommended) | Visual Studio | Xcode |
Finally, you’ll need to be familiar with the command line interface (CLI). If you haven’t seen it yet, take a look at the Command Line Tutorial.
Example program
We’ll work in a directory called leakcheck
just for this tutorial.
$ mkdir leakcheck
Create a file called main.cpp
and copy-paste this leaky Hello World program.
#include <iostream>
using namespace std;
int main() {
new int; // Memory leak!
cout << "Hello Leaks!\n";
}
Create a file called Makefile
and copy-paste this code.
CXX ?= g++
CXXFLAGS ?= -Wall -Werror -pedantic -g --std=c++17 -Wno-sign-compare -Wno-comment
# Run regression test
test: main.exe
./main.exe
# Compile the main executable
main.exe: main.cpp
$(CXX) $(CXXFLAGS) main.cpp -o main.exe
# Remove automatically generated files
clean :
rm -rvf *.exe *~ *.out *.dSYM *.stackdump
Your directory should look like this:
$ tree
.
├── Makefile
└── main.cpp
The program should compile and run.
$ make main.exe
$ ./main.exe
Hello Leaks!
macOS
Verify that your Makefile does not enable the address sanitizer.
CXXFLAGS ?= -Wall -Werror -pedantic -g --std=c++17 -Wno-sign-compare -Wno-comment
# primer-spec-highlight-start
# Should *not* see -fsanitize=address
# primer-spec-highlight-end
Compile and run with the leaks
program.
$ make main.exe
$ MallocStackLogging=1 leaks -quiet -atExit -- ./main.exe
main.exe(14025) MallocStackLogging: could not tag MSL-related memory as no_footprint, so those pages will be included in process footprint - (null)
main.exe(14025) MallocStackLogging: recording malloc and VM allocation stacks using lite mode
Hello Leaks!
Process 14025 is not debuggable. Due to security restrictions, leaks can only show or save contents of readonly memory of restricted processes.
leaks Report Version: 4.0, multi-line stacks
Process 14025: 226 nodes malloced for 17 KB
Process 14025: 1 leak for 16 total leaked bytes.
STACK OF 1 INSTANCE OF 'ROOT LEAK: <malloc in main>':
3 dyld 0x1aea9be50 start + 2544
2 main.exe 0x1001bf220 main + 16 main.cpp:0
1 libc++abi.dylib 0x1aed808b0 operator new(unsigned long) + 32
0 libsystem_malloc.dylib 0x1aec2ec20 _malloc_zone_malloc_instrumented_or_legacy + 128
====
1 (16 bytes) ROOT LEAK: <malloc in main 0x12e7040f0> [16]
WSL and Linux
Edit your Makefile and enable the address sanitizer by adding -fsanitize=address
.
CXXFLAGS ?= -Wall -Werror -pedantic -g --std=c++17 -Wno-sign-compare -Wno-comment
# primer-spec-highlight-start
CXXFLAGS += -fsanitize=address
# primer-spec-highlight-end
Compile and run.
$ make main.exe
$ ./main.exe
Hello Leaks!
=================================================================
==1905936==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 4 byte(s) in 1 object(s) allocated from:
#0 0x7f54a90ae7b0 in operator new(unsigned long) (/lib64/libasan.so.5+0xf17b0)
#1 0x400a73 in main /home/awdeorio/leakcheck/main.cpp:6
#2 0x7f54a8303cf2 in __libc_start_main (/lib64/libc.so.6+0x3acf2)
SUMMARY: AddressSanitizer: 4 byte(s) leaked in 1 allocation(s).
CAEN Linux Pitfall On Michigan Engineering CAEN Linux, you may need to load a full-featured GCC with the module
tool. You’ll need to do this each time you log in.
$ module load gcc/9
Acknowledgments
Original document written by Andrew DeOrio awdeorio@umich.edu.
This document is licensed under a Creative Commons Attribution-NonCommercial 4.0 License. You’re free to copy and share this document, but not to sell it. You may not share source code provided with this document.