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 "base/third_party/dynamic_annotations/dynamic_annotations.h" 39 40 #ifdef __GNUC__ 41 /* valgrind.h uses gcc extensions so it won't build with other compilers */ 42 # include "base/third_party/valgrind/valgrind.h" 43 #endif 44 45 /* Compiler-based ThreadSanitizer defines 46 DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL = 1 47 and provides its own definitions of the functions. */ 48 49 #ifndef DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL 50 # define DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL 0 51 #endif 52 53 /* Each function is empty and called (via a macro) only in debug mode. 54 The arguments are captured by dynamic tools at runtime. */ 55 56 #if DYNAMIC_ANNOTATIONS_ENABLED == 1 \ 57 && DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL == 0 58 59 /* Identical code folding(-Wl,--icf=all) countermeasures. 60 This makes all Annotate* functions different, which prevents the linker from 61 folding them. */ 62 #ifdef __COUNTER__ 63 #define DYNAMIC_ANNOTATIONS_IMPL \ 64 volatile unsigned short lineno = (__LINE__ << 8) + __COUNTER__; (void)lineno; 65 #else 66 #define DYNAMIC_ANNOTATIONS_IMPL \ 67 volatile unsigned short lineno = (__LINE__ << 8); (void)lineno; 68 #endif 69 70 /* WARNING: always add new annotations to the end of the list. 71 Otherwise, lineno (see above) numbers for different Annotate* functions may 72 conflict. */ 73 void DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockCreate)( 74 const char *file, int line, const volatile void *lock) 75 {DYNAMIC_ANNOTATIONS_IMPL} 76 77 void DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockDestroy)( 78 const char *file, int line, const volatile void *lock) 79 {DYNAMIC_ANNOTATIONS_IMPL} 80 81 void DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockAcquired)( 82 const char *file, int line, const volatile void *lock, long is_w) 83 {DYNAMIC_ANNOTATIONS_IMPL} 84 85 void DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockReleased)( 86 const char *file, int line, const volatile void *lock, long is_w) 87 {DYNAMIC_ANNOTATIONS_IMPL} 88 89 void DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierInit)( 90 const char *file, int line, const volatile void *barrier, long count, 91 long reinitialization_allowed) 92 {DYNAMIC_ANNOTATIONS_IMPL} 93 94 void DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierWaitBefore)( 95 const char *file, int line, const volatile void *barrier) 96 {DYNAMIC_ANNOTATIONS_IMPL} 97 98 void DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierWaitAfter)( 99 const char *file, int line, const volatile void *barrier) 100 {DYNAMIC_ANNOTATIONS_IMPL} 101 102 void DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierDestroy)( 103 const char *file, int line, const volatile void *barrier) 104 {DYNAMIC_ANNOTATIONS_IMPL} 105 106 void DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarWait)( 107 const char *file, int line, const volatile void *cv, 108 const volatile void *lock) 109 {DYNAMIC_ANNOTATIONS_IMPL} 110 111 void DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarSignal)( 112 const char *file, int line, const volatile void *cv) 113 {DYNAMIC_ANNOTATIONS_IMPL} 114 115 void DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarSignalAll)( 116 const char *file, int line, const volatile void *cv) 117 {DYNAMIC_ANNOTATIONS_IMPL} 118 119 void DYNAMIC_ANNOTATIONS_NAME(AnnotateHappensBefore)( 120 const char *file, int line, const volatile void *obj) 121 {DYNAMIC_ANNOTATIONS_IMPL}; 122 123 void DYNAMIC_ANNOTATIONS_NAME(AnnotateHappensAfter)( 124 const char *file, int line, const volatile void *obj) 125 {DYNAMIC_ANNOTATIONS_IMPL}; 126 127 void DYNAMIC_ANNOTATIONS_NAME(AnnotatePublishMemoryRange)( 128 const char *file, int line, const volatile void *address, long size) 129 {DYNAMIC_ANNOTATIONS_IMPL} 130 131 void DYNAMIC_ANNOTATIONS_NAME(AnnotateUnpublishMemoryRange)( 132 const char *file, int line, const volatile void *address, long size) 133 {DYNAMIC_ANNOTATIONS_IMPL} 134 135 void DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQCreate)( 136 const char *file, int line, const volatile void *pcq) 137 {DYNAMIC_ANNOTATIONS_IMPL} 138 139 void DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQDestroy)( 140 const char *file, int line, const volatile void *pcq) 141 {DYNAMIC_ANNOTATIONS_IMPL} 142 143 void DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQPut)( 144 const char *file, int line, const volatile void *pcq) 145 {DYNAMIC_ANNOTATIONS_IMPL} 146 147 void DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQGet)( 148 const char *file, int line, const volatile void *pcq) 149 {DYNAMIC_ANNOTATIONS_IMPL} 150 151 void DYNAMIC_ANNOTATIONS_NAME(AnnotateNewMemory)( 152 const char *file, int line, const volatile void *mem, long size) 153 {DYNAMIC_ANNOTATIONS_IMPL} 154 155 void DYNAMIC_ANNOTATIONS_NAME(AnnotateExpectRace)( 156 const char *file, int line, const volatile void *mem, 157 const char *description) 158 {DYNAMIC_ANNOTATIONS_IMPL} 159 160 void DYNAMIC_ANNOTATIONS_NAME(AnnotateFlushExpectedRaces)( 161 const char *file, int line) 162 {DYNAMIC_ANNOTATIONS_IMPL} 163 164 void DYNAMIC_ANNOTATIONS_NAME(AnnotateBenignRace)( 165 const char *file, int line, const volatile void *mem, 166 const char *description) 167 {DYNAMIC_ANNOTATIONS_IMPL} 168 169 void DYNAMIC_ANNOTATIONS_NAME(AnnotateBenignRaceSized)( 170 const char *file, int line, const volatile void *mem, long size, 171 const char *description) 172 {DYNAMIC_ANNOTATIONS_IMPL} 173 174 void DYNAMIC_ANNOTATIONS_NAME(AnnotateMutexIsUsedAsCondVar)( 175 const char *file, int line, const volatile void *mu) 176 {DYNAMIC_ANNOTATIONS_IMPL} 177 178 void DYNAMIC_ANNOTATIONS_NAME(AnnotateMutexIsNotPHB)( 179 const char *file, int line, const volatile void *mu) 180 {DYNAMIC_ANNOTATIONS_IMPL} 181 182 void DYNAMIC_ANNOTATIONS_NAME(AnnotateTraceMemory)( 183 const char *file, int line, const volatile void *arg) 184 {DYNAMIC_ANNOTATIONS_IMPL} 185 186 void DYNAMIC_ANNOTATIONS_NAME(AnnotateThreadName)( 187 const char *file, int line, const char *name) 188 {DYNAMIC_ANNOTATIONS_IMPL} 189 190 void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreReadsBegin)( 191 const char *file, int line) 192 {DYNAMIC_ANNOTATIONS_IMPL} 193 194 void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreReadsEnd)( 195 const char *file, int line) 196 {DYNAMIC_ANNOTATIONS_IMPL} 197 198 void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreWritesBegin)( 199 const char *file, int line) 200 {DYNAMIC_ANNOTATIONS_IMPL} 201 202 void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreWritesEnd)( 203 const char *file, int line) 204 {DYNAMIC_ANNOTATIONS_IMPL} 205 206 void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreSyncBegin)( 207 const char *file, int line) 208 {DYNAMIC_ANNOTATIONS_IMPL} 209 210 void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreSyncEnd)( 211 const char *file, int line) 212 {DYNAMIC_ANNOTATIONS_IMPL} 213 214 void DYNAMIC_ANNOTATIONS_NAME(AnnotateEnableRaceDetection)( 215 const char *file, int line, int enable) 216 {DYNAMIC_ANNOTATIONS_IMPL} 217 218 void DYNAMIC_ANNOTATIONS_NAME(AnnotateNoOp)( 219 const char *file, int line, const volatile void *arg) 220 {DYNAMIC_ANNOTATIONS_IMPL} 221 222 void DYNAMIC_ANNOTATIONS_NAME(AnnotateFlushState)( 223 const char *file, int line) 224 {DYNAMIC_ANNOTATIONS_IMPL} 225 226 #endif /* DYNAMIC_ANNOTATIONS_ENABLED == 1 227 && DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL == 0 */ 228 229 #if DYNAMIC_ANNOTATIONS_PROVIDE_RUNNING_ON_VALGRIND == 1 \ 230 && DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL == 0 231 static int GetRunningOnValgrind(void) { 232 #ifdef RUNNING_ON_VALGRIND 233 if (RUNNING_ON_VALGRIND) return 1; 234 #endif 235 236 #ifndef _MSC_VER 237 char *running_on_valgrind_str = getenv("RUNNING_ON_VALGRIND"); 238 if (running_on_valgrind_str) { 239 return strcmp(running_on_valgrind_str, "0") != 0; 240 } 241 #else 242 /* Visual Studio issues warnings if we use getenv, 243 * so we use GetEnvironmentVariableA instead. 244 */ 245 char value[100] = "1"; 246 int res = GetEnvironmentVariableA("RUNNING_ON_VALGRIND", 247 value, sizeof(value)); 248 /* value will remain "1" if res == 0 or res >= sizeof(value). The latter 249 * can happen only if the given value is long, in this case it can't be "0". 250 */ 251 if (res > 0 && strcmp(value, "0") != 0) 252 return 1; 253 #endif 254 return 0; 255 } 256 257 /* See the comments in dynamic_annotations.h */ 258 int RunningOnValgrind(void) { 259 static volatile int running_on_valgrind = -1; 260 /* C doesn't have thread-safe initialization of statics, and we 261 don't want to depend on pthread_once here, so hack it. */ 262 int local_running_on_valgrind = running_on_valgrind; 263 if (local_running_on_valgrind == -1) 264 running_on_valgrind = local_running_on_valgrind = GetRunningOnValgrind(); 265 return local_running_on_valgrind; 266 } 267 268 #endif /* DYNAMIC_ANNOTATIONS_PROVIDE_RUNNING_ON_VALGRIND == 1 269 && DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL == 0 */ 270