OLD | NEW |
| (Empty) |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 // This file defines dynamic annotations for use with dynamic analysis | |
6 // tool such as valgrind, PIN, etc. | |
7 // | |
8 // Dynamic annotation is a source code annotation that affects | |
9 // the generated code (that is, the annotation is not a comment). | |
10 // Each such annotation is attached to a particular | |
11 // instruction and/or to a particular object (address) in the program. | |
12 // | |
13 // The annotations that should be used by users are macros in all upper-case | |
14 // (e.g., ANNOTATE_NEW_MEMORY). | |
15 // | |
16 // Actual implementation of these macros may differ depending on the | |
17 // dynamic analysis tool being used. | |
18 // | |
19 // This file supports the following dynamic analysis tools: | |
20 // - None (NVALGRIND is defined). | |
21 // Macros are defined empty. | |
22 // - ThreadSanitizer (NVALGRIND is not defined). | |
23 // Macros are defined as calls to non-inlinable empty functions | |
24 // that are intercepted by ThreadSanitizer. | |
25 // | |
26 #ifndef BASE_DYNAMIC_ANNOTATIONS_H_ | |
27 #define BASE_DYNAMIC_ANNOTATIONS_H_ | |
28 | |
29 #ifdef __GNUC__ | |
30 // valgrind.h uses gcc extensions so it may not build with other compilers. | |
31 // Also, it defines NVALGRIND on Windows, which disables dynamic annotations | |
32 // for ThreadSanitizer. | |
33 #include "base/third_party/valgrind/valgrind.h" | |
34 #endif | |
35 | |
36 #ifndef NVALGRIND | |
37 // ------------------------------------------------------------- | |
38 // Annotations useful when implementing condition variables such as CondVar, | |
39 // using conditional critical sections (Await/LockWhen) and when constructing | |
40 // user-defined synchronization mechanisms. | |
41 // | |
42 // The annotations ANNOTATE_HAPPENS_BEFORE() and ANNOTATE_HAPPENS_AFTER() can | |
43 // be used to define happens-before arcs in user-defined synchronization | |
44 // mechanisms: the race detector will infer an arc from the former to the | |
45 // latter when they share the same argument pointer. | |
46 // | |
47 // Example 1 (reference counting): | |
48 // | |
49 // void Unref() { | |
50 // ANNOTATE_HAPPENS_BEFORE(&refcount_); | |
51 // if (AtomicDecrementByOne(&refcount_) == 0) { | |
52 // ANNOTATE_HAPPENS_AFTER(&refcount_); | |
53 // delete this; | |
54 // } | |
55 // } | |
56 // | |
57 // Example 2 (message queue): | |
58 // | |
59 // void MyQueue::Put(Type *e) { | |
60 // MutexLock lock(&mu_); | |
61 // ANNOTATE_HAPPENS_BEFORE(e); | |
62 // PutElementIntoMyQueue(e); | |
63 // } | |
64 // | |
65 // Type *MyQueue::Get() { | |
66 // MutexLock lock(&mu_); | |
67 // Type *e = GetElementFromMyQueue(); | |
68 // ANNOTATE_HAPPENS_AFTER(e); | |
69 // return e; | |
70 // } | |
71 // | |
72 // Note: when possible, please use the existing reference counting and message | |
73 // queue implementations instead of inventing new ones. | |
74 | |
75 // Report that wait on the condition variable at address "cv" has succeeded | |
76 // and the lock at address "lock" is held. | |
77 #define ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) \ | |
78 AnnotateCondVarWait(__FILE__, __LINE__, cv, lock) | |
79 | |
80 // Report that wait on the condition variable at "cv" has succeeded. Variant | |
81 // w/o lock. | |
82 #define ANNOTATE_CONDVAR_WAIT(cv) \ | |
83 AnnotateCondVarWait(__FILE__, __LINE__, cv, NULL) | |
84 | |
85 // Report that we are about to signal on the condition variable at address | |
86 // "cv". | |
87 #define ANNOTATE_CONDVAR_SIGNAL(cv) \ | |
88 AnnotateCondVarSignal(__FILE__, __LINE__, cv) | |
89 | |
90 // Report that we are about to signal_all on the condition variable at "cv". | |
91 #define ANNOTATE_CONDVAR_SIGNAL_ALL(cv) \ | |
92 AnnotateCondVarSignalAll(__FILE__, __LINE__, cv) | |
93 | |
94 // Annotations for user-defined synchronization mechanisms. | |
95 #define ANNOTATE_HAPPENS_BEFORE(obj) ANNOTATE_CONDVAR_SIGNAL(obj) | |
96 #define ANNOTATE_HAPPENS_AFTER(obj) ANNOTATE_CONDVAR_WAIT(obj) | |
97 | |
98 // Report that the bytes in the range [pointer, pointer+size) are about | |
99 // to be published safely. The race checker will create a happens-before | |
100 // arc from the call ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) to | |
101 // subsequent accesses to this memory. | |
102 #define ANNOTATE_PUBLISH_MEMORY_RANGE(pointer, size) \ | |
103 AnnotatePublishMemoryRange(__FILE__, __LINE__, pointer, size) | |
104 | |
105 // Instruct the tool to create a happens-before arc between mu->Unlock() and | |
106 // mu->Lock(). This annotation may slow down the race detector; normally it | |
107 // is used only when it would be difficult to annotate each of the mutex's | |
108 // critical sections individually using the annotations above. | |
109 #define ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mu) \ | |
110 AnnotateMutexIsUsedAsCondVar(__FILE__, __LINE__, mu) | |
111 | |
112 // ------------------------------------------------------------- | |
113 // Annotations useful when defining memory allocators, or when memory that | |
114 // was protected in one way starts to be protected in another. | |
115 | |
116 // Report that a new memory at "address" of size "size" has been allocated. | |
117 // This might be used when the memory has been retrieved from a free list and | |
118 // is about to be reused, or when a the locking discipline for a variable | |
119 // changes. | |
120 #define ANNOTATE_NEW_MEMORY(address, size) \ | |
121 AnnotateNewMemory(__FILE__, __LINE__, address, size) | |
122 | |
123 // ------------------------------------------------------------- | |
124 // Annotations useful when defining FIFO queues that transfer data between | |
125 // threads. | |
126 | |
127 // Report that the producer-consumer queue (such as ProducerConsumerQueue) at | |
128 // address "pcq" has been created. The ANNOTATE_PCQ_* annotations | |
129 // should be used only for FIFO queues. For non-FIFO queues use | |
130 // ANNOTATE_HAPPENS_BEFORE (for put) and ANNOTATE_HAPPENS_AFTER (for get). | |
131 #define ANNOTATE_PCQ_CREATE(pcq) \ | |
132 AnnotatePCQCreate(__FILE__, __LINE__, pcq) | |
133 | |
134 // Report that the queue at address "pcq" is about to be destroyed. | |
135 #define ANNOTATE_PCQ_DESTROY(pcq) \ | |
136 AnnotatePCQDestroy(__FILE__, __LINE__, pcq) | |
137 | |
138 // Report that we are about to put an element into a FIFO queue at address | |
139 // "pcq". | |
140 #define ANNOTATE_PCQ_PUT(pcq) \ | |
141 AnnotatePCQPut(__FILE__, __LINE__, pcq) | |
142 | |
143 // Report that we've just got an element from a FIFO queue at address "pcq". | |
144 #define ANNOTATE_PCQ_GET(pcq) \ | |
145 AnnotatePCQGet(__FILE__, __LINE__, pcq) | |
146 | |
147 // ------------------------------------------------------------- | |
148 // Annotations that suppress errors. It is usually better to express the | |
149 // program's synchronization using the other annotations, but these can | |
150 // be used when all else fails. | |
151 | |
152 // Report that we may have a benign race on at "address". | |
153 // Insert at the point where "address" has been allocated, preferably close | |
154 // to the point where the race happens. | |
155 // See also ANNOTATE_BENIGN_RACE_STATIC. | |
156 #define ANNOTATE_BENIGN_RACE(address, description) \ | |
157 AnnotateBenignRace(__FILE__, __LINE__, address, description) | |
158 | |
159 // Request the analysis tool to ignore all reads in the current thread | |
160 // until ANNOTATE_IGNORE_READS_END is called. | |
161 // Useful to ignore intentional racey reads, while still checking | |
162 // other reads and all writes. | |
163 // See also ANNOTATE_UNPROTECTED_READ. | |
164 #define ANNOTATE_IGNORE_READS_BEGIN() \ | |
165 AnnotateIgnoreReadsBegin(__FILE__, __LINE__) | |
166 | |
167 // Stop ignoring reads. | |
168 #define ANNOTATE_IGNORE_READS_END() \ | |
169 AnnotateIgnoreReadsEnd(__FILE__, __LINE__) | |
170 | |
171 // Similar to ANNOTATE_IGNORE_READS_BEGIN, but ignore writes. | |
172 #define ANNOTATE_IGNORE_WRITES_BEGIN() \ | |
173 AnnotateIgnoreWritesBegin(__FILE__, __LINE__) | |
174 | |
175 // Stop ignoring writes. | |
176 #define ANNOTATE_IGNORE_WRITES_END() \ | |
177 AnnotateIgnoreWritesEnd(__FILE__, __LINE__) | |
178 | |
179 // Start ignoring all memory accesses (reads and writes). | |
180 #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \ | |
181 do {\ | |
182 ANNOTATE_IGNORE_READS_BEGIN();\ | |
183 ANNOTATE_IGNORE_WRITES_BEGIN();\ | |
184 }while(0)\ | |
185 | |
186 // Stop ignoring all memory accesses. | |
187 #define ANNOTATE_IGNORE_READS_AND_WRITES_END() \ | |
188 do {\ | |
189 ANNOTATE_IGNORE_WRITES_END();\ | |
190 ANNOTATE_IGNORE_READS_END();\ | |
191 }while(0)\ | |
192 | |
193 // ------------------------------------------------------------- | |
194 // Annotations useful for debugging. | |
195 | |
196 // Request to trace every access to "address". | |
197 #define ANNOTATE_TRACE_MEMORY(address) \ | |
198 AnnotateTraceMemory(__FILE__, __LINE__, address) | |
199 | |
200 // Report the current thread name to a race detector. | |
201 #define ANNOTATE_THREAD_NAME(name) \ | |
202 AnnotateThreadName(__FILE__, __LINE__, name) | |
203 | |
204 // ------------------------------------------------------------- | |
205 // Annotations useful when implementing locks. They are not | |
206 // normally needed by modules that merely use locks. | |
207 // The "lock" argument is a pointer to the lock object. | |
208 | |
209 // Report that a lock has been created at address "lock". | |
210 #define ANNOTATE_RWLOCK_CREATE(lock) \ | |
211 AnnotateRWLockCreate(__FILE__, __LINE__, lock) | |
212 | |
213 // Report that the lock at address "lock" is about to be destroyed. | |
214 #define ANNOTATE_RWLOCK_DESTROY(lock) \ | |
215 AnnotateRWLockDestroy(__FILE__, __LINE__, lock) | |
216 | |
217 // Report that the lock at address "lock" has been acquired. | |
218 // is_w=1 for writer lock, is_w=0 for reader lock. | |
219 #define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) \ | |
220 AnnotateRWLockAcquired(__FILE__, __LINE__, lock, is_w) | |
221 | |
222 // Report that the lock at address "lock" is about to be released. | |
223 #define ANNOTATE_RWLOCK_RELEASED(lock, is_w) \ | |
224 AnnotateRWLockReleased(__FILE__, __LINE__, lock, is_w) | |
225 | |
226 // ------------------------------------------------------------- | |
227 // Annotations useful for testing race detectors. | |
228 | |
229 // Report that we expect a race on the variable at "address". | |
230 // Use only in unit tests for a race detector. | |
231 #define ANNOTATE_EXPECT_RACE(address, description) \ | |
232 AnnotateExpectRace(__FILE__, __LINE__, address, description) | |
233 | |
234 // A no-op. Insert where you like to test the interceptors. | |
235 #define ANNOTATE_NO_OP(arg) \ | |
236 AnnotateNoOp(__FILE__, __LINE__, arg) | |
237 | |
238 // Use the macros above rather than using these functions directly. | |
239 extern "C" void AnnotateRWLockCreate(const char *file, int line, | |
240 const volatile void *lock); | |
241 extern "C" void AnnotateRWLockDestroy(const char *file, int line, | |
242 const volatile void *lock); | |
243 extern "C" void AnnotateRWLockAcquired(const char *file, int line, | |
244 const volatile void *lock, long is_w); | |
245 extern "C" void AnnotateRWLockReleased(const char *file, int line, | |
246 const volatile void *lock, long is_w); | |
247 extern "C" void AnnotateCondVarWait(const char *file, int line, | |
248 const volatile void *cv, | |
249 const volatile void *lock); | |
250 extern "C" void AnnotateCondVarSignal(const char *file, int line, | |
251 const volatile void *cv); | |
252 extern "C" void AnnotateCondVarSignalAll(const char *file, int line, | |
253 const volatile void *cv); | |
254 extern "C" void AnnotatePublishMemoryRange(const char *file, int line, | |
255 const volatile void *address, | |
256 long size); | |
257 extern "C" void AnnotatePCQCreate(const char *file, int line, | |
258 const volatile void *pcq); | |
259 extern "C" void AnnotatePCQDestroy(const char *file, int line, | |
260 const volatile void *pcq); | |
261 extern "C" void AnnotatePCQPut(const char *file, int line, | |
262 const volatile void *pcq); | |
263 extern "C" void AnnotatePCQGet(const char *file, int line, | |
264 const volatile void *pcq); | |
265 extern "C" void AnnotateNewMemory(const char *file, int line, | |
266 const volatile void *address, | |
267 long size); | |
268 extern "C" void AnnotateExpectRace(const char *file, int line, | |
269 const volatile void *address, | |
270 const char *description); | |
271 extern "C" void AnnotateBenignRace(const char *file, int line, | |
272 const volatile void *address, | |
273 const char *description); | |
274 extern "C" void AnnotateMutexIsUsedAsCondVar(const char *file, int line, | |
275 const volatile void *mu); | |
276 extern "C" void AnnotateTraceMemory(const char *file, int line, | |
277 const volatile void *arg); | |
278 extern "C" void AnnotateThreadName(const char *file, int line, | |
279 const char *name); | |
280 extern "C" void AnnotateIgnoreReadsBegin(const char *file, int line); | |
281 extern "C" void AnnotateIgnoreReadsEnd(const char *file, int line); | |
282 extern "C" void AnnotateIgnoreWritesBegin(const char *file, int line); | |
283 extern "C" void AnnotateIgnoreWritesEnd(const char *file, int line); | |
284 extern "C" void AnnotateNoOp(const char *file, int line, | |
285 const volatile void *arg); | |
286 | |
287 // ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racey reads. | |
288 // | |
289 // Instead of doing | |
290 // ANNOTATE_IGNORE_READS_BEGIN(); | |
291 // ... = x; | |
292 // ANNOTATE_IGNORE_READS_END(); | |
293 // one can use | |
294 // ... = ANNOTATE_UNPROTECTED_READ(x); | |
295 template <class T> | |
296 inline T ANNOTATE_UNPROTECTED_READ(const volatile T &x) { | |
297 ANNOTATE_IGNORE_READS_BEGIN(); | |
298 T res = x; | |
299 ANNOTATE_IGNORE_READS_END(); | |
300 return res; | |
301 } | |
302 | |
303 // Apply ANNOTATE_BENIGN_RACE to a static variable. | |
304 #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description) \ | |
305 namespace { \ | |
306 class static_var ## _annotator { \ | |
307 public: \ | |
308 static_var ## _annotator() { \ | |
309 ANNOTATE_BENIGN_RACE(&static_var, \ | |
310 # static_var ": " description); \ | |
311 } \ | |
312 }; \ | |
313 static static_var ## _annotator the ## static_var ## _annotator;\ | |
314 } | |
315 | |
316 #else | |
317 // NVALGRIND is defined, empty macros. | |
318 | |
319 #define ANNOTATE_RWLOCK_CREATE(lock) // empty | |
320 #define ANNOTATE_RWLOCK_DESTROY(lock) // empty | |
321 #define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) // empty | |
322 #define ANNOTATE_RWLOCK_RELEASED(lock, is_w) // empty | |
323 #define ANNOTATE_CONDVAR_LOCK_WAIT(cv, lock) // empty | |
324 #define ANNOTATE_CONDVAR_WAIT(cv) // empty | |
325 #define ANNOTATE_CONDVAR_SIGNAL(cv) // empty | |
326 #define ANNOTATE_CONDVAR_SIGNAL_ALL(cv) // empty | |
327 #define ANNOTATE_HAPPENS_BEFORE(obj) // empty | |
328 #define ANNOTATE_HAPPENS_AFTER(obj) // empty | |
329 #define ANNOTATE_PUBLISH_MEMORY_RANGE(address, size) // empty | |
330 #define ANNOTATE_PUBLISH_OBJECT(address) // empty | |
331 #define ANNOTATE_PCQ_CREATE(pcq) // empty | |
332 #define ANNOTATE_PCQ_DESTROY(pcq) // empty | |
333 #define ANNOTATE_PCQ_PUT(pcq) // empty | |
334 #define ANNOTATE_PCQ_GET(pcq) // empty | |
335 #define ANNOTATE_NEW_MEMORY(address, size) // empty | |
336 #define ANNOTATE_EXPECT_RACE(address, description) // empty | |
337 #define ANNOTATE_BENIGN_RACE(address, description) // empty | |
338 #define ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mu) // empty | |
339 #define ANNOTATE_TRACE_MEMORY(arg) // empty | |
340 #define ANNOTATE_THREAD_NAME(name) // empty | |
341 #define ANNOTATE_IGNORE_READS_BEGIN() // empty | |
342 #define ANNOTATE_IGNORE_READS_END() // empty | |
343 #define ANNOTATE_IGNORE_WRITES_BEGIN() // empty | |
344 #define ANNOTATE_IGNORE_WRITES_END() // empty | |
345 #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() // empty | |
346 #define ANNOTATE_IGNORE_READS_AND_WRITES_END() // empty | |
347 #define ANNOTATE_NO_OP(arg) // empty | |
348 #define ANNOTATE_UNPROTECTED_READ(x) (x) | |
349 #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description) // empty | |
350 | |
351 #endif // NVALGRIND | |
352 | |
353 // Return non-zero value if running under valgrind. | |
354 extern "C" int RunningOnValgrind(); | |
355 | |
356 #endif // BASE_DYNAMIC_ANNOTATIONS_H_ | |
OLD | NEW |