dynamic_annotations.h
Go to the documentation of this file.
00001 /*
00002  *  Copyright 2017 The Abseil Authors.
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *      https://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 /* This file defines dynamic annotations for use with dynamic analysis
00017    tool such as valgrind, PIN, etc.
00018 
00019    Dynamic annotation is a source code annotation that affects
00020    the generated code (that is, the annotation is not a comment).
00021    Each such annotation is attached to a particular
00022    instruction and/or to a particular object (address) in the program.
00023 
00024    The annotations that should be used by users are macros in all upper-case
00025    (e.g., ANNOTATE_THREAD_NAME).
00026 
00027    Actual implementation of these macros may differ depending on the
00028    dynamic analysis tool being used.
00029 
00030    This file supports the following configurations:
00031    - Dynamic Annotations enabled (with static thread-safety warnings disabled).
00032      In this case, macros expand to functions implemented by Thread Sanitizer,
00033      when building with TSan. When not provided an external implementation,
00034      dynamic_annotations.cc provides no-op implementations.
00035 
00036    - Static Clang thread-safety warnings enabled.
00037      When building with a Clang compiler that supports thread-safety warnings,
00038      a subset of annotations can be statically-checked at compile-time. We
00039      expand these macros to static-inline functions that can be analyzed for
00040      thread-safety, but afterwards elided when building the final binary.
00041 
00042    - All annotations are disabled.
00043      If neither Dynamic Annotations nor Clang thread-safety warnings are
00044      enabled, then all annotation-macros expand to empty. */
00045 
00046 #ifndef ABSL_BASE_DYNAMIC_ANNOTATIONS_H_
00047 #define ABSL_BASE_DYNAMIC_ANNOTATIONS_H_
00048 
00049 #ifndef DYNAMIC_ANNOTATIONS_ENABLED
00050 # define DYNAMIC_ANNOTATIONS_ENABLED 0
00051 #endif
00052 
00053 #if DYNAMIC_ANNOTATIONS_ENABLED != 0
00054 
00055   /* -------------------------------------------------------------
00056      Annotations that suppress errors.  It is usually better to express the
00057      program's synchronization using the other annotations, but these can
00058      be used when all else fails. */
00059 
00060   /* Report that we may have a benign race at "pointer", with size
00061      "sizeof(*(pointer))". "pointer" must be a non-void* pointer.  Insert at the
00062      point where "pointer" has been allocated, preferably close to the point
00063      where the race happens.  See also ANNOTATE_BENIGN_RACE_STATIC. */
00064   #define ANNOTATE_BENIGN_RACE(pointer, description) \
00065     AnnotateBenignRaceSized(__FILE__, __LINE__, pointer, \
00066                             sizeof(*(pointer)), description)
00067 
00068   /* Same as ANNOTATE_BENIGN_RACE(address, description), but applies to
00069      the memory range [address, address+size). */
00070   #define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) \
00071     AnnotateBenignRaceSized(__FILE__, __LINE__, address, size, description)
00072 
00073   /* Enable (enable!=0) or disable (enable==0) race detection for all threads.
00074      This annotation could be useful if you want to skip expensive race analysis
00075      during some period of program execution, e.g. during initialization. */
00076   #define ANNOTATE_ENABLE_RACE_DETECTION(enable) \
00077     AnnotateEnableRaceDetection(__FILE__, __LINE__, enable)
00078 
00079   /* -------------------------------------------------------------
00080      Annotations useful for debugging. */
00081 
00082   /* Report the current thread name to a race detector. */
00083   #define ANNOTATE_THREAD_NAME(name) \
00084     AnnotateThreadName(__FILE__, __LINE__, name)
00085 
00086   /* -------------------------------------------------------------
00087      Annotations useful when implementing locks.  They are not
00088      normally needed by modules that merely use locks.
00089      The "lock" argument is a pointer to the lock object. */
00090 
00091   /* Report that a lock has been created at address "lock". */
00092   #define ANNOTATE_RWLOCK_CREATE(lock) \
00093     AnnotateRWLockCreate(__FILE__, __LINE__, lock)
00094 
00095   /* Report that a linker initialized lock has been created at address "lock".
00096    */
00097 #ifdef THREAD_SANITIZER
00098   #define ANNOTATE_RWLOCK_CREATE_STATIC(lock) \
00099     AnnotateRWLockCreateStatic(__FILE__, __LINE__, lock)
00100 #else
00101   #define ANNOTATE_RWLOCK_CREATE_STATIC(lock) ANNOTATE_RWLOCK_CREATE(lock)
00102 #endif
00103 
00104   /* Report that the lock at address "lock" is about to be destroyed. */
00105   #define ANNOTATE_RWLOCK_DESTROY(lock) \
00106     AnnotateRWLockDestroy(__FILE__, __LINE__, lock)
00107 
00108   /* Report that the lock at address "lock" has been acquired.
00109      is_w=1 for writer lock, is_w=0 for reader lock. */
00110   #define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) \
00111     AnnotateRWLockAcquired(__FILE__, __LINE__, lock, is_w)
00112 
00113   /* Report that the lock at address "lock" is about to be released. */
00114   #define ANNOTATE_RWLOCK_RELEASED(lock, is_w) \
00115     AnnotateRWLockReleased(__FILE__, __LINE__, lock, is_w)
00116 
00117 #else  /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */
00118 
00119   #define ANNOTATE_RWLOCK_CREATE(lock) /* empty */
00120   #define ANNOTATE_RWLOCK_CREATE_STATIC(lock) /* empty */
00121   #define ANNOTATE_RWLOCK_DESTROY(lock) /* empty */
00122   #define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) /* empty */
00123   #define ANNOTATE_RWLOCK_RELEASED(lock, is_w) /* empty */
00124   #define ANNOTATE_BENIGN_RACE(address, description) /* empty */
00125   #define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) /* empty */
00126   #define ANNOTATE_THREAD_NAME(name) /* empty */
00127   #define ANNOTATE_ENABLE_RACE_DETECTION(enable) /* empty */
00128 
00129 #endif  /* DYNAMIC_ANNOTATIONS_ENABLED */
00130 
00131 /* These annotations are also made available to LLVM's Memory Sanitizer */
00132 #if DYNAMIC_ANNOTATIONS_ENABLED == 1 || defined(MEMORY_SANITIZER)
00133   #define ANNOTATE_MEMORY_IS_INITIALIZED(address, size) \
00134     AnnotateMemoryIsInitialized(__FILE__, __LINE__, address, size)
00135 
00136   #define ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) \
00137     AnnotateMemoryIsUninitialized(__FILE__, __LINE__, address, size)
00138 #else
00139   #define ANNOTATE_MEMORY_IS_INITIALIZED(address, size) /* empty */
00140   #define ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) /* empty */
00141 #endif  /* DYNAMIC_ANNOTATIONS_ENABLED || MEMORY_SANITIZER */
00142 
00143 /* TODO(delesley) -- Replace __CLANG_SUPPORT_DYN_ANNOTATION__ with the
00144    appropriate feature ID. */
00145 #if defined(__clang__) && (!defined(SWIG)) \
00146     && defined(__CLANG_SUPPORT_DYN_ANNOTATION__)
00147 
00148   #if DYNAMIC_ANNOTATIONS_ENABLED == 0
00149     #define ANNOTALYSIS_ENABLED
00150   #endif
00151 
00152   /* When running in opt-mode, GCC will issue a warning, if these attributes are
00153      compiled. Only include them when compiling using Clang. */
00154   #define ATTRIBUTE_IGNORE_READS_BEGIN \
00155       __attribute((exclusive_lock_function("*")))
00156   #define ATTRIBUTE_IGNORE_READS_END \
00157       __attribute((unlock_function("*")))
00158 #else
00159   #define ATTRIBUTE_IGNORE_READS_BEGIN  /* empty */
00160   #define ATTRIBUTE_IGNORE_READS_END  /* empty */
00161 #endif  /* defined(__clang__) && ... */
00162 
00163 #if (DYNAMIC_ANNOTATIONS_ENABLED != 0) || defined(ANNOTALYSIS_ENABLED)
00164   #define ANNOTATIONS_ENABLED
00165 #endif
00166 
00167 #if (DYNAMIC_ANNOTATIONS_ENABLED != 0)
00168 
00169   /* Request the analysis tool to ignore all reads in the current thread
00170      until ANNOTATE_IGNORE_READS_END is called.
00171      Useful to ignore intentional racey reads, while still checking
00172      other reads and all writes.
00173      See also ANNOTATE_UNPROTECTED_READ. */
00174   #define ANNOTATE_IGNORE_READS_BEGIN() \
00175     AnnotateIgnoreReadsBegin(__FILE__, __LINE__)
00176 
00177   /* Stop ignoring reads. */
00178   #define ANNOTATE_IGNORE_READS_END() \
00179     AnnotateIgnoreReadsEnd(__FILE__, __LINE__)
00180 
00181   /* Similar to ANNOTATE_IGNORE_READS_BEGIN, but ignore writes instead. */
00182   #define ANNOTATE_IGNORE_WRITES_BEGIN() \
00183     AnnotateIgnoreWritesBegin(__FILE__, __LINE__)
00184 
00185   /* Stop ignoring writes. */
00186   #define ANNOTATE_IGNORE_WRITES_END() \
00187     AnnotateIgnoreWritesEnd(__FILE__, __LINE__)
00188 
00189 /* Clang provides limited support for static thread-safety analysis
00190    through a feature called Annotalysis. We configure macro-definitions
00191    according to whether Annotalysis support is available. */
00192 #elif defined(ANNOTALYSIS_ENABLED)
00193 
00194   #define ANNOTATE_IGNORE_READS_BEGIN() \
00195     StaticAnnotateIgnoreReadsBegin(__FILE__, __LINE__)
00196 
00197   #define ANNOTATE_IGNORE_READS_END() \
00198     StaticAnnotateIgnoreReadsEnd(__FILE__, __LINE__)
00199 
00200   #define ANNOTATE_IGNORE_WRITES_BEGIN() \
00201     StaticAnnotateIgnoreWritesBegin(__FILE__, __LINE__)
00202 
00203   #define ANNOTATE_IGNORE_WRITES_END() \
00204     StaticAnnotateIgnoreWritesEnd(__FILE__, __LINE__)
00205 
00206 #else
00207   #define ANNOTATE_IGNORE_READS_BEGIN()  /* empty */
00208   #define ANNOTATE_IGNORE_READS_END()  /* empty */
00209   #define ANNOTATE_IGNORE_WRITES_BEGIN()  /* empty */
00210   #define ANNOTATE_IGNORE_WRITES_END()  /* empty */
00211 #endif
00212 
00213 /* Implement the ANNOTATE_IGNORE_READS_AND_WRITES_* annotations using the more
00214    primitive annotations defined above. */
00215 #if defined(ANNOTATIONS_ENABLED)
00216 
00217   /* Start ignoring all memory accesses (both reads and writes). */
00218   #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \
00219     do {                                           \
00220       ANNOTATE_IGNORE_READS_BEGIN();               \
00221       ANNOTATE_IGNORE_WRITES_BEGIN();              \
00222     }while (0)
00223 
00224   /* Stop ignoring both reads and writes. */
00225   #define ANNOTATE_IGNORE_READS_AND_WRITES_END()   \
00226     do {                                           \
00227       ANNOTATE_IGNORE_WRITES_END();                \
00228       ANNOTATE_IGNORE_READS_END();                 \
00229     }while (0)
00230 
00231 #else
00232   #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN()  /* empty */
00233   #define ANNOTATE_IGNORE_READS_AND_WRITES_END()  /* empty */
00234 #endif
00235 
00236 /* Use the macros above rather than using these functions directly. */
00237 #include <stddef.h>
00238 #ifdef __cplusplus
00239 extern "C" {
00240 #endif
00241 void AnnotateRWLockCreate(const char *file, int line,
00242                           const volatile void *lock);
00243 void AnnotateRWLockCreateStatic(const char *file, int line,
00244                           const volatile void *lock);
00245 void AnnotateRWLockDestroy(const char *file, int line,
00246                            const volatile void *lock);
00247 void AnnotateRWLockAcquired(const char *file, int line,
00248                             const volatile void *lock, long is_w);  /* NOLINT */
00249 void AnnotateRWLockReleased(const char *file, int line,
00250                             const volatile void *lock, long is_w);  /* NOLINT */
00251 void AnnotateBenignRace(const char *file, int line,
00252                         const volatile void *address,
00253                         const char *description);
00254 void AnnotateBenignRaceSized(const char *file, int line,
00255                         const volatile void *address,
00256                         size_t size,
00257                         const char *description);
00258 void AnnotateThreadName(const char *file, int line,
00259                         const char *name);
00260 void AnnotateEnableRaceDetection(const char *file, int line, int enable);
00261 void AnnotateMemoryIsInitialized(const char *file, int line,
00262                                  const volatile void *mem, size_t size);
00263 void AnnotateMemoryIsUninitialized(const char *file, int line,
00264                                    const volatile void *mem, size_t size);
00265 
00266 /* Annotations expand to these functions, when Dynamic Annotations are enabled.
00267    These functions are either implemented as no-op calls, if no Sanitizer is
00268    attached, or provided with externally-linked implementations by a library
00269    like ThreadSanitizer. */
00270 void AnnotateIgnoreReadsBegin(const char *file, int line)
00271     ATTRIBUTE_IGNORE_READS_BEGIN;
00272 void AnnotateIgnoreReadsEnd(const char *file, int line)
00273     ATTRIBUTE_IGNORE_READS_END;
00274 void AnnotateIgnoreWritesBegin(const char *file, int line);
00275 void AnnotateIgnoreWritesEnd(const char *file, int line);
00276 
00277 #if defined(ANNOTALYSIS_ENABLED)
00278 /* When Annotalysis is enabled without Dynamic Annotations, the use of
00279    static-inline functions allows the annotations to be read at compile-time,
00280    while still letting the compiler elide the functions from the final build.
00281 
00282    TODO(delesley) -- The exclusive lock here ignores writes as well, but
00283    allows IGNORE_READS_AND_WRITES to work properly. */
00284 #pragma GCC diagnostic push
00285 #pragma GCC diagnostic ignored "-Wunused-function"
00286 static inline void StaticAnnotateIgnoreReadsBegin(const char *file, int line)
00287     ATTRIBUTE_IGNORE_READS_BEGIN { (void)file; (void)line; }
00288 static inline void StaticAnnotateIgnoreReadsEnd(const char *file, int line)
00289     ATTRIBUTE_IGNORE_READS_END { (void)file; (void)line; }
00290 static inline void StaticAnnotateIgnoreWritesBegin(
00291     const char *file, int line) { (void)file; (void)line; }
00292 static inline void StaticAnnotateIgnoreWritesEnd(
00293     const char *file, int line) { (void)file; (void)line; }
00294 #pragma GCC diagnostic pop
00295 #endif
00296 
00297 /* Return non-zero value if running under valgrind.
00298 
00299   If "valgrind.h" is included into dynamic_annotations.cc,
00300   the regular valgrind mechanism will be used.
00301   See http://valgrind.org/docs/manual/manual-core-adv.html about
00302   RUNNING_ON_VALGRIND and other valgrind "client requests".
00303   The file "valgrind.h" may be obtained by doing
00304      svn co svn://svn.valgrind.org/valgrind/trunk/include
00305 
00306   If for some reason you can't use "valgrind.h" or want to fake valgrind,
00307   there are two ways to make this function return non-zero:
00308     - Use environment variable: export RUNNING_ON_VALGRIND=1
00309     - Make your tool intercept the function RunningOnValgrind() and
00310       change its return value.
00311  */
00312 int RunningOnValgrind(void);
00313 
00314 /* ValgrindSlowdown returns:
00315     * 1.0, if (RunningOnValgrind() == 0)
00316     * 50.0, if (RunningOnValgrind() != 0 && getenv("VALGRIND_SLOWDOWN") == NULL)
00317     * atof(getenv("VALGRIND_SLOWDOWN")) otherwise
00318    This function can be used to scale timeout values:
00319    EXAMPLE:
00320    for (;;) {
00321      DoExpensiveBackgroundTask();
00322      SleepForSeconds(5 * ValgrindSlowdown());
00323    }
00324  */
00325 double ValgrindSlowdown(void);
00326 
00327 #ifdef __cplusplus
00328 }
00329 #endif
00330 
00331 /* ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racey reads.
00332 
00333      Instead of doing
00334         ANNOTATE_IGNORE_READS_BEGIN();
00335         ... = x;
00336         ANNOTATE_IGNORE_READS_END();
00337      one can use
00338         ... = ANNOTATE_UNPROTECTED_READ(x); */
00339 #if defined(__cplusplus) && defined(ANNOTATIONS_ENABLED)
00340 template <typename T>
00341 inline T ANNOTATE_UNPROTECTED_READ(const volatile T &x) { /* NOLINT */
00342   ANNOTATE_IGNORE_READS_BEGIN();
00343   T res = x;
00344   ANNOTATE_IGNORE_READS_END();
00345   return res;
00346   }
00347 #else
00348   #define ANNOTATE_UNPROTECTED_READ(x) (x)
00349 #endif
00350 
00351 #if DYNAMIC_ANNOTATIONS_ENABLED != 0 && defined(__cplusplus)
00352   /* Apply ANNOTATE_BENIGN_RACE_SIZED to a static variable. */
00353   #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description)        \
00354     namespace {                                                       \
00355       class static_var ## _annotator {                                \
00356        public:                                                        \
00357         static_var ## _annotator() {                                  \
00358           ANNOTATE_BENIGN_RACE_SIZED(&static_var,                     \
00359                                       sizeof(static_var),             \
00360             # static_var ": " description);                           \
00361         }                                                             \
00362       };                                                              \
00363       static static_var ## _annotator the ## static_var ## _annotator;\
00364     }  // namespace
00365 #else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */
00366   #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description)  /* empty */
00367 #endif /* DYNAMIC_ANNOTATIONS_ENABLED */
00368 
00369 #ifdef ADDRESS_SANITIZER
00370 /* Describe the current state of a contiguous container such as e.g.
00371  * std::vector or std::string. For more details see
00372  * sanitizer/common_interface_defs.h, which is provided by the compiler. */
00373 #include <sanitizer/common_interface_defs.h>
00374 #define ANNOTATE_CONTIGUOUS_CONTAINER(beg, end, old_mid, new_mid) \
00375   __sanitizer_annotate_contiguous_container(beg, end, old_mid, new_mid)
00376 #define ADDRESS_SANITIZER_REDZONE(name)         \
00377   struct { char x[8] __attribute__ ((aligned (8))); } name
00378 #else
00379 #define ANNOTATE_CONTIGUOUS_CONTAINER(beg, end, old_mid, new_mid)
00380 #define ADDRESS_SANITIZER_REDZONE(name) static_assert(true, "")
00381 #endif  // ADDRESS_SANITIZER
00382 
00383 /* Undefine the macros intended only in this file. */
00384 #undef ANNOTALYSIS_ENABLED
00385 #undef ANNOTATIONS_ENABLED
00386 #undef ATTRIBUTE_IGNORE_READS_BEGIN
00387 #undef ATTRIBUTE_IGNORE_READS_END
00388 
00389 #endif  /* ABSL_BASE_DYNAMIC_ANNOTATIONS_H_ */


abseil_cpp
Author(s):
autogenerated on Wed Jun 19 2019 19:42:14