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.
269extern "C" void AnnotateRWLockCreate(const char *file, int line,
270                                     const volatile void *lock);
271extern "C" void AnnotateRWLockDestroy(const char *file, int line,
272                                      const volatile void *lock);
273extern "C" void AnnotateRWLockAcquired(const char *file, int line,
274                                       const volatile void *lock, long is_w);
275extern "C" void AnnotateRWLockReleased(const char *file, int line,
276                                       const volatile void *lock, long is_w);
277extern "C" void AnnotateCondVarWait(const char *file, int line,
278                                    const volatile void *cv,
279                                    const volatile void *lock);
280extern "C" void AnnotateCondVarSignal(const char *file, int line,
281                                      const volatile void *cv);
282extern "C" void AnnotateCondVarSignalAll(const char *file, int line,
283                                         const volatile void *cv);
284extern "C" void AnnotatePublishMemoryRange(const char *file, int line,
285                                           const volatile void *address,
286                                           long size);
287extern "C" void AnnotatePCQCreate(const char *file, int line,
288                                  const volatile void *pcq);
289extern "C" void AnnotatePCQDestroy(const char *file, int line,
290                                   const volatile void *pcq);
291extern "C" void AnnotatePCQPut(const char *file, int line,
292                               const volatile void *pcq);
293extern "C" void AnnotatePCQGet(const char *file, int line,
294                               const volatile void *pcq);
295extern "C" void AnnotateNewMemory(const char *file, int line,
296                                  const volatile void *address,
297                                  long size);
298extern "C" void AnnotateExpectRace(const char *file, int line,
299                                   const volatile void *address,
300                                   const char *description);
301extern "C" void AnnotateBenignRace(const char *file, int line,
302                                   const volatile void *address,
303                                   const char *description);
304extern "C" void AnnotateMutexIsUsedAsCondVar(const char *file, int line,
305                                            const volatile void *mu);
306extern "C" void AnnotateTraceMemory(const char *file, int line,
307                                    const volatile void *arg);
308extern "C" void AnnotateThreadName(const char *file, int line,
309                                   const char *name);
310extern "C" void AnnotateIgnoreReadsBegin(const char *file, int line);
311extern "C" void AnnotateIgnoreReadsEnd(const char *file, int line);
312extern "C" void AnnotateIgnoreWritesBegin(const char *file, int line);
313extern "C" void AnnotateIgnoreWritesEnd(const char *file, int line);
314extern "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>
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.
355extern "C" int RunningOnValgrind();
356
357
358#endif  // BASE_DYNAMIC_ANNOTATIONS_H_
359