| 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 |