1 | /* |
2 | * Copyright 2017 The Abseil Authors. |
3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. |
6 | * You may obtain a copy of the License at |
7 | * |
8 | * https://www.apache.org/licenses/LICENSE-2.0 |
9 | * |
10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. |
15 | */ |
16 | /* This file defines dynamic annotations for use with dynamic analysis |
17 | tool such as valgrind, PIN, etc. |
18 | |
19 | Dynamic annotation is a source code annotation that affects |
20 | the generated code (that is, the annotation is not a comment). |
21 | Each such annotation is attached to a particular |
22 | instruction and/or to a particular object (address) in the program. |
23 | |
24 | The annotations that should be used by users are macros in all upper-case |
25 | (e.g., ANNOTATE_THREAD_NAME). |
26 | |
27 | Actual implementation of these macros may differ depending on the |
28 | dynamic analysis tool being used. |
29 | |
30 | This file supports the following configurations: |
31 | - Dynamic Annotations enabled (with static thread-safety warnings disabled). |
32 | In this case, macros expand to functions implemented by Thread Sanitizer, |
33 | when building with TSan. When not provided an external implementation, |
34 | dynamic_annotations.cc provides no-op implementations. |
35 | |
36 | - Static Clang thread-safety warnings enabled. |
37 | When building with a Clang compiler that supports thread-safety warnings, |
38 | a subset of annotations can be statically-checked at compile-time. We |
39 | expand these macros to static-inline functions that can be analyzed for |
40 | thread-safety, but afterwards elided when building the final binary. |
41 | |
42 | - All annotations are disabled. |
43 | If neither Dynamic Annotations nor Clang thread-safety warnings are |
44 | enabled, then all annotation-macros expand to empty. */ |
45 | |
46 | #ifndef ABSL_BASE_DYNAMIC_ANNOTATIONS_H_ |
47 | #define ABSL_BASE_DYNAMIC_ANNOTATIONS_H_ |
48 | |
49 | #ifndef DYNAMIC_ANNOTATIONS_ENABLED |
50 | # define DYNAMIC_ANNOTATIONS_ENABLED 0 |
51 | #endif |
52 | |
53 | #if DYNAMIC_ANNOTATIONS_ENABLED != 0 |
54 | |
55 | /* ------------------------------------------------------------- |
56 | Annotations that suppress errors. It is usually better to express the |
57 | program's synchronization using the other annotations, but these can |
58 | be used when all else fails. */ |
59 | |
60 | /* Report that we may have a benign race at "pointer", with size |
61 | "sizeof(*(pointer))". "pointer" must be a non-void* pointer. Insert at the |
62 | point where "pointer" has been allocated, preferably close to the point |
63 | where the race happens. See also ANNOTATE_BENIGN_RACE_STATIC. */ |
64 | #define ANNOTATE_BENIGN_RACE(pointer, description) \ |
65 | AnnotateBenignRaceSized(__FILE__, __LINE__, pointer, \ |
66 | sizeof(*(pointer)), description) |
67 | |
68 | /* Same as ANNOTATE_BENIGN_RACE(address, description), but applies to |
69 | the memory range [address, address+size). */ |
70 | #define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) \ |
71 | AnnotateBenignRaceSized(__FILE__, __LINE__, address, size, description) |
72 | |
73 | /* Enable (enable!=0) or disable (enable==0) race detection for all threads. |
74 | This annotation could be useful if you want to skip expensive race analysis |
75 | during some period of program execution, e.g. during initialization. */ |
76 | #define ANNOTATE_ENABLE_RACE_DETECTION(enable) \ |
77 | AnnotateEnableRaceDetection(__FILE__, __LINE__, enable) |
78 | |
79 | /* ------------------------------------------------------------- |
80 | Annotations useful for debugging. */ |
81 | |
82 | /* Report the current thread name to a race detector. */ |
83 | #define ANNOTATE_THREAD_NAME(name) \ |
84 | AnnotateThreadName(__FILE__, __LINE__, name) |
85 | |
86 | /* ------------------------------------------------------------- |
87 | Annotations useful when implementing locks. They are not |
88 | normally needed by modules that merely use locks. |
89 | The "lock" argument is a pointer to the lock object. */ |
90 | |
91 | /* Report that a lock has been created at address "lock". */ |
92 | #define ANNOTATE_RWLOCK_CREATE(lock) \ |
93 | AnnotateRWLockCreate(__FILE__, __LINE__, lock) |
94 | |
95 | /* Report that a linker initialized lock has been created at address "lock". |
96 | */ |
97 | #ifdef THREAD_SANITIZER |
98 | #define ANNOTATE_RWLOCK_CREATE_STATIC(lock) \ |
99 | AnnotateRWLockCreateStatic(__FILE__, __LINE__, lock) |
100 | #else |
101 | #define ANNOTATE_RWLOCK_CREATE_STATIC(lock) ANNOTATE_RWLOCK_CREATE(lock) |
102 | #endif |
103 | |
104 | /* Report that the lock at address "lock" is about to be destroyed. */ |
105 | #define ANNOTATE_RWLOCK_DESTROY(lock) \ |
106 | AnnotateRWLockDestroy(__FILE__, __LINE__, lock) |
107 | |
108 | /* Report that the lock at address "lock" has been acquired. |
109 | is_w=1 for writer lock, is_w=0 for reader lock. */ |
110 | #define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) \ |
111 | AnnotateRWLockAcquired(__FILE__, __LINE__, lock, is_w) |
112 | |
113 | /* Report that the lock at address "lock" is about to be released. */ |
114 | #define ANNOTATE_RWLOCK_RELEASED(lock, is_w) \ |
115 | AnnotateRWLockReleased(__FILE__, __LINE__, lock, is_w) |
116 | |
117 | #else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */ |
118 | |
119 | #define ANNOTATE_RWLOCK_CREATE(lock) /* empty */ |
120 | #define ANNOTATE_RWLOCK_CREATE_STATIC(lock) /* empty */ |
121 | #define ANNOTATE_RWLOCK_DESTROY(lock) /* empty */ |
122 | #define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) /* empty */ |
123 | #define ANNOTATE_RWLOCK_RELEASED(lock, is_w) /* empty */ |
124 | #define ANNOTATE_BENIGN_RACE(address, description) /* empty */ |
125 | #define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) /* empty */ |
126 | #define ANNOTATE_THREAD_NAME(name) /* empty */ |
127 | #define ANNOTATE_ENABLE_RACE_DETECTION(enable) /* empty */ |
128 | |
129 | #endif /* DYNAMIC_ANNOTATIONS_ENABLED */ |
130 | |
131 | /* These annotations are also made available to LLVM's Memory Sanitizer */ |
132 | #if DYNAMIC_ANNOTATIONS_ENABLED == 1 || defined(MEMORY_SANITIZER) |
133 | #define ANNOTATE_MEMORY_IS_INITIALIZED(address, size) \ |
134 | AnnotateMemoryIsInitialized(__FILE__, __LINE__, address, size) |
135 | |
136 | #define ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) \ |
137 | AnnotateMemoryIsUninitialized(__FILE__, __LINE__, address, size) |
138 | #else |
139 | #define ANNOTATE_MEMORY_IS_INITIALIZED(address, size) /* empty */ |
140 | #define ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) /* empty */ |
141 | #endif /* DYNAMIC_ANNOTATIONS_ENABLED || MEMORY_SANITIZER */ |
142 | |
143 | /* TODO(delesley) -- Replace __CLANG_SUPPORT_DYN_ANNOTATION__ with the |
144 | appropriate feature ID. */ |
145 | #if defined(__clang__) && (!defined(SWIG)) \ |
146 | && defined(__CLANG_SUPPORT_DYN_ANNOTATION__) |
147 | |
148 | #if DYNAMIC_ANNOTATIONS_ENABLED == 0 |
149 | #define ANNOTALYSIS_ENABLED |
150 | #endif |
151 | |
152 | /* When running in opt-mode, GCC will issue a warning, if these attributes are |
153 | compiled. Only include them when compiling using Clang. */ |
154 | #define ATTRIBUTE_IGNORE_READS_BEGIN \ |
155 | __attribute((exclusive_lock_function("*"))) |
156 | #define ATTRIBUTE_IGNORE_READS_END \ |
157 | __attribute((unlock_function("*"))) |
158 | #else |
159 | #define ATTRIBUTE_IGNORE_READS_BEGIN /* empty */ |
160 | #define ATTRIBUTE_IGNORE_READS_END /* empty */ |
161 | #endif /* defined(__clang__) && ... */ |
162 | |
163 | #if (DYNAMIC_ANNOTATIONS_ENABLED != 0) || defined(ANNOTALYSIS_ENABLED) |
164 | #define ANNOTATIONS_ENABLED |
165 | #endif |
166 | |
167 | #if (DYNAMIC_ANNOTATIONS_ENABLED != 0) |
168 | |
169 | /* Request the analysis tool to ignore all reads in the current thread |
170 | until ANNOTATE_IGNORE_READS_END is called. |
171 | Useful to ignore intentional racey reads, while still checking |
172 | other reads and all writes. |
173 | See also ANNOTATE_UNPROTECTED_READ. */ |
174 | #define ANNOTATE_IGNORE_READS_BEGIN() \ |
175 | AnnotateIgnoreReadsBegin(__FILE__, __LINE__) |
176 | |
177 | /* Stop ignoring reads. */ |
178 | #define ANNOTATE_IGNORE_READS_END() \ |
179 | AnnotateIgnoreReadsEnd(__FILE__, __LINE__) |
180 | |
181 | /* Similar to ANNOTATE_IGNORE_READS_BEGIN, but ignore writes instead. */ |
182 | #define ANNOTATE_IGNORE_WRITES_BEGIN() \ |
183 | AnnotateIgnoreWritesBegin(__FILE__, __LINE__) |
184 | |
185 | /* Stop ignoring writes. */ |
186 | #define ANNOTATE_IGNORE_WRITES_END() \ |
187 | AnnotateIgnoreWritesEnd(__FILE__, __LINE__) |
188 | |
189 | /* Clang provides limited support for static thread-safety analysis |
190 | through a feature called Annotalysis. We configure macro-definitions |
191 | according to whether Annotalysis support is available. */ |
192 | #elif defined(ANNOTALYSIS_ENABLED) |
193 | |
194 | #define ANNOTATE_IGNORE_READS_BEGIN() \ |
195 | StaticAnnotateIgnoreReadsBegin(__FILE__, __LINE__) |
196 | |
197 | #define ANNOTATE_IGNORE_READS_END() \ |
198 | StaticAnnotateIgnoreReadsEnd(__FILE__, __LINE__) |
199 | |
200 | #define ANNOTATE_IGNORE_WRITES_BEGIN() \ |
201 | StaticAnnotateIgnoreWritesBegin(__FILE__, __LINE__) |
202 | |
203 | #define ANNOTATE_IGNORE_WRITES_END() \ |
204 | StaticAnnotateIgnoreWritesEnd(__FILE__, __LINE__) |
205 | |
206 | #else |
207 | #define ANNOTATE_IGNORE_READS_BEGIN() /* empty */ |
208 | #define ANNOTATE_IGNORE_READS_END() /* empty */ |
209 | #define ANNOTATE_IGNORE_WRITES_BEGIN() /* empty */ |
210 | #define ANNOTATE_IGNORE_WRITES_END() /* empty */ |
211 | #endif |
212 | |
213 | /* Implement the ANNOTATE_IGNORE_READS_AND_WRITES_* annotations using the more |
214 | primitive annotations defined above. */ |
215 | #if defined(ANNOTATIONS_ENABLED) |
216 | |
217 | /* Start ignoring all memory accesses (both reads and writes). */ |
218 | #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \ |
219 | do { \ |
220 | ANNOTATE_IGNORE_READS_BEGIN(); \ |
221 | ANNOTATE_IGNORE_WRITES_BEGIN(); \ |
222 | }while (0) |
223 | |
224 | /* Stop ignoring both reads and writes. */ |
225 | #define ANNOTATE_IGNORE_READS_AND_WRITES_END() \ |
226 | do { \ |
227 | ANNOTATE_IGNORE_WRITES_END(); \ |
228 | ANNOTATE_IGNORE_READS_END(); \ |
229 | }while (0) |
230 | |
231 | #else |
232 | #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() /* empty */ |
233 | #define ANNOTATE_IGNORE_READS_AND_WRITES_END() /* empty */ |
234 | #endif |
235 | |
236 | /* Use the macros above rather than using these functions directly. */ |
237 | #include <stddef.h> |
238 | #ifdef __cplusplus |
239 | extern "C" { |
240 | #endif |
241 | void AnnotateRWLockCreate(const char *file, int line, |
242 | const volatile void *lock); |
243 | void AnnotateRWLockCreateStatic(const char *file, int line, |
244 | const volatile void *lock); |
245 | void AnnotateRWLockDestroy(const char *file, int line, |
246 | const volatile void *lock); |
247 | void AnnotateRWLockAcquired(const char *file, int line, |
248 | const volatile void *lock, long is_w); /* NOLINT */ |
249 | void AnnotateRWLockReleased(const char *file, int line, |
250 | const volatile void *lock, long is_w); /* NOLINT */ |
251 | void AnnotateBenignRace(const char *file, int line, |
252 | const volatile void *address, |
253 | const char *description); |
254 | void AnnotateBenignRaceSized(const char *file, int line, |
255 | const volatile void *address, |
256 | size_t size, |
257 | const char *description); |
258 | void AnnotateThreadName(const char *file, int line, |
259 | const char *name); |
260 | void AnnotateEnableRaceDetection(const char *file, int line, int enable); |
261 | void AnnotateMemoryIsInitialized(const char *file, int line, |
262 | const volatile void *mem, size_t size); |
263 | void AnnotateMemoryIsUninitialized(const char *file, int line, |
264 | const volatile void *mem, size_t size); |
265 | |
266 | /* Annotations expand to these functions, when Dynamic Annotations are enabled. |
267 | These functions are either implemented as no-op calls, if no Sanitizer is |
268 | attached, or provided with externally-linked implementations by a library |
269 | like ThreadSanitizer. */ |
270 | void AnnotateIgnoreReadsBegin(const char *file, int line) |
271 | ATTRIBUTE_IGNORE_READS_BEGIN; |
272 | void AnnotateIgnoreReadsEnd(const char *file, int line) |
273 | ATTRIBUTE_IGNORE_READS_END; |
274 | void AnnotateIgnoreWritesBegin(const char *file, int line); |
275 | void AnnotateIgnoreWritesEnd(const char *file, int line); |
276 | |
277 | #if defined(ANNOTALYSIS_ENABLED) |
278 | /* When Annotalysis is enabled without Dynamic Annotations, the use of |
279 | static-inline functions allows the annotations to be read at compile-time, |
280 | while still letting the compiler elide the functions from the final build. |
281 | |
282 | TODO(delesley) -- The exclusive lock here ignores writes as well, but |
283 | allows IGNORE_READS_AND_WRITES to work properly. */ |
284 | #pragma GCC diagnostic push |
285 | #pragma GCC diagnostic ignored "-Wunused-function" |
286 | static inline void StaticAnnotateIgnoreReadsBegin(const char *file, int line) |
287 | ATTRIBUTE_IGNORE_READS_BEGIN { (void)file; (void)line; } |
288 | static inline void StaticAnnotateIgnoreReadsEnd(const char *file, int line) |
289 | ATTRIBUTE_IGNORE_READS_END { (void)file; (void)line; } |
290 | static inline void StaticAnnotateIgnoreWritesBegin( |
291 | const char *file, int line) { (void)file; (void)line; } |
292 | static inline void StaticAnnotateIgnoreWritesEnd( |
293 | const char *file, int line) { (void)file; (void)line; } |
294 | #pragma GCC diagnostic pop |
295 | #endif |
296 | |
297 | /* Return non-zero value if running under valgrind. |
298 | |
299 | If "valgrind.h" is included into dynamic_annotations.cc, |
300 | the regular valgrind mechanism will be used. |
301 | See http://valgrind.org/docs/manual/manual-core-adv.html about |
302 | RUNNING_ON_VALGRIND and other valgrind "client requests". |
303 | The file "valgrind.h" may be obtained by doing |
304 | svn co svn://svn.valgrind.org/valgrind/trunk/include |
305 | |
306 | If for some reason you can't use "valgrind.h" or want to fake valgrind, |
307 | there are two ways to make this function return non-zero: |
308 | - Use environment variable: export RUNNING_ON_VALGRIND=1 |
309 | - Make your tool intercept the function RunningOnValgrind() and |
310 | change its return value. |
311 | */ |
312 | int RunningOnValgrind(void); |
313 | |
314 | /* ValgrindSlowdown returns: |
315 | * 1.0, if (RunningOnValgrind() == 0) |
316 | * 50.0, if (RunningOnValgrind() != 0 && getenv("VALGRIND_SLOWDOWN") == NULL) |
317 | * atof(getenv("VALGRIND_SLOWDOWN")) otherwise |
318 | This function can be used to scale timeout values: |
319 | EXAMPLE: |
320 | for (;;) { |
321 | DoExpensiveBackgroundTask(); |
322 | SleepForSeconds(5 * ValgrindSlowdown()); |
323 | } |
324 | */ |
325 | double ValgrindSlowdown(void); |
326 | |
327 | #ifdef __cplusplus |
328 | } |
329 | #endif |
330 | |
331 | /* ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racey reads. |
332 | |
333 | Instead of doing |
334 | ANNOTATE_IGNORE_READS_BEGIN(); |
335 | ... = x; |
336 | ANNOTATE_IGNORE_READS_END(); |
337 | one can use |
338 | ... = ANNOTATE_UNPROTECTED_READ(x); */ |
339 | #if defined(__cplusplus) && defined(ANNOTATIONS_ENABLED) |
340 | template <typename T> |
341 | inline T ANNOTATE_UNPROTECTED_READ(const volatile T &x) { /* NOLINT */ |
342 | ANNOTATE_IGNORE_READS_BEGIN(); |
343 | T res = x; |
344 | ANNOTATE_IGNORE_READS_END(); |
345 | return res; |
346 | } |
347 | #else |
348 | #define ANNOTATE_UNPROTECTED_READ(x) (x) |
349 | #endif |
350 | |
351 | #if DYNAMIC_ANNOTATIONS_ENABLED != 0 && defined(__cplusplus) |
352 | /* Apply ANNOTATE_BENIGN_RACE_SIZED to a static variable. */ |
353 | #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description) \ |
354 | namespace { \ |
355 | class static_var ## _annotator { \ |
356 | public: \ |
357 | static_var ## _annotator() { \ |
358 | ANNOTATE_BENIGN_RACE_SIZED(&static_var, \ |
359 | sizeof(static_var), \ |
360 | # static_var ": " description); \ |
361 | } \ |
362 | }; \ |
363 | static static_var ## _annotator the ## static_var ## _annotator;\ |
364 | } // namespace |
365 | #else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */ |
366 | #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description) /* empty */ |
367 | #endif /* DYNAMIC_ANNOTATIONS_ENABLED */ |
368 | |
369 | #ifdef ADDRESS_SANITIZER |
370 | /* Describe the current state of a contiguous container such as e.g. |
371 | * std::vector or std::string. For more details see |
372 | * sanitizer/common_interface_defs.h, which is provided by the compiler. */ |
373 | #include <sanitizer/common_interface_defs.h> |
374 | #define ANNOTATE_CONTIGUOUS_CONTAINER(beg, end, old_mid, new_mid) \ |
375 | __sanitizer_annotate_contiguous_container(beg, end, old_mid, new_mid) |
376 | #define ADDRESS_SANITIZER_REDZONE(name) \ |
377 | struct { char x[8] __attribute__ ((aligned (8))); } name |
378 | #else |
379 | #define ANNOTATE_CONTIGUOUS_CONTAINER(beg, end, old_mid, new_mid) |
380 | #define ADDRESS_SANITIZER_REDZONE(name) static_assert(true, "") |
381 | #endif // ADDRESS_SANITIZER |
382 | |
383 | /* Undefine the macros intended only in this file. */ |
384 | #undef ANNOTALYSIS_ENABLED |
385 | #undef ANNOTATIONS_ENABLED |
386 | #undef ATTRIBUTE_IGNORE_READS_BEGIN |
387 | #undef ATTRIBUTE_IGNORE_READS_END |
388 | |
389 | #endif /* ABSL_BASE_DYNAMIC_ANNOTATIONS_H_ */ |
390 | |