|
19 | 19 | #include <cassert>
|
20 | 20 | #include <cstdlib>
|
21 | 21 | #include <cstring>
|
| 22 | +#include <dlfcn.h> |
22 | 23 | #include <inttypes.h>
|
23 | 24 | #include <iostream>
|
24 | 25 | #include <list>
|
|
29 | 30 | #include <unistd.h>
|
30 | 31 | #include <unordered_map>
|
31 | 32 | #include <vector>
|
32 |
| -#include <dlfcn.h> |
33 | 33 |
|
34 | 34 | #include "omp-tools.h"
|
35 | 35 |
|
@@ -146,18 +146,28 @@ void __attribute__((weak)) __tsan_flush_memory() {}
|
146 | 146 | static ArcherFlags *archer_flags;
|
147 | 147 |
|
148 | 148 | #ifndef TsanHappensBefore
|
| 149 | + |
| 150 | +template <typename... Args> static void __ompt_tsan_func(Args...) {} |
| 151 | + |
| 152 | +#define DECLARE_TSAN_FUNCTION(name, ...) \ |
| 153 | + static void (*name)(__VA_ARGS__) = __ompt_tsan_func<__VA_ARGS__>; |
| 154 | + |
149 | 155 | // Thread Sanitizer is a tool that finds races in code.
|
150 | 156 | // See http://code.google.com/p/data-race-test/wiki/DynamicAnnotations .
|
151 | 157 | // tsan detects these exact functions by name.
|
152 | 158 | extern "C" {
|
153 |
| -static void (*AnnotateHappensAfter)(const char *, int, const volatile void *); |
154 |
| -static void (*AnnotateHappensBefore)(const char *, int, const volatile void *); |
155 |
| -static void (*AnnotateIgnoreWritesBegin)(const char *, int); |
156 |
| -static void (*AnnotateIgnoreWritesEnd)(const char *, int); |
157 |
| -static void (*AnnotateNewMemory)(const char *, int, const volatile void *, |
158 |
| - size_t); |
159 |
| -static void (*__tsan_func_entry)(const void *); |
160 |
| -static void (*__tsan_func_exit)(void); |
| 159 | +DECLARE_TSAN_FUNCTION(AnnotateHappensAfter, const char *, int, |
| 160 | + const volatile void *) |
| 161 | +DECLARE_TSAN_FUNCTION(AnnotateHappensBefore, const char *, int, |
| 162 | + const volatile void *) |
| 163 | +DECLARE_TSAN_FUNCTION(AnnotateIgnoreWritesBegin, const char *, int) |
| 164 | +DECLARE_TSAN_FUNCTION(AnnotateIgnoreWritesEnd, const char *, int) |
| 165 | +DECLARE_TSAN_FUNCTION(AnnotateNewMemory, const char *, int, |
| 166 | + const volatile void *, size_t) |
| 167 | +DECLARE_TSAN_FUNCTION(__tsan_func_entry, const void *) |
| 168 | +DECLARE_TSAN_FUNCTION(__tsan_func_exit) |
| 169 | + |
| 170 | +// RunningOnValgrind is used to detect absence of TSan and must intentionally be a nullptr. |
161 | 171 | static int (*RunningOnValgrind)(void);
|
162 | 172 | }
|
163 | 173 |
|
@@ -1142,7 +1152,10 @@ static void ompt_tsan_mutex_released(ompt_mutex_t kind, ompt_wait_id_t wait_id,
|
1142 | 1152 |
|
1143 | 1153 | #define findTsanFunction(f, fSig) \
|
1144 | 1154 | do { \
|
1145 |
| - if (NULL == (f = fSig dlsym(RTLD_DEFAULT, #f))) \ |
| 1155 | + void *fp = dlsym(RTLD_DEFAULT, #f); \ |
| 1156 | + if (fp) \ |
| 1157 | + f = fSig fp; \ |
| 1158 | + else \ |
1146 | 1159 | printf("Unable to find TSan function " #f ".\n"); \
|
1147 | 1160 | } while (0)
|
1148 | 1161 |
|
|
0 commit comments