1 /* Copyright (c) 2012, 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 /* Each function is empty and called (via a macro) only in debug mode.
41    The arguments are captured by dynamic tools at runtime. */
42 
43 #if DYNAMIC_ANNOTATIONS_ENABLED == 1
44 
45 /* WARNING: because NaCl defines the bodies of all Valgrind interceptors to be
46    empty, compilers that perform Identical Code Folding (ICF) can place them at
47    the exact same memory address, which will cause Valgrind to fail. */
48 
49 // Dynamic annotation functions are stubs in NaCl.
50 #define DYNAMIC_ANNOTATIONS_IMPL
51 
DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockCreate)52 void DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockCreate)(
53     const char *file, int line, const volatile void *lock)
54 {DYNAMIC_ANNOTATIONS_IMPL}
55 
DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockDestroy)56 void DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockDestroy)(
57     const char *file, int line, const volatile void *lock)
58 {DYNAMIC_ANNOTATIONS_IMPL}
59 
DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockAcquired)60 void DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockAcquired)(
61     const char *file, int line, const volatile void *lock, long is_w)
62 {DYNAMIC_ANNOTATIONS_IMPL}
63 
DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockReleased)64 void DYNAMIC_ANNOTATIONS_NAME(AnnotateRWLockReleased)(
65     const char *file, int line, const volatile void *lock, long is_w)
66 {DYNAMIC_ANNOTATIONS_IMPL}
67 
DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierInit)68 void DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierInit)(
69     const char *file, int line, const volatile void *barrier, long count,
70     long reinitialization_allowed)
71 {DYNAMIC_ANNOTATIONS_IMPL}
72 
DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierWaitBefore)73 void DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierWaitBefore)(
74     const char *file, int line, const volatile void *barrier)
75 {DYNAMIC_ANNOTATIONS_IMPL}
76 
DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierWaitAfter)77 void DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierWaitAfter)(
78     const char *file, int line, const volatile void *barrier)
79 {DYNAMIC_ANNOTATIONS_IMPL}
80 
DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierDestroy)81 void DYNAMIC_ANNOTATIONS_NAME(AnnotateBarrierDestroy)(
82     const char *file, int line, const volatile void *barrier)
83 {DYNAMIC_ANNOTATIONS_IMPL}
84 
DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarWait)85 void DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarWait)(
86     const char *file, int line, const volatile void *cv,
87     const volatile void *lock)
88 {DYNAMIC_ANNOTATIONS_IMPL}
89 
DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarSignal)90 void DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarSignal)(
91     const char *file, int line, const volatile void *cv)
92 {DYNAMIC_ANNOTATIONS_IMPL}
93 
DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarSignalAll)94 void DYNAMIC_ANNOTATIONS_NAME(AnnotateCondVarSignalAll)(
95     const char *file, int line, const volatile void *cv)
96 {DYNAMIC_ANNOTATIONS_IMPL}
97 
DYNAMIC_ANNOTATIONS_NAME(AnnotateHappensBefore)98 void DYNAMIC_ANNOTATIONS_NAME(AnnotateHappensBefore)(
99     const char *file, int line, const volatile void *obj)
100 {DYNAMIC_ANNOTATIONS_IMPL}
101 
DYNAMIC_ANNOTATIONS_NAME(AnnotateHappensAfter)102 void DYNAMIC_ANNOTATIONS_NAME(AnnotateHappensAfter)(
103     const char *file, int line, const volatile void *obj)
104 {DYNAMIC_ANNOTATIONS_IMPL}
105 
DYNAMIC_ANNOTATIONS_NAME(AnnotatePublishMemoryRange)106 void DYNAMIC_ANNOTATIONS_NAME(AnnotatePublishMemoryRange)(
107     const char *file, int line, const volatile void *address, long size)
108 {DYNAMIC_ANNOTATIONS_IMPL}
109 
DYNAMIC_ANNOTATIONS_NAME(AnnotateUnpublishMemoryRange)110 void DYNAMIC_ANNOTATIONS_NAME(AnnotateUnpublishMemoryRange)(
111     const char *file, int line, const volatile void *address, long size)
112 {DYNAMIC_ANNOTATIONS_IMPL}
113 
DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQCreate)114 void DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQCreate)(
115     const char *file, int line, const volatile void *pcq)
116 {DYNAMIC_ANNOTATIONS_IMPL}
117 
DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQDestroy)118 void DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQDestroy)(
119     const char *file, int line, const volatile void *pcq)
120 {DYNAMIC_ANNOTATIONS_IMPL}
121 
DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQPut)122 void DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQPut)(
123     const char *file, int line, const volatile void *pcq)
124 {DYNAMIC_ANNOTATIONS_IMPL}
125 
DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQGet)126 void DYNAMIC_ANNOTATIONS_NAME(AnnotatePCQGet)(
127     const char *file, int line, const volatile void *pcq)
128 {DYNAMIC_ANNOTATIONS_IMPL}
129 
DYNAMIC_ANNOTATIONS_NAME(AnnotateNewMemory)130 void DYNAMIC_ANNOTATIONS_NAME(AnnotateNewMemory)(
131     const char *file, int line, const volatile void *mem, long size)
132 {DYNAMIC_ANNOTATIONS_IMPL}
133 
DYNAMIC_ANNOTATIONS_NAME(AnnotateExpectRace)134 void DYNAMIC_ANNOTATIONS_NAME(AnnotateExpectRace)(
135     const char *file, int line, const volatile void *mem,
136     const char *description)
137 {DYNAMIC_ANNOTATIONS_IMPL}
138 
DYNAMIC_ANNOTATIONS_NAME(AnnotateFlushExpectedRaces)139 void DYNAMIC_ANNOTATIONS_NAME(AnnotateFlushExpectedRaces)(
140     const char *file, int line)
141 {DYNAMIC_ANNOTATIONS_IMPL}
142 
DYNAMIC_ANNOTATIONS_NAME(AnnotateBenignRace)143 void DYNAMIC_ANNOTATIONS_NAME(AnnotateBenignRace)(
144     const char *file, int line, const volatile void *mem,
145     const char *description)
146 {DYNAMIC_ANNOTATIONS_IMPL}
147 
DYNAMIC_ANNOTATIONS_NAME(AnnotateBenignRaceSized)148 void DYNAMIC_ANNOTATIONS_NAME(AnnotateBenignRaceSized)(
149     const char *file, int line, const volatile void *mem, long size,
150     const char *description)
151 {DYNAMIC_ANNOTATIONS_IMPL}
152 
DYNAMIC_ANNOTATIONS_NAME(AnnotateMutexIsUsedAsCondVar)153 void DYNAMIC_ANNOTATIONS_NAME(AnnotateMutexIsUsedAsCondVar)(
154     const char *file, int line, const volatile void *mu)
155 {DYNAMIC_ANNOTATIONS_IMPL}
156 
DYNAMIC_ANNOTATIONS_NAME(AnnotateMutexIsNotPHB)157 void DYNAMIC_ANNOTATIONS_NAME(AnnotateMutexIsNotPHB)(
158     const char *file, int line, const volatile void *mu)
159 {DYNAMIC_ANNOTATIONS_IMPL}
160 
DYNAMIC_ANNOTATIONS_NAME(AnnotateTraceMemory)161 void DYNAMIC_ANNOTATIONS_NAME(AnnotateTraceMemory)(
162     const char *file, int line, const volatile void *arg)
163 {DYNAMIC_ANNOTATIONS_IMPL}
164 
DYNAMIC_ANNOTATIONS_NAME(AnnotateThreadName)165 void DYNAMIC_ANNOTATIONS_NAME(AnnotateThreadName)(
166     const char *file, int line, const char *name)
167 {DYNAMIC_ANNOTATIONS_IMPL}
168 
DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreReadsBegin)169 void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreReadsBegin)(
170     const char *file, int line)
171 {DYNAMIC_ANNOTATIONS_IMPL}
172 
DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreReadsEnd)173 void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreReadsEnd)(
174     const char *file, int line)
175 {DYNAMIC_ANNOTATIONS_IMPL}
176 
DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreWritesBegin)177 void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreWritesBegin)(
178     const char *file, int line)
179 {DYNAMIC_ANNOTATIONS_IMPL}
180 
DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreWritesEnd)181 void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreWritesEnd)(
182     const char *file, int line)
183 {DYNAMIC_ANNOTATIONS_IMPL}
184 
DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreSyncBegin)185 void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreSyncBegin)(
186     const char *file, int line)
187 {DYNAMIC_ANNOTATIONS_IMPL}
188 
DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreSyncEnd)189 void DYNAMIC_ANNOTATIONS_NAME(AnnotateIgnoreSyncEnd)(
190     const char *file, int line)
191 {DYNAMIC_ANNOTATIONS_IMPL}
192 
DYNAMIC_ANNOTATIONS_NAME(AnnotateEnableRaceDetection)193 void DYNAMIC_ANNOTATIONS_NAME(AnnotateEnableRaceDetection)(
194     const char *file, int line, int enable)
195 {DYNAMIC_ANNOTATIONS_IMPL}
196 
DYNAMIC_ANNOTATIONS_NAME(AnnotateNoOp)197 void DYNAMIC_ANNOTATIONS_NAME(AnnotateNoOp)(
198     const char *file, int line, const volatile void *arg)
199 {DYNAMIC_ANNOTATIONS_IMPL}
200 
DYNAMIC_ANNOTATIONS_NAME(AnnotateFlushState)201 void DYNAMIC_ANNOTATIONS_NAME(AnnotateFlushState)(
202     const char *file, int line)
203 {DYNAMIC_ANNOTATIONS_IMPL}
204 
205 #endif  /* DYNAMIC_ANNOTATIONS_ENABLED == 1 */
206 
207 #if DYNAMIC_ANNOTATIONS_PROVIDE_RUNNING_ON_VALGRIND == 1
GetRunningOnValgrind(void)208 static int GetRunningOnValgrind(void) {
209 #ifdef RUNNING_ON_VALGRIND
210   if (RUNNING_ON_VALGRIND) return 1;
211 #endif
212 
213 #ifndef _MSC_VER
214   char *running_on_valgrind_str = getenv("RUNNING_ON_VALGRIND");
215   if (running_on_valgrind_str) {
216     return strcmp(running_on_valgrind_str, "0") != 0;
217   }
218 #else
219   /* Visual Studio issues warnings if we use getenv,
220    * so we use GetEnvironmentVariableA instead.
221    */
222   char value[100] = "1";
223   int res = GetEnvironmentVariableA("RUNNING_ON_VALGRIND",
224                                     value, sizeof(value));
225   /* value will remain "1" if res == 0 or res >= sizeof(value). The latter
226    * can happen only if the given value is long, in this case it can't be "0".
227    */
228   if (res > 0 && strcmp(value, "0") != 0)
229     return 1;
230 #endif
231   return 0;
232 }
233 
234 /* See the comments in dynamic_annotations.h */
RunningOnValgrind(void)235 int RunningOnValgrind(void) {
236   static volatile int running_on_valgrind = -1;
237   /* C doesn't have thread-safe initialization of statics, and we
238      don't want to depend on pthread_once here, so hack it. */
239   int local_running_on_valgrind = running_on_valgrind;
240   if (local_running_on_valgrind == -1)
241     running_on_valgrind = local_running_on_valgrind = GetRunningOnValgrind();
242   return local_running_on_valgrind;
243 }
244 
245 #endif /* DYNAMIC_ANNOTATIONS_PROVIDE_RUNNING_ON_VALGRIND == 1 */
246