EECS 280 Tutorials
Address Sanitizer
This tutorial will compile your code with an Address Sanitizer enabled. The Address Sanitizer is very good at finding memory errors, including going off the end of an array or vector.
If you’re interested, here is more information about the Address Sanitizer and detailed examples of what the Address Sanitizer can do.
Quick Start
To enable the address sanitizer, add these compiler flags to add to your Makefile
.
WSL or Linux: Add compiler flags -fsanitize=address
, -fsanitize=undefined
, and -D_GLIBCXX_DEBUG
. For example:
CXXFLAGS = --std=c++17 -Wall -Werror -pedantic -g -fsanitize=address -fsanitize=undefined -D_GLIBCXX_DEBUG
macOS: Add compiler flags -fsanitize=address
and -fsanitize=undefined
. For example:
CXXFLAGS = --std=c++17 -Wall -Werror -pedantic -g -fsanitize=address -fsanitize=undefined
Visual Studio: Address sanitizer is enabled by default.
Xcode: Enable the address sanitizer and undefined behavior sanitizer with this (tutorial).
Pitfall: If you enable sanitizers in your Makefile
and change nothing else in your code, you will need to do a make clean
to recompile with the sanitizers on.
$ make clean
Example without Address Sanitizer
Let’s do an example without an address sanitizer. We’ll make a mistake on purpose in asan.cpp
, going off the end of a vector
.
#include <iostream>
#include <vector>
using namespace std;
int main() {
cout << "hello from main!\n";
vector<int> v = {0, 0}; // v contains 2 items
// primer-spec-highlight-start
cout << v[2] << "\n"; // off the end of v
// primer-spec-highlight-end
}
Clean, build and run. Notice that the output of v[2]
is 0
, however, this operation is undefined because it’s off the end of the vector! Because the output is undefined, your output might be different.
$ g++ --std=c++17 -Wall -Werror -pedantic -g asan.cpp -o asan.exe
$ ./asan.exe
hello from main!
0
Example with Address Sanitizer
We’ll now recompile with the address sanitizer enabled. If you’re using GCC, you’ll need version 4.9 or higher.
WARNING: The address sanitizer will not work on heavily resource limited system such as CAEN Linux.
Compile with the address sanitizer flags.
$ g++ --std=c++17 -Wall -Werror -pedantic -g -fsanitize=address -fsanitize=undefined asan.cpp -o asan.exe
Run. The sanitizer detects the problem and prints a stack trace.
$ ./asan.exe
hello from main!
=================================================================
==34112==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6020000000d8 at pc 0x000105c1639c bp 0x7ffee9fe9f90 sp 0x7ffee9fe9f88
READ of size 4 at 0x6020000000d8 thread T0
#0 0x105c1639b in main asan.cpp:8
#1 0x7fff206a4f3c in start+0x0 (libdyld.dylib:x86_64+0x15f3c)
...
Visual Debuggers
Visual Studio
Visual Studio provides an address sanitizer with bounds checking automatically with every debug build. You don’t need to do anything different!
Xcode
If you’re using Xcode, you can enable the address sanitizer and undefined behavior sanitizer when you run or debug within Xcode (tutorial).
VS Code
If you’re using VS Code, you can enable the address sanitizer by editing your launch.json
(tutorial).
Emacs, VIM, et al.
Update your Makefile
using the instructions in the Quick Start. Then, build and run in the terminal.
Pro-tips
Here’s a way to automatically add the correct compiler flags on macOS or Windows/WSL/Linux. Edit the top of your Makefile
with the following code, which will figure out the OS and append the correct compiler flags.
CXX ?= g++
CXXFLAGS ?= --std=c++17 -Wall -Werror -pedantic -g
# Add sanitizer flags for identifying undefined behavior. The flags are
# different on macOS (AKA Darwin) and Windows/WSL/Linux.
UNAME := $(shell uname -s)
ifeq "$(UNAME)" "Darwin"
CXXFLAGS += -fsanitize=address -fsanitize=undefined
else
CXXFLAGS += -fsanitize=address -fsanitize=undefined -D_GLIBCXX_DEBUG
endif
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.