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