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