• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <stdlib.h>
16 #include <string.h>
17 
18 #include "absl/base/dynamic_annotations.h"
19 
20 #ifndef __has_feature
21 #define __has_feature(x) 0
22 #endif
23 
24 /* Compiler-based ThreadSanitizer defines
25    DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL = 1
26    and provides its own definitions of the functions. */
27 
28 #ifndef DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL
29 # define DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL 0
30 #endif
31 
32 /* Each function is empty and called (via a macro) only in debug mode.
33    The arguments are captured by dynamic tools at runtime. */
34 
35 #if DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL == 0 && !defined(__native_client__)
36 
37 #if __has_feature(memory_sanitizer)
38 #include <sanitizer/msan_interface.h>
39 #endif
40 
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44 
AnnotateRWLockCreate(const char *,int,const volatile void *)45 void AnnotateRWLockCreate(const char *, int,
46                           const volatile void *){}
AnnotateRWLockDestroy(const char *,int,const volatile void *)47 void AnnotateRWLockDestroy(const char *, int,
48                            const volatile void *){}
AnnotateRWLockAcquired(const char *,int,const volatile void *,long)49 void AnnotateRWLockAcquired(const char *, int,
50                             const volatile void *, long){}
AnnotateRWLockReleased(const char *,int,const volatile void *,long)51 void AnnotateRWLockReleased(const char *, int,
52                             const volatile void *, long){}
AnnotateBenignRace(const char *,int,const volatile void *,const char *)53 void AnnotateBenignRace(const char *, int,
54                         const volatile void *,
55                         const char *){}
AnnotateBenignRaceSized(const char *,int,const volatile void *,size_t,const char *)56 void AnnotateBenignRaceSized(const char *, int,
57                              const volatile void *,
58                              size_t,
59                              const char *) {}
AnnotateThreadName(const char *,int,const char *)60 void AnnotateThreadName(const char *, int,
61                         const char *){}
AnnotateIgnoreReadsBegin(const char *,int)62 void AnnotateIgnoreReadsBegin(const char *, int){}
AnnotateIgnoreReadsEnd(const char *,int)63 void AnnotateIgnoreReadsEnd(const char *, int){}
AnnotateIgnoreWritesBegin(const char *,int)64 void AnnotateIgnoreWritesBegin(const char *, int){}
AnnotateIgnoreWritesEnd(const char *,int)65 void AnnotateIgnoreWritesEnd(const char *, int){}
AnnotateEnableRaceDetection(const char *,int,int)66 void AnnotateEnableRaceDetection(const char *, int, int){}
AnnotateMemoryIsInitialized(const char *,int,const volatile void * mem,size_t size)67 void AnnotateMemoryIsInitialized(const char *, int,
68                                  const volatile void *mem, size_t size) {
69 #if __has_feature(memory_sanitizer)
70   __msan_unpoison(mem, size);
71 #else
72   (void)mem;
73   (void)size;
74 #endif
75 }
76 
AnnotateMemoryIsUninitialized(const char *,int,const volatile void * mem,size_t size)77 void AnnotateMemoryIsUninitialized(const char *, int,
78                                    const volatile void *mem, size_t size) {
79 #if __has_feature(memory_sanitizer)
80   __msan_allocated_memory(mem, size);
81 #else
82   (void)mem;
83   (void)size;
84 #endif
85 }
86 
GetRunningOnValgrind(void)87 static int GetRunningOnValgrind(void) {
88 #ifdef RUNNING_ON_VALGRIND
89   if (RUNNING_ON_VALGRIND) return 1;
90 #endif
91   char *running_on_valgrind_str = getenv("RUNNING_ON_VALGRIND");
92   if (running_on_valgrind_str) {
93     return strcmp(running_on_valgrind_str, "0") != 0;
94   }
95   return 0;
96 }
97 
98 /* See the comments in dynamic_annotations.h */
RunningOnValgrind(void)99 int RunningOnValgrind(void) {
100   static volatile int running_on_valgrind = -1;
101   int local_running_on_valgrind = running_on_valgrind;
102   /* C doesn't have thread-safe initialization of statics, and we
103      don't want to depend on pthread_once here, so hack it. */
104   ANNOTATE_BENIGN_RACE(&running_on_valgrind, "safe hack");
105   if (local_running_on_valgrind == -1)
106     running_on_valgrind = local_running_on_valgrind = GetRunningOnValgrind();
107   return local_running_on_valgrind;
108 }
109 
110 /* See the comments in dynamic_annotations.h */
ValgrindSlowdown(void)111 double ValgrindSlowdown(void) {
112   /* Same initialization hack as in RunningOnValgrind(). */
113   static volatile double slowdown = 0.0;
114   double local_slowdown = slowdown;
115   ANNOTATE_BENIGN_RACE(&slowdown, "safe hack");
116   if (RunningOnValgrind() == 0) {
117     return 1.0;
118   }
119   if (local_slowdown == 0.0) {
120     char *env = getenv("VALGRIND_SLOWDOWN");
121     slowdown = local_slowdown = env ? atof(env) : 50.0;
122   }
123   return local_slowdown;
124 }
125 
126 #ifdef __cplusplus
127 }  // extern "C"
128 #endif
129 #endif  /* DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL == 0 */
130