Sanitizers are dynamic analysis tools that detect bugs such as buffer overflows or accesses, dangling pointers or different types of undefined behavior at runtime and prevent security vulnerabilities in C/C++ code.
Valgrind is a dynamic analysis tool that can be used to detect memory leaks, or buffer overflows errors in C/C++ code.
NOTE Valgrind tools are not designed to be used simultaneously. Each tool serves a specific purpose and provides different types of analysis or debugging capabilities. Run one tool at a time to get the desired information about a program's behavior or performance.
Support and Services
Linux
Support for x86, AMD64, ARM32, ARM64, PPC32, PPC64BE, PPC64LE, S390X, MIPS32, MIPS64.
Android
Support for ARM, ARM64, MIPS32, X86.
Solaris
Support for X86, AMD64.
FreeBSD
Support for X86, AMD64.
MacOSX
Support for AMD64.
1.1.1. Memcheck
Memcheck detects memory-management problems, primarily aimed at C and C++ programs.
Files and Folders
program.c
Create a memory leak by allocating memory and not freeing it.
#include <stdlib.h>
int* function(void) {
int *memory_leak = malloc(sizeof(int)); // Triggering memory leak error
return memory_leak;
}
int main(void) {
int *data = function();
return 0;
}
Commands and Operations
Compile and Check
Compiling a program with gcc and checking for memory leaks with Memcheck.
==1665143== Memcheck, a memory error detector
==1665143== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1665143== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==1665143== Command: ./executable
==1665143==
==1665143==
==1665143== HEAP SUMMARY:
==1665143== in use at exit: 4 bytes in 1 blocks
==1665143== total heap usage: 1 allocs, 0 frees, 4 bytes allocated
==1665143==
==1665143== 4 bytes in 1 blocks are definitely lost in loss record 1 of 1
==1665143== at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==1665143== by 0x10915E: function (program.c:4)
==1665143== by 0x109179: main (program.c:9)
==1665143==
==1665143== LEAK SUMMARY:
==1665143== definitely lost: 4 bytes in 1 blocks
==1665143== indirectly lost: 0 bytes in 0 blocks
==1665143== possibly lost: 0 bytes in 0 blocks
==1665143== still reachable: 0 bytes in 0 blocks
==1665143== suppressed: 0 bytes in 0 blocks
==1665143==
==1665143== For lists of detected and suppressed errors, rerun with: -s
==1665143== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
1.1.2. Helgrind
Helgrind is a thread debugger for finding data races in multithreaded programs.
Files and Folders
program.c
Creates data races by having two threads increment a shared variable.
==1587133== Helgrind, a thread error detector
==1587133== Copyright (C) 2007-2017, and GNU GPL'd, by OpenWorks LLP et al.
==1587133== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==1587133== Command: ./executable
==1587133==
==1587133== Possible data race during write of size 4 at 0x10C014 by thread #3
==1587133== Locks held: none
==1587133== at 0x1091BE: thread_function (program.c:7)
==1587133== by 0x485396A: ??? (in /usr/libexec/valgrind/vgpreload_helgrind-amd64-linux.so)
==1587133== by 0x48FBAC2: start_thread (pthread_create.c:442)
==1587133== by 0x498CA03: clone (clone.S:100)
==1587133==
==1587133== This conflicts with a previous write of size 4 by thread #2
==1587133== Locks held: none
==1587133== at 0x1091BE: thread_function (program.c:7)
==1587133== by 0x485396A: ??? (in /usr/libexec/valgrind/vgpreload_helgrind-amd64-linux.so)
==1587133== by 0x48FBAC2: start_thread (pthread_create.c:442)
==1587133== by 0x498CA03: clone (clone.S:100)
==1587133== Address 0x10c014 is 0 bytes inside data symbol "shared_variable"
==1587133==
Shared variable: 2
==1587133==
==1587133== Use --history-level=approx or =none to gain increased speed, at
==1587133== the cost of reduced accuracy of conflicting-access information
==1587133== For lists of detected and suppressed errors, rerun with: -s
==1587133== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
1.1.3. DRD
DRD is a thread error detector that helps in identifying issues in multithreaded programs.
Files and Folders
program.c
Creates data races by having two threads increment a shared variable.
==1591008== drd, a thread error detector
==1591008== Copyright (C) 2006-2020, and GNU GPL'd, by Bart Van Assche.
==1591008== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==1591008== Command: ./executable
==1591008==
==1591008== Thread 3:
==1591008== Conflicting store by thread 3 at 0x0010c014 size 4
==1591008== at 0x1091BE: thread_function (program.c:7)
==1591008== by 0x485437A: ??? (in /usr/libexec/valgrind/vgpreload_drd-amd64-linux.so)
==1591008== by 0x4918AC2: start_thread (pthread_create.c:442)
==1591008== by 0x49A9A03: clone (clone.S:100)
==1591008== Allocation context: BSS section of /home/executable
==1591008== Other segment start (thread 2)
==1591008== at 0x49A99F6: clone (clone.S:83)
==1591008== by 0x49187CF: ??? (pthread_create.c:321)
==1591008== by 0x52B063F: ???
==1591008== Other segment end (thread 2)
==1591008== at 0x49A2B7B: madvise (syscall-template.S:117)
==1591008== by 0x4918BE0: advise_stack_range (allocatestack.c:195)
==1591008== by 0x4918BE0: start_thread (pthread_create.c:551)
==1591008== by 0x49A9A03: clone (clone.S:100)
==1591008==
Shared variable: 2
==1591008==
==1591008== For lists of detected and suppressed errors, rerun with: -s
==1591008== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 8 from 4)
1.1.4. Massif
Massif is a heap profiler that measures how much heap memory a program uses.
Files and Folders
program.c
Allocates and frees memory to analyze heap usage with Massif.
desc: (none)
cmd: ./executable
time_unit: i
#-----------
snapshot=2
#-----------
time=148046
mem_heap_B=1
mem_heap_extra_B=23
mem_stacks_B=0
heap_tree=detailed
n1: 1 (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
n1: 1 0x10917E: function (program.c:4)
n0: 1 0x1091C7: main (program.c:14)
#-----------
snapshot=5
#-----------
time=148123
mem_heap_B=1048576
mem_heap_extra_B=8
mem_stacks_B=0
heap_tree=peak
n2: 1048576 (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
n1: 1048576 0x1091A7: massif (program.c:9)
n0: 1048576 0x1091CC: main (program.c:15)
n0: 0 in 1 place, below massif's threshold (1.00%)
1.1.5. Cachegrind
Cachegrind is a cache profiler that analyzes cache use and identifies bottlenecks.
Files and Folders
program.c
Creates cache performance issues by accessing an array of integers.
#include <stdlib.h>
int function(void) {
int i, sum = 0;
int *array = malloc(1000 * sizeof(int));
for (i = 0; i < 1000; i++) {
sum += array[i];
}
return sum;
}
int main(void) {
int data = function();
return data;
}
The Google Sanitizers are a collection of tools integrated into compilers, designed to detect various types of bugs.
NOTE Google Sanitizers are not designed to be used simultaneously. Each sanitizer serves a specific purpose and provides different types of analysis or debugging capabilities. Compile and run a program with one sanitizer at a time to get the desired information about a program’s behavior or performance. Using multiple sanitizers at once could lead to conflicts and potentially inaccurate results.
Support and Services
LLVM/Clang
Support for AddressSanitizer (ASan), LeakSanitizer (LSan), UndefinedBehaviorSanitizer (UBSan), ThreadSanitizer (TSan), MemorySanitizer (MSan), DataFlowSanitizer (DFSan).
GCC/G++
Support for AddressSanitizer (ASan), LeakSanitizer (LSan), UndefinedBehaviorSanitizer (UBSan), ThreadSanitizer (TSan).
MSVC
Support for AddressSanitizer (ASan).
1.2.1. AddressSanitizer (ASan)
AddressSanitizer (ASan) is a dynamic analysis tool that detects memory access errors, such as out-of-bounds memory accesses and use-after-free bugs.
Files and Folders
program.cpp
Out-of-bounds access, triggering ASan error.
#include <iostream>
void function(void) {
int* array = new int[10];
array[11] = 42; // Triggering ASan error
delete[] array;
}
int main(void) {
function();
return 0;
}
Commands and Operations
Compile
Compiling with the sanitizer flag -fsanitize=address.
=================================================================
==1617890==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60400000003c at pc 0x56502431e2e2 bp 0x7fff570c3790 sp 0x7fff570c3780
WRITE of size 4 at 0x60400000003c thread T0
#0 0x56502431e2e1 in function() (/home/executable+0x12e1)
#1 0x56502431e30a in main (/home/executable+0x130a)
#2 0x7f84f97c2d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
#3 0x7f84f97c2e3f in __libc_start_main_impl ../csu/libc-start.c:392
#4 0x56502431e1c4 in _start (/home/executable+0x11c4)
0x60400000003c is located 4 bytes to the right of 40-byte region [0x604000000010,0x604000000038)
allocated by thread T0 here:
#0 0x7f84f9dab357 in operator new[](unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:102
#1 0x56502431e29e in function() (/home/executable+0x129e)
#2 0x56502431e30a in main (/home/executable+0x130a)
#3 0x7f84f97c2d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
SUMMARY: AddressSanitizer: heap-buffer-overflow (/home/executable+0x12e1) in function()
Shadow bytes around the buggy address:
0x0c087fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c087fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c087fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c087fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c087fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c087fff8000: fa fa 00 00 00 00 00[fa]fa fa fa fa fa fa fa fa
0x0c087fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c087fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c087fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c087fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c087fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==1617890==ABORTING
==12345==WARNING: MemorySanitizer: use-of-uninitialized-value
#0 0x4a5b2c in main /path/to/program.c:5:12
#1 0x7f6e38c5783f in __libc_start_main /build/glibc-e6zv40/glibc-2.23/csu/../csu/libc-start.c:291
#2 0x419a68 in _start (/path/to/program+0x419a68)
Uninitialized value was created by a stack allocation
#0 0x4a5a40 in main /path/to/program.c:3:5
SUMMARY: MemorySanitizer: use-of-uninitialized-value /path/to/program.c:5:12 in main
Exiting
1.2.4. UndefinedBehaviorSanitizer (UBSan)
UndefinedBehaviorSanitizer (UBSan) is a dynamic analysis tool that detects undefined behavior, such as signed integer overflow and division by zero.
Files and Folders
program.cpp
Division by zero and signed integer overflow, triggering UBSan error.
#include <iostream>
#include <limits>
void divisionByZero(void) {
int x = 10;
int y = 0;
int result = x / y; // Division by zero
std::cout << result << std::endl;
}
void signedIntegerOverflow(void) {
int maxInt = std::numeric_limits<int>::max();
int result = maxInt + 1; // Signed integer overflow
std::cout << result << std::endl;
}
int main(void) {
divisionByZero();
signedIntegerOverflow();
return 0;
}
Commands and Operations
Compile
Compiling with the sanitizer flag -fsanitize=undefined.
program.cpp:6:20: runtime error: division by zero
program.cpp:13:7: runtime error: signed integer overflow: 2147483647 + 1 cannot be represented in type 'int'
1.2.5. ThreadSanitizer (TSan)
ThreadSanitizer (TSan) is a tool that detects data races and synchronization bugs in multithreaded code.
Sanitizer
Sanitizers are dynamic analysis tools that detect bugs such as buffer overflows or accesses, dangling pointers or different types of undefined behavior at runtime and prevent security vulnerabilities in C/C++ code.
1. Category
1.1. Valgrind
Valgrind is a dynamic analysis tool that can be used to detect memory leaks, or buffer overflows errors in C/C++ code.
Support and Services
Linux
Android
Solaris
FreeBSD
MacOSX
1.1.1. Memcheck
Memcheck detects memory-management problems, primarily aimed at C and C++ programs.
Files and Folders
program.c
Commands and Operations
Compile and Check
Output and Result
output.log
1.1.2. Helgrind
Helgrind is a thread debugger for finding data races in multithreaded programs.
Files and Folders
program.c
Commands and Operations
Compile and Detect
Output and Result
output.log
1.1.3. DRD
DRD is a thread error detector that helps in identifying issues in multithreaded programs.
Files and Folders
program.c
Commands and Operations
Compile and Detect
Output and Result
output.log
1.1.4. Massif
Massif is a heap profiler that measures how much heap memory a program uses.
Files and Folders
program.c
Commands and Operations
Compile and Analyze
Output and Result
massif.out.xxx
1.1.5. Cachegrind
Cachegrind is a cache profiler that analyzes cache use and identifies bottlenecks.
Files and Folders
program.c
Commands and Operations
Compile, Profile and Analyze
Output and Result
output.log
1.2. Google Sanitizer
The Google Sanitizers are a collection of tools integrated into compilers, designed to detect various types of bugs.
Support and Services
LLVM/Clang
GCC/G++
MSVC
1.2.1. AddressSanitizer (ASan)
AddressSanitizer (ASan) is a dynamic analysis tool that detects memory access errors, such as out-of-bounds memory accesses and use-after-free bugs.
Files and Folders
program.cpp
Commands and Operations
Compile
Output and Result
output.log
1.2.2. LeakSanitizer (LSan)
LeakSanitizer (LSan) is a dynamic analysis tool that detects memory leaks.
Files and Folders
program.cpp
Commands and Operations
Compile
output.log
1.2.3. MemorySanitizer (MSan)
MemorySanitizer (MSan) is a dynamic analysis tool that detects uninitialized memory reads.
Files and Folders
program.cpp
Commands and Operations
Compile
Output and Result
output.log
1.2.4. UndefinedBehaviorSanitizer (UBSan)
UndefinedBehaviorSanitizer (UBSan) is a dynamic analysis tool that detects undefined behavior, such as signed integer overflow and division by zero.
Files and Folders
program.cpp
Commands and Operations
Compile
Output and Result
output.log
1.2.5. ThreadSanitizer (TSan)
ThreadSanitizer (TSan) is a tool that detects data races and synchronization bugs in multithreaded code.
Files and Folders
program.cpp
Commands and Operations
Compile
Output and Result
output.log
2. References