Thread-sanitizer
=======ThreadSanitizer (aka TSan) is a data race detector for C/C++. Data races are one of the most common and hardest to debug types of bugs in concurrent systems.
A data race occurs when two threads access the same variable concurrently and at least one of the accesses is write. C++11 standard officially bans data races as undefined behavior.
$ cat simple_race.cc
#include <pthread.h>
#include <stdio.h>
int Global;
void *Thread1(void *x) {
Global++;
return NULL;
}
void *Thread2(void *x) {
Global--;
return NULL;
}
int main() {
pthread_t t[2];
pthread_create(&t[0], NULL, Thread1, NULL);
pthread_create(&t[1], NULL, Thread2, NULL);
pthread_join(t[0], NULL);
pthread_join(t[1], NULL);
}
$ clang++ simple_race.cc -fsanitize=thread -fPIE -pie -g
$ ./a.out
==================
WARNING: ThreadSanitizer: data race (pid=26327)
Write of size 4 at 0x7f89554701d0 by thread T1:
#0 Thread1(void*) simple_race.cc:8 (exe+0x000000006e66)
Previous write of size 4 at 0x7f89554701d0 by thread T2:
#0 Thread2(void*) simple_race.cc:13 (exe+0x000000006ed6)
Thread T1 (tid=26328, running) created at:
#0 pthread_create tsan_interceptors.cc:683 (exe+0x00000001108b)
#1 main simple_race.cc:19 (exe+0x000000006f39)
Thread T2 (tid=26329, running) created at:
#0 pthread_create tsan_interceptors.cc:683 (exe+0x00000001108b)
#1 main simple_race.cc:20 (exe+0x000000006f63)
==================
ThreadSanitizer: reported 1 warnings
Address-Sanitizer
=======
AddressSanitizer (aka ASan) is a memory error detector for C/C++. It finds:
- Use after free (dangling pointer dereference)
- Heap buffer overflow
- Stack buffer overflow
- Global buffer overflow
- Use after return
- Initialization order bugs
In order to use AddressSanitizer you will need to compile and link your program using clang with the -fsanitize=address switch.
To get a reasonable performance add -O1 or higher.
To get nicer stack traces in error messages add -fno-omit-frame-pointer.
% cat tests/use-after-free.c
#include <stdlib.h>
int main() {
char *x = (char*)malloc(10 * sizeof(char*));
free(x);
return x[5];
}
% ../clang_build_Linux/Release+Asserts/bin/clang -fsanitize=address -O1 -fno-omit-frame-pointer -g tests/use-after-free.c
% ./a.out
==9901==ERROR: AddressSanitizer: heap-use-after-free on address 0x60700000dfb5 at pc 0x45917b bp 0x7fff4490c700 sp 0x7fff4490c6f8
READ of size 1 at 0x60700000dfb5 thread T0
#0 0x45917a in main use-after-free.c:5
#1 0x7fce9f25e76c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226
#2 0x459074 in _start (a.out+0x459074)
0x60700000dfb5 is located 5 bytes inside of 80-byte region [0x60700000dfb0,0x60700000e000)
freed by thread T0 here:
#0 0x4441ee in __interceptor_free projects/compiler-rt/lib/asan/asan_malloc_linux.cc:64
#1 0x45914a in main use-after-free.c:4
#2 0x7fce9f25e76c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226
previously allocated by thread T0 here:
#0 0x44436e in __interceptor_malloc projects/compiler-rt/lib/asan/asan_malloc_linux.cc:74
#1 0x45913f in main use-after-free.c:3
#2 0x7fce9f25e76c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226
SUMMARY: AddressSanitizer: heap-use-after-free use-after-free.c:5 main
Memory-Sanitizer
=======
MemorySanitizer (MSan) is a detector of uninitialized memory reads in C/C++ programs.
Uninitialized values occur when stack- or heap-allocated memory is read before it is written. MSan detects cases where such values affect program execution.
MemorySanitizer is bit-exact: it can track uninitialized bits in a bitfield. It will tolerate copying of uninitialized memory, and also simple logic and arithmetic operations with it. In general, MemorySanitizer silently tracks the spread of uninitialized data in memory, and reports a warning when a code branch is taken (or not taken) depending on an uninitialized value.
% cat umr.cc
#include <stdio.h>
int main(int argc, char** argv) {
int* a = new int[10];
a[5] = 0;
if (a[argc])
printf("xx\n");
return 0;
}
%clang -fsanitize=memory -fPIE -pie -fno-omit-frame-pointer -g -O2 umr.cc
% ./a.out
==6726== WARNING: MemorySanitizer: UMR (uninitialized-memory-read)
#0 0x7fd1c2944171 in main umr.cc:6
#1 0x7fd1c1d4676c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226
'''
'''
%clang -fsanitize=memory -fsanitize-memory-track-origins -fPIE -pie -fno-omit-frame-pointer -g -O2 umr.cc
% ./a.out
==6726== WARNING: MemorySanitizer: UMR (uninitialized-memory-read)
#0 0x7fd1c2944171 in main umr.cc:6
#1 0x7fd1c1d4676c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226
ORIGIN: heap allocation:
#0 0x7f5872b6a31b in operator new[](unsigned long) msan_new_delete.cc:39
#1 0x7f5872b62151 in main umr.cc:4
#2 0x7f5871f6476c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226
** Ref:**
[ThreadSanitizer](https://code.google.com/p/thread-sanitizer/)
[AddressSanitizer](https://code.google.com/p/address-sanitizer/)
[MemorySanitizer](https://code.google.com/p/memory-sanitizer/)