diff options
author | Ben Gamari <ben@smart-cactus.org> | 2019-12-01 11:50:44 -0500 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2020-10-24 20:59:39 -0400 |
commit | ccf2d4b091284a60acc6c16d166ea7cafade209f (patch) | |
tree | 20af66bb3ffb2e05c3e3960473b6c4da015b1241 /includes | |
parent | b9d4dd9cbc4f1dd40e6beaf5d8301ac9d3034fca (diff) | |
download | haskell-ccf2d4b091284a60acc6c16d166ea7cafade209f.tar.gz |
rts: Infrastructure for testing with ThreadSanitizer
Diffstat (limited to 'includes')
-rw-r--r-- | includes/Rts.h | 1 | ||||
-rw-r--r-- | includes/rts/TSANUtils.h | 63 |
2 files changed, 64 insertions, 0 deletions
diff --git a/includes/Rts.h b/includes/Rts.h index 5768e0eb7d..1e5a60262b 100644 --- a/includes/Rts.h +++ b/includes/Rts.h @@ -193,6 +193,7 @@ void _assertFail(const char *filename, unsigned int linenum) /* Parallel information */ #include "rts/OSThreads.h" +#include "rts/TSANUtils.h" #include "rts/SpinLock.h" #include "rts/Messages.h" diff --git a/includes/rts/TSANUtils.h b/includes/rts/TSANUtils.h new file mode 100644 index 0000000000..00f226d9c6 --- /dev/null +++ b/includes/rts/TSANUtils.h @@ -0,0 +1,63 @@ +/* ---------------------------------------------------------------------------- + * + * (c) The GHC Team, 2006-2019 + * + * Utilities for annotating "safe" data races for Thread Sanitizer + * -------------------------------------------------------------------------- */ + +/* + * Note [ThreadSanitizer] + * ~~~~~~~~~~~~~~~~~~~~~~~ + * ThreadSanitizer (abbreviated TSAN) is a library and set of compiler + * instrumentation (supported by both GCC and Clang) for checking C/C++ code + * for data races. + * + * In GHC we use it to check the runtime system implementation (but not yet + * generated code). TSAN requires that the checked program uses C++11-style + * atomics for all potentially-racing accesses. Note that we use the __atomic_* + * builtin operations but not the C11 _Atomic types to maintain compatibility + * with older compilers. + * + * In addition to the atomic operations themselves, TSAN provides a variety of + * annotation operations which can be used to annotate cases where the + * intended semantics are either ambiguous or intentionally racy (known as a + * *benign race*). + * + * Finally, there are a few benign races which we can't easily annotate. To + * silence these errors we have a suppressions file in rts/.tsan-suppressions. + * In general it's best to add suppressions only as a last resort, when the + * more precise annotation functions prove to be insufficient. + * + * Users guide: https://github.com/google/sanitizers/wiki/ThreadSanitizerCppManual + */ + +#if defined(__SANITIZE_THREAD__) +#define TSAN_ENABLED +#elif defined(__has_feature) +#if __has_feature(thread_sanitizer) +#define TSAN_ENABLED +#endif +#endif + +#if defined(TSAN_ENABLED) +#define TSAN_ANNOTATE_HAPPENS_BEFORE(addr) \ + AnnotateHappensBefore(__FILE__, __LINE__, (void*)(addr)) +#define TSAN_ANNOTATE_HAPPENS_AFTER(addr) \ + AnnotateHappensAfter(__FILE__, __LINE__, (void*)(addr)) +#define TSAN_ANNOTATE_BENIGN_RACE_SIZED(addr,size,desc) \ + AnnotateBenignRaceSized(__FILE__, __LINE__, (void*)(addr), size, desc) +void AnnotateHappensBefore(const char* f, int l, void* addr); +void AnnotateHappensAfter(const char* f, int l, void* addr); +void AnnotateBenignRaceSized(const char *file, + int line, + const volatile void *mem, + long size, + const char *description); +#else +#define TSAN_ANNOTATE_HAPPENS_BEFORE(addr) +#define TSAN_ANNOTATE_HAPPENS_AFTER(addr) +#define TSAN_ANNOTATE_BENIGN_RACE_SIZED(addr,size,desc) +#endif + +#define TSAN_ANNOTATE_BENIGN_RACE(addr,desc) \ + TSAN_ANNOTATE_BENIGN_RACE_SIZED((void*)(addr), sizeof(*addr), desc) |