Home | History | Annotate | Download | only in base
      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>
    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