1 /* Copyright (c) 2011, Google Inc. 2 * All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Neither the name of Google Inc. nor the names of its 11 * contributors may be used to endorse or promote products derived from 12 * this software without specific prior written permission. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 15 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 16 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 17 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 18 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 19 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 20 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #ifdef _MSC_VER 28 # include <windows.h> 29 #endif 30 31 #ifdef __cplusplus 32 # error "This file should be built as pure C to avoid name mangling" 33 #endif 34 35 #include <stdlib.h> 36 #include <string.h> 37 38 #include "dynamic_annotations.h" 39 40 #ifdef __GNUC__ 41 /* valgrind.h uses gcc extensions so it won't build with other compilers */ 42 # include "third_party/valgrind/valgrind.h" 43 #endif 44 45 /* Each function is empty and called (via a macro) only in debug mode. 46 The arguments are captured by dynamic tools at runtime. */ 47 48 #if DYNAMIC_ANNOTATIONS_ENABLED == 1 49 50 /* Identical code folding(-Wl,--icf=all) countermeasures. 51 This makes all Annotate* functions different, which prevents the linker from folding them. */ 52 #ifdef __COUNTER__ 53 #define DYNAMIC_ANNOTATIONS_IMPL volatile short lineno = (__LINE__ << 8) + __COUNTER__; (void)lineno; 54 #else 55 #define DYNAMIC_ANNOTATIONS_IMPL volatile short lineno = (__LINE__ << 8); (void)lineno; 56 #endif 57 58 /* WARNING: always add new annotations to the end of the list. 59 Otherwise, lineno (see above) numbers for different Annotate* functions may conflict. */ 60 void DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockCreate)( 61 const char *file, int line, const volatile void *lock) {DYNAMIC_ANNOTATIONS_IMPL} 62 void DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockDestroy)( 63 const char *file, int line, const volatile void *lock) {DYNAMIC_ANNOTATIONS_IMPL} 64 void DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockAcquired)( 65 const char *file, int line, const volatile void *lock, long is_w) {DYNAMIC_ANNOTATIONS_IMPL} 66 void DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockReleased)( 67 const char *file, int line, const volatile void *lock, long is_w) {DYNAMIC_ANNOTATIONS_IMPL} 68 void DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierInit)( 69 const char *file, int line, const volatile void *barrier, long count, 70 long reinitialization_allowed) {DYNAMIC_ANNOTATIONS_IMPL} 71 void DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierWaitBefore)( 72 const char *file, int line, const volatile void *barrier) {DYNAMIC_ANNOTATIONS_IMPL} 73 void DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierWaitAfter)( 74 const char *file, int line, const volatile void *barrier) {DYNAMIC_ANNOTATIONS_IMPL} 75 void DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierDestroy)( 76 const char *file, int line, const volatile void *barrier) {DYNAMIC_ANNOTATIONS_IMPL} 77 78 void DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarWait)( 79 const char *file, int line, const volatile void *cv, 80 const volatile void *lock) {DYNAMIC_ANNOTATIONS_IMPL} 81 void DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarSignal)( 82 const char *file, int line, const volatile void *cv) {DYNAMIC_ANNOTATIONS_IMPL} 83 void DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarSignalAll)( 84 const char *file, int line, const volatile void *cv) {DYNAMIC_ANNOTATIONS_IMPL} 85 void DYNAMIC_ANNOTATIONS_NAME(AnnotateHappensBefore)( 86 const char *file, int line, const volatile void *obj) {DYNAMIC_ANNOTATIONS_IMPL}; 87 void DYNAMIC_ANNOTATIONS_NAME(AnnotateHappensAfter)( 88 const char *file, int line, const volatile void *obj) {DYNAMIC_ANNOTATIONS_IMPL}; 89 void DYNAMIC_ANNOTATIONS_NAME(AnnotatePublishMemoryRange)( 90 const char *file, int line, const volatile void *address, long size) {DYNAMIC_ANNOTATIONS_IMPL} 91 void DYNAMIC_ANNOTATIONS_NAME(AnnotateUnpublishMemoryRange)( 92 const char *file, int line, const volatile void *address, long size) {DYNAMIC_ANNOTATIONS_IMPL} 93 void DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQCreate)( 94 const char *file, int line, const volatile void *pcq) {DYNAMIC_ANNOTATIONS_IMPL} 95 void DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQDestroy)( 96 const char *file, int line, const volatile void *pcq) {DYNAMIC_ANNOTATIONS_IMPL} 97 void DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQPut)( 98 const char *file, int line, const volatile void *pcq) {DYNAMIC_ANNOTATIONS_IMPL} 99 void DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQGet)( 100 const char *file, int line, const volatile void *pcq) {DYNAMIC_ANNOTATIONS_IMPL} 101 void DYNAMIC_ANNOTATIONS_NAME(AnnotateNewMemory)( 102 const char *file, int line, const volatile void *mem, long size) {DYNAMIC_ANNOTATIONS_IMPL} 103 void DYNAMIC_ANNOTATIONS_NAME(AnnotateExpectRace)( 104 const char *file, int line, const volatile void *mem, 105 const char *description) {DYNAMIC_ANNOTATIONS_IMPL} 106 void DYNAMIC_ANNOTATIONS_NAME(AnnotateFlushExpectedRaces)( 107 const char *file, int line) {DYNAMIC_ANNOTATIONS_IMPL} 108 void DYNAMIC_ANNOTATIONS_NAME(AnnotateBenignRace)( 109 const char *file, int line, const volatile void *mem, 110 const char *description) {DYNAMIC_ANNOTATIONS_IMPL} 111 void DYNAMIC_ANNOTATIONS_NAME(AnnotateBenignRaceSized)( 112 const char *file, int line, const volatile void *mem, long size, 113 const char *description) {DYNAMIC_ANNOTATIONS_IMPL} 114 void DYNAMIC_ANNOTATIONS_NAME(AnnotateMutexIsUsedAsCondVar)( 115 const char *file, int line, const volatile void *mu) {DYNAMIC_ANNOTATIONS_IMPL} 116 void DYNAMIC_ANNOTATIONS_NAME(AnnotateMutexIsNotPHB)( 117 const char *file, int line, const volatile void *mu) {DYNAMIC_ANNOTATIONS_IMPL} 118 void DYNAMIC_ANNOTATIONS_NAME(AnnotateTraceMemory)( 119 const char *file, int line, const volatile void *arg) {DYNAMIC_ANNOTATIONS_IMPL} 120 void DYNAMIC_ANNOTATIONS_NAME(AnnotateThreadName)( 121 const char *file, int line, const char *name) {DYNAMIC_ANNOTATIONS_IMPL} 122 void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreReadsBegin)( 123 const char *file, int line) {DYNAMIC_ANNOTATIONS_IMPL} 124 void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreReadsEnd)( 125 const char *file, int line) {DYNAMIC_ANNOTATIONS_IMPL} 126 void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreWritesBegin)( 127 const char *file, int line) {DYNAMIC_ANNOTATIONS_IMPL} 128 void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreWritesEnd)( 129 const char *file, int line) {DYNAMIC_ANNOTATIONS_IMPL} 130 void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreSyncBegin)( 131 const char *file, int line) {DYNAMIC_ANNOTATIONS_IMPL} 132 void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreSyncEnd)( 133 const char *file, int line) {DYNAMIC_ANNOTATIONS_IMPL} 134 void DYNAMIC_ANNOTATIONS_NAME(AnnotateEnableRaceDetection)( 135 const char *file, int line, int enable) {DYNAMIC_ANNOTATIONS_IMPL} 136 void DYNAMIC_ANNOTATIONS_NAME(AnnotateNoOp)( 137 const char *file, int line, const volatile void *arg) {DYNAMIC_ANNOTATIONS_IMPL} 138 void DYNAMIC_ANNOTATIONS_NAME(AnnotateFlushState)( 139 const char *file, int line) {DYNAMIC_ANNOTATIONS_IMPL} 140 141 #endif /* DYNAMIC_ANNOTATIONS_ENABLED == 1 */ 142 143 #if DYNAMIC_ANNOTATIONS_PROVIDE_RUNNING_ON_VALGRIND == 1 144 static int GetRunningOnValgrind(void) { 145 #ifdef RUNNING_ON_VALGRIND 146 if (RUNNING_ON_VALGRIND) return 1; 147 #endif 148 149 #ifndef _MSC_VER 150 char *running_on_valgrind_str = getenv("RUNNING_ON_VALGRIND"); 151 if (running_on_valgrind_str) { 152 return strcmp(running_on_valgrind_str, "0") != 0; 153 } 154 #else 155 /* Visual Studio issues warnings if we use getenv, 156 * so we use GetEnvironmentVariableA instead. 157 */ 158 char value[100] = "1"; 159 int res = GetEnvironmentVariableA("RUNNING_ON_VALGRIND", 160 value, sizeof(value)); 161 /* value will remain "1" if res == 0 or res >= sizeof(value). The latter 162 * can happen only if the given value is long, in this case it can't be "0". 163 */ 164 if (res > 0 && strcmp(value, "0") != 0) 165 return 1; 166 #endif 167 return 0; 168 } 169 170 /* See the comments in dynamic_annotations.h */ 171 int RunningOnValgrind(void) { 172 static volatile int running_on_valgrind = -1; 173 /* C doesn't have thread-safe initialization of statics, and we 174 don't want to depend on pthread_once here, so hack it. */ 175 int local_running_on_valgrind = running_on_valgrind; 176 if (local_running_on_valgrind == -1) 177 running_on_valgrind = local_running_on_valgrind = GetRunningOnValgrind(); 178 return local_running_on_valgrind; 179 } 180 181 #endif /* DYNAMIC_ANNOTATIONS_PROVIDE_RUNNING_ON_VALGRIND == 1 */ 182