1 //===-- tsan_interceptors.cc ----------------------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file is a part of ThreadSanitizer (TSan), a race detector.
11 //
12 // FIXME: move as many interceptors as possible into
13 // sanitizer_common/sanitizer_common_interceptors.inc
14 //===----------------------------------------------------------------------===//
15
16 #include "sanitizer_common/sanitizer_atomic.h"
17 #include "sanitizer_common/sanitizer_libc.h"
18 #include "sanitizer_common/sanitizer_linux.h"
19 #include "sanitizer_common/sanitizer_platform_limits_posix.h"
20 #include "sanitizer_common/sanitizer_placement_new.h"
21 #include "sanitizer_common/sanitizer_stacktrace.h"
22 #include "interception/interception.h"
23 #include "tsan_interface.h"
24 #include "tsan_platform.h"
25 #include "tsan_rtl.h"
26 #include "tsan_mman.h"
27 #include "tsan_fd.h"
28
29 using namespace __tsan; // NOLINT
30
31 const int kSigCount = 64;
32
33 struct my_siginfo_t {
34 // The size is determined by looking at sizeof of real siginfo_t on linux.
35 u64 opaque[128 / sizeof(u64)];
36 };
37
38 struct sigset_t {
39 // The size is determined by looking at sizeof of real sigset_t on linux.
40 u64 val[128 / sizeof(u64)];
41 };
42
43 struct ucontext_t {
44 // The size is determined by looking at sizeof of real ucontext_t on linux.
45 u64 opaque[936 / sizeof(u64) + 1];
46 };
47
48 extern "C" int pthread_attr_init(void *attr);
49 extern "C" int pthread_attr_destroy(void *attr);
50 extern "C" int pthread_attr_getdetachstate(void *attr, int *v);
51 extern "C" int pthread_attr_setstacksize(void *attr, uptr stacksize);
52 extern "C" int pthread_attr_getstacksize(void *attr, uptr *stacksize);
53 extern "C" int pthread_key_create(unsigned *key, void (*destructor)(void* v));
54 extern "C" int pthread_setspecific(unsigned key, const void *v);
55 extern "C" int pthread_mutexattr_gettype(void *a, int *type);
56 extern "C" int pthread_yield();
57 extern "C" int pthread_sigmask(int how, const sigset_t *set, sigset_t *oldset);
58 extern "C" int sigfillset(sigset_t *set);
59 extern "C" void *pthread_self();
60 extern "C" void _exit(int status);
61 extern "C" int *__errno_location();
62 extern "C" int fileno_unlocked(void *stream);
63 extern "C" void *__libc_malloc(uptr size);
64 extern "C" void *__libc_calloc(uptr size, uptr n);
65 extern "C" void *__libc_realloc(void *ptr, uptr size);
66 extern "C" void __libc_free(void *ptr);
67 extern "C" int mallopt(int param, int value);
68 const int PTHREAD_MUTEX_RECURSIVE = 1;
69 const int PTHREAD_MUTEX_RECURSIVE_NP = 1;
70 const int kPthreadAttrSize = 56;
71 const int EINVAL = 22;
72 const int EBUSY = 16;
73 const int EPOLL_CTL_ADD = 1;
74 const int SIGILL = 4;
75 const int SIGABRT = 6;
76 const int SIGFPE = 8;
77 const int SIGSEGV = 11;
78 const int SIGPIPE = 13;
79 const int SIGBUS = 7;
80 const int SIGSYS = 31;
81 void *const MAP_FAILED = (void*)-1;
82 const int PTHREAD_BARRIER_SERIAL_THREAD = -1;
83 const int MAP_FIXED = 0x10;
84 typedef long long_t; // NOLINT
85
86 // From /usr/include/unistd.h
87 # define F_ULOCK 0 /* Unlock a previously locked region. */
88 # define F_LOCK 1 /* Lock a region for exclusive use. */
89 # define F_TLOCK 2 /* Test and lock a region for exclusive use. */
90 # define F_TEST 3 /* Test a region for other processes locks. */
91
92 typedef void (*sighandler_t)(int sig);
93
94 #define errno (*__errno_location())
95
96 struct sigaction_t {
97 union {
98 sighandler_t sa_handler;
99 void (*sa_sigaction)(int sig, my_siginfo_t *siginfo, void *uctx);
100 };
101 sigset_t sa_mask;
102 int sa_flags;
103 void (*sa_restorer)();
104 };
105
106 const sighandler_t SIG_DFL = (sighandler_t)0;
107 const sighandler_t SIG_IGN = (sighandler_t)1;
108 const sighandler_t SIG_ERR = (sighandler_t)-1;
109 const int SA_SIGINFO = 4;
110 const int SIG_SETMASK = 2;
111
112 namespace std {
113 struct nothrow_t {};
114 } // namespace std
115
116 static sigaction_t sigactions[kSigCount];
117
118 namespace __tsan {
119 struct SignalDesc {
120 bool armed;
121 bool sigaction;
122 my_siginfo_t siginfo;
123 ucontext_t ctx;
124 };
125
126 struct SignalContext {
127 int in_blocking_func;
128 int int_signal_send;
129 int pending_signal_count;
130 SignalDesc pending_signals[kSigCount];
131 };
132 } // namespace __tsan
133
SigCtx(ThreadState * thr)134 static SignalContext *SigCtx(ThreadState *thr) {
135 SignalContext *ctx = (SignalContext*)thr->signal_ctx;
136 if (ctx == 0 && thr->is_alive) {
137 ScopedInRtl in_rtl;
138 ctx = (SignalContext*)MmapOrDie(sizeof(*ctx), "SignalContext");
139 MemoryResetRange(thr, (uptr)&SigCtx, (uptr)ctx, sizeof(*ctx));
140 thr->signal_ctx = ctx;
141 }
142 return ctx;
143 }
144
145 static unsigned g_thread_finalize_key;
146
147 class ScopedInterceptor {
148 public:
149 ScopedInterceptor(ThreadState *thr, const char *fname, uptr pc);
150 ~ScopedInterceptor();
151 private:
152 ThreadState *const thr_;
153 const int in_rtl_;
154 };
155
ScopedInterceptor(ThreadState * thr,const char * fname,uptr pc)156 ScopedInterceptor::ScopedInterceptor(ThreadState *thr, const char *fname,
157 uptr pc)
158 : thr_(thr)
159 , in_rtl_(thr->in_rtl) {
160 if (thr_->in_rtl == 0) {
161 Initialize(thr);
162 FuncEntry(thr, pc);
163 thr_->in_rtl++;
164 DPrintf("#%d: intercept %s()\n", thr_->tid, fname);
165 } else {
166 thr_->in_rtl++;
167 }
168 }
169
~ScopedInterceptor()170 ScopedInterceptor::~ScopedInterceptor() {
171 thr_->in_rtl--;
172 if (thr_->in_rtl == 0) {
173 FuncExit(thr_);
174 ProcessPendingSignals(thr_);
175 }
176 CHECK_EQ(in_rtl_, thr_->in_rtl);
177 }
178
179 #define SCOPED_INTERCEPTOR_RAW(func, ...) \
180 ThreadState *thr = cur_thread(); \
181 StatInc(thr, StatInterceptor); \
182 StatInc(thr, StatInt_##func); \
183 const uptr caller_pc = GET_CALLER_PC(); \
184 ScopedInterceptor si(thr, #func, caller_pc); \
185 const uptr pc = __sanitizer::StackTrace::GetCurrentPc(); \
186 (void)pc; \
187 /**/
188
189 #define SCOPED_TSAN_INTERCEPTOR(func, ...) \
190 SCOPED_INTERCEPTOR_RAW(func, __VA_ARGS__); \
191 if (REAL(func) == 0) { \
192 Printf("FATAL: ThreadSanitizer: failed to intercept %s\n", #func); \
193 Die(); \
194 } \
195 if (thr->in_rtl > 1) \
196 return REAL(func)(__VA_ARGS__); \
197 /**/
198
199 #define TSAN_INTERCEPTOR(ret, func, ...) INTERCEPTOR(ret, func, __VA_ARGS__)
200 #define TSAN_INTERCEPT(func) INTERCEPT_FUNCTION(func)
201
202 #define BLOCK_REAL(name) (BlockingCall(thr), REAL(name))
203
204 struct BlockingCall {
BlockingCallBlockingCall205 explicit BlockingCall(ThreadState *thr)
206 : ctx(SigCtx(thr)) {
207 ctx->in_blocking_func++;
208 }
209
~BlockingCallBlockingCall210 ~BlockingCall() {
211 ctx->in_blocking_func--;
212 }
213
214 SignalContext *ctx;
215 };
216
TSAN_INTERCEPTOR(unsigned,sleep,unsigned sec)217 TSAN_INTERCEPTOR(unsigned, sleep, unsigned sec) {
218 SCOPED_TSAN_INTERCEPTOR(sleep, sec);
219 unsigned res = BLOCK_REAL(sleep)(sec);
220 AfterSleep(thr, pc);
221 return res;
222 }
223
TSAN_INTERCEPTOR(int,usleep,long_t usec)224 TSAN_INTERCEPTOR(int, usleep, long_t usec) {
225 SCOPED_TSAN_INTERCEPTOR(usleep, usec);
226 int res = BLOCK_REAL(usleep)(usec);
227 AfterSleep(thr, pc);
228 return res;
229 }
230
TSAN_INTERCEPTOR(int,nanosleep,void * req,void * rem)231 TSAN_INTERCEPTOR(int, nanosleep, void *req, void *rem) {
232 SCOPED_TSAN_INTERCEPTOR(nanosleep, req, rem);
233 int res = BLOCK_REAL(nanosleep)(req, rem);
234 AfterSleep(thr, pc);
235 return res;
236 }
237
238 class AtExitContext {
239 public:
AtExitContext()240 AtExitContext()
241 : mtx_(MutexTypeAtExit, StatMtxAtExit)
242 , pos_() {
243 }
244
245 typedef void(*atexit_t)();
246
atexit(ThreadState * thr,uptr pc,bool is_on_exit,atexit_t f,void * arg)247 int atexit(ThreadState *thr, uptr pc, bool is_on_exit,
248 atexit_t f, void *arg) {
249 Lock l(&mtx_);
250 if (pos_ == kMaxAtExit)
251 return 1;
252 Release(thr, pc, (uptr)this);
253 stack_[pos_] = f;
254 args_[pos_] = arg;
255 is_on_exits_[pos_] = is_on_exit;
256 pos_++;
257 return 0;
258 }
259
exit(ThreadState * thr,uptr pc)260 void exit(ThreadState *thr, uptr pc) {
261 CHECK_EQ(thr->in_rtl, 0);
262 for (;;) {
263 atexit_t f = 0;
264 void *arg = 0;
265 bool is_on_exit = false;
266 {
267 Lock l(&mtx_);
268 if (pos_) {
269 pos_--;
270 f = stack_[pos_];
271 arg = args_[pos_];
272 is_on_exit = is_on_exits_[pos_];
273 ScopedInRtl in_rtl;
274 Acquire(thr, pc, (uptr)this);
275 }
276 }
277 if (f == 0)
278 break;
279 DPrintf("#%d: executing atexit func %p\n", thr->tid, f);
280 CHECK_EQ(thr->in_rtl, 0);
281 if (is_on_exit)
282 ((void(*)(int status, void *arg))f)(0, arg);
283 else
284 ((void(*)(void *arg, void *dso))f)(arg, 0);
285 }
286 }
287
288 private:
289 static const int kMaxAtExit = 128;
290 Mutex mtx_;
291 atexit_t stack_[kMaxAtExit];
292 void *args_[kMaxAtExit];
293 bool is_on_exits_[kMaxAtExit];
294 int pos_;
295 };
296
297 static AtExitContext *atexit_ctx;
298
TSAN_INTERCEPTOR(int,atexit,void (* f)())299 TSAN_INTERCEPTOR(int, atexit, void (*f)()) {
300 if (cur_thread()->in_symbolizer)
301 return 0;
302 SCOPED_TSAN_INTERCEPTOR(atexit, f);
303 return atexit_ctx->atexit(thr, pc, false, (void(*)())f, 0);
304 }
305
TSAN_INTERCEPTOR(int,on_exit,void (* f)(int,void *),void * arg)306 TSAN_INTERCEPTOR(int, on_exit, void(*f)(int, void*), void *arg) {
307 if (cur_thread()->in_symbolizer)
308 return 0;
309 SCOPED_TSAN_INTERCEPTOR(on_exit, f, arg);
310 return atexit_ctx->atexit(thr, pc, true, (void(*)())f, arg);
311 }
312
TSAN_INTERCEPTOR(int,__cxa_atexit,void (* f)(void * a),void * arg,void * dso)313 TSAN_INTERCEPTOR(int, __cxa_atexit, void (*f)(void *a), void *arg, void *dso) {
314 if (cur_thread()->in_symbolizer)
315 return 0;
316 SCOPED_TSAN_INTERCEPTOR(__cxa_atexit, f, arg, dso);
317 if (dso)
318 return REAL(__cxa_atexit)(f, arg, dso);
319 return atexit_ctx->atexit(thr, pc, false, (void(*)())f, arg);
320 }
321
322 // Cleanup old bufs.
JmpBufGarbageCollect(ThreadState * thr,uptr sp)323 static void JmpBufGarbageCollect(ThreadState *thr, uptr sp) {
324 for (uptr i = 0; i < thr->jmp_bufs.Size(); i++) {
325 JmpBuf *buf = &thr->jmp_bufs[i];
326 if (buf->sp <= sp) {
327 uptr sz = thr->jmp_bufs.Size();
328 thr->jmp_bufs[i] = thr->jmp_bufs[sz - 1];
329 thr->jmp_bufs.PopBack();
330 i--;
331 }
332 }
333 }
334
SetJmp(ThreadState * thr,uptr sp,uptr mangled_sp)335 static void SetJmp(ThreadState *thr, uptr sp, uptr mangled_sp) {
336 if (thr->shadow_stack_pos == 0) // called from libc guts during bootstrap
337 return;
338 // Cleanup old bufs.
339 JmpBufGarbageCollect(thr, sp);
340 // Remember the buf.
341 JmpBuf *buf = thr->jmp_bufs.PushBack();
342 buf->sp = sp;
343 buf->mangled_sp = mangled_sp;
344 buf->shadow_stack_pos = thr->shadow_stack_pos;
345 }
346
LongJmp(ThreadState * thr,uptr * env)347 static void LongJmp(ThreadState *thr, uptr *env) {
348 uptr mangled_sp = env[6];
349 // Find the saved buf by mangled_sp.
350 for (uptr i = 0; i < thr->jmp_bufs.Size(); i++) {
351 JmpBuf *buf = &thr->jmp_bufs[i];
352 if (buf->mangled_sp == mangled_sp) {
353 CHECK_GE(thr->shadow_stack_pos, buf->shadow_stack_pos);
354 // Unwind the stack.
355 while (thr->shadow_stack_pos > buf->shadow_stack_pos)
356 FuncExit(thr);
357 JmpBufGarbageCollect(thr, buf->sp - 1); // do not collect buf->sp
358 return;
359 }
360 }
361 Printf("ThreadSanitizer: can't find longjmp buf\n");
362 CHECK(0);
363 }
364
__tsan_setjmp(uptr sp,uptr mangled_sp)365 extern "C" void __tsan_setjmp(uptr sp, uptr mangled_sp) {
366 ScopedInRtl in_rtl;
367 SetJmp(cur_thread(), sp, mangled_sp);
368 }
369
370 // Not called. Merely to satisfy TSAN_INTERCEPT().
371 extern "C" int __interceptor_setjmp(void *env)
372 SANITIZER_INTERFACE_ATTRIBUTE;
__interceptor_setjmp(void * env)373 extern "C" int __interceptor_setjmp(void *env) {
374 CHECK(0);
375 return 0;
376 }
377
378 extern "C" int __interceptor__setjmp(void *env)
379 SANITIZER_INTERFACE_ATTRIBUTE;
__interceptor__setjmp(void * env)380 extern "C" int __interceptor__setjmp(void *env) {
381 CHECK(0);
382 return 0;
383 }
384
385 extern "C" int __interceptor_sigsetjmp(void *env)
386 SANITIZER_INTERFACE_ATTRIBUTE;
__interceptor_sigsetjmp(void * env)387 extern "C" int __interceptor_sigsetjmp(void *env) {
388 CHECK(0);
389 return 0;
390 }
391
392 extern "C" int __interceptor___sigsetjmp(void *env)
393 SANITIZER_INTERFACE_ATTRIBUTE;
__interceptor___sigsetjmp(void * env)394 extern "C" int __interceptor___sigsetjmp(void *env) {
395 CHECK(0);
396 return 0;
397 }
398
399 extern "C" int setjmp(void *env);
400 extern "C" int _setjmp(void *env);
401 extern "C" int sigsetjmp(void *env);
402 extern "C" int __sigsetjmp(void *env);
DEFINE_REAL(int,setjmp,void * env)403 DEFINE_REAL(int, setjmp, void *env)
404 DEFINE_REAL(int, _setjmp, void *env)
405 DEFINE_REAL(int, sigsetjmp, void *env)
406 DEFINE_REAL(int, __sigsetjmp, void *env)
407
408 TSAN_INTERCEPTOR(void, longjmp, uptr *env, int val) {
409 {
410 SCOPED_TSAN_INTERCEPTOR(longjmp, env, val);
411 }
412 LongJmp(cur_thread(), env);
413 REAL(longjmp)(env, val);
414 }
415
TSAN_INTERCEPTOR(void,siglongjmp,uptr * env,int val)416 TSAN_INTERCEPTOR(void, siglongjmp, uptr *env, int val) {
417 {
418 SCOPED_TSAN_INTERCEPTOR(siglongjmp, env, val);
419 }
420 LongJmp(cur_thread(), env);
421 REAL(siglongjmp)(env, val);
422 }
423
TSAN_INTERCEPTOR(void *,malloc,uptr size)424 TSAN_INTERCEPTOR(void*, malloc, uptr size) {
425 if (cur_thread()->in_symbolizer)
426 return __libc_malloc(size);
427 void *p = 0;
428 {
429 SCOPED_INTERCEPTOR_RAW(malloc, size);
430 p = user_alloc(thr, pc, size);
431 }
432 invoke_malloc_hook(p, size);
433 return p;
434 }
435
TSAN_INTERCEPTOR(void *,__libc_memalign,uptr align,uptr sz)436 TSAN_INTERCEPTOR(void*, __libc_memalign, uptr align, uptr sz) {
437 SCOPED_TSAN_INTERCEPTOR(__libc_memalign, align, sz);
438 return user_alloc(thr, pc, sz, align);
439 }
440
TSAN_INTERCEPTOR(void *,calloc,uptr size,uptr n)441 TSAN_INTERCEPTOR(void*, calloc, uptr size, uptr n) {
442 if (cur_thread()->in_symbolizer)
443 return __libc_calloc(size, n);
444 if (__sanitizer::CallocShouldReturnNullDueToOverflow(size, n)) return 0;
445 void *p = 0;
446 {
447 SCOPED_INTERCEPTOR_RAW(calloc, size, n);
448 p = user_alloc(thr, pc, n * size);
449 if (p)
450 internal_memset(p, 0, n * size);
451 }
452 invoke_malloc_hook(p, n * size);
453 return p;
454 }
455
TSAN_INTERCEPTOR(void *,realloc,void * p,uptr size)456 TSAN_INTERCEPTOR(void*, realloc, void *p, uptr size) {
457 if (cur_thread()->in_symbolizer)
458 return __libc_realloc(p, size);
459 if (p)
460 invoke_free_hook(p);
461 {
462 SCOPED_INTERCEPTOR_RAW(realloc, p, size);
463 p = user_realloc(thr, pc, p, size);
464 }
465 invoke_malloc_hook(p, size);
466 return p;
467 }
468
TSAN_INTERCEPTOR(void,free,void * p)469 TSAN_INTERCEPTOR(void, free, void *p) {
470 if (p == 0)
471 return;
472 if (cur_thread()->in_symbolizer)
473 return __libc_free(p);
474 invoke_free_hook(p);
475 SCOPED_INTERCEPTOR_RAW(free, p);
476 user_free(thr, pc, p);
477 }
478
TSAN_INTERCEPTOR(void,cfree,void * p)479 TSAN_INTERCEPTOR(void, cfree, void *p) {
480 if (p == 0)
481 return;
482 if (cur_thread()->in_symbolizer)
483 return __libc_free(p);
484 invoke_free_hook(p);
485 SCOPED_INTERCEPTOR_RAW(cfree, p);
486 user_free(thr, pc, p);
487 }
488
TSAN_INTERCEPTOR(uptr,malloc_usable_size,void * p)489 TSAN_INTERCEPTOR(uptr, malloc_usable_size, void *p) {
490 SCOPED_INTERCEPTOR_RAW(malloc_usable_size, p);
491 return user_alloc_usable_size(thr, pc, p);
492 }
493
494 #define OPERATOR_NEW_BODY(mangled_name) \
495 if (cur_thread()->in_symbolizer) \
496 return __libc_malloc(size); \
497 void *p = 0; \
498 { \
499 SCOPED_INTERCEPTOR_RAW(mangled_name, size); \
500 p = user_alloc(thr, pc, size); \
501 } \
502 invoke_malloc_hook(p, size); \
503 return p;
504
505 void *operator new(__sanitizer::uptr size)
506 SANITIZER_INTERFACE_ATTRIBUTE;
operator new(__sanitizer::uptr size)507 void *operator new(__sanitizer::uptr size) {
508 OPERATOR_NEW_BODY(_Znwm);
509 }
510
511 void *operator new[](__sanitizer::uptr size)
512 SANITIZER_INTERFACE_ATTRIBUTE;
operator new[](__sanitizer::uptr size)513 void *operator new[](__sanitizer::uptr size) {
514 OPERATOR_NEW_BODY(_Znam);
515 }
516
517 void *operator new(__sanitizer::uptr size, std::nothrow_t const&)
518 SANITIZER_INTERFACE_ATTRIBUTE;
operator new(__sanitizer::uptr size,std::nothrow_t const &)519 void *operator new(__sanitizer::uptr size, std::nothrow_t const&) {
520 OPERATOR_NEW_BODY(_ZnwmRKSt9nothrow_t);
521 }
522
523 void *operator new[](__sanitizer::uptr size, std::nothrow_t const&)
524 SANITIZER_INTERFACE_ATTRIBUTE;
operator new[](__sanitizer::uptr size,std::nothrow_t const &)525 void *operator new[](__sanitizer::uptr size, std::nothrow_t const&) {
526 OPERATOR_NEW_BODY(_ZnamRKSt9nothrow_t);
527 }
528
529 #define OPERATOR_DELETE_BODY(mangled_name) \
530 if (ptr == 0) return; \
531 if (cur_thread()->in_symbolizer) \
532 return __libc_free(ptr); \
533 invoke_free_hook(ptr); \
534 SCOPED_INTERCEPTOR_RAW(mangled_name, ptr); \
535 user_free(thr, pc, ptr);
536
537 void operator delete(void *ptr)
538 SANITIZER_INTERFACE_ATTRIBUTE;
operator delete(void * ptr)539 void operator delete(void *ptr) {
540 OPERATOR_DELETE_BODY(_ZdlPv);
541 }
542
543 void operator delete[](void *ptr)
544 SANITIZER_INTERFACE_ATTRIBUTE;
operator delete[](void * ptr)545 void operator delete[](void *ptr) {
546 OPERATOR_DELETE_BODY(_ZdlPvRKSt9nothrow_t);
547 }
548
549 void operator delete(void *ptr, std::nothrow_t const&)
550 SANITIZER_INTERFACE_ATTRIBUTE;
operator delete(void * ptr,std::nothrow_t const &)551 void operator delete(void *ptr, std::nothrow_t const&) {
552 OPERATOR_DELETE_BODY(_ZdaPv);
553 }
554
555 void operator delete[](void *ptr, std::nothrow_t const&)
556 SANITIZER_INTERFACE_ATTRIBUTE;
operator delete[](void * ptr,std::nothrow_t const &)557 void operator delete[](void *ptr, std::nothrow_t const&) {
558 OPERATOR_DELETE_BODY(_ZdaPvRKSt9nothrow_t);
559 }
560
TSAN_INTERCEPTOR(uptr,strlen,const char * s)561 TSAN_INTERCEPTOR(uptr, strlen, const char *s) {
562 SCOPED_TSAN_INTERCEPTOR(strlen, s);
563 uptr len = internal_strlen(s);
564 MemoryAccessRange(thr, pc, (uptr)s, len + 1, false);
565 return len;
566 }
567
TSAN_INTERCEPTOR(void *,memset,void * dst,int v,uptr size)568 TSAN_INTERCEPTOR(void*, memset, void *dst, int v, uptr size) {
569 SCOPED_TSAN_INTERCEPTOR(memset, dst, v, size);
570 MemoryAccessRange(thr, pc, (uptr)dst, size, true);
571 return internal_memset(dst, v, size);
572 }
573
TSAN_INTERCEPTOR(void *,memcpy,void * dst,const void * src,uptr size)574 TSAN_INTERCEPTOR(void*, memcpy, void *dst, const void *src, uptr size) {
575 SCOPED_TSAN_INTERCEPTOR(memcpy, dst, src, size);
576 MemoryAccessRange(thr, pc, (uptr)dst, size, true);
577 MemoryAccessRange(thr, pc, (uptr)src, size, false);
578 return internal_memcpy(dst, src, size);
579 }
580
TSAN_INTERCEPTOR(int,memcmp,const void * s1,const void * s2,uptr n)581 TSAN_INTERCEPTOR(int, memcmp, const void *s1, const void *s2, uptr n) {
582 SCOPED_TSAN_INTERCEPTOR(memcmp, s1, s2, n);
583 int res = 0;
584 uptr len = 0;
585 for (; len < n; len++) {
586 if ((res = ((unsigned char*)s1)[len] - ((unsigned char*)s2)[len]))
587 break;
588 }
589 MemoryAccessRange(thr, pc, (uptr)s1, len < n ? len + 1 : n, false);
590 MemoryAccessRange(thr, pc, (uptr)s2, len < n ? len + 1 : n, false);
591 return res;
592 }
593
TSAN_INTERCEPTOR(void *,memchr,void * s,int c,uptr n)594 TSAN_INTERCEPTOR(void*, memchr, void *s, int c, uptr n) {
595 SCOPED_TSAN_INTERCEPTOR(memchr, s, c, n);
596 void *res = REAL(memchr)(s, c, n);
597 uptr len = res ? (char*)res - (char*)s + 1 : n;
598 MemoryAccessRange(thr, pc, (uptr)s, len, false);
599 return res;
600 }
601
TSAN_INTERCEPTOR(void *,memrchr,char * s,int c,uptr n)602 TSAN_INTERCEPTOR(void*, memrchr, char *s, int c, uptr n) {
603 SCOPED_TSAN_INTERCEPTOR(memrchr, s, c, n);
604 MemoryAccessRange(thr, pc, (uptr)s, n, false);
605 return REAL(memrchr)(s, c, n);
606 }
607
TSAN_INTERCEPTOR(void *,memmove,void * dst,void * src,uptr n)608 TSAN_INTERCEPTOR(void*, memmove, void *dst, void *src, uptr n) {
609 SCOPED_TSAN_INTERCEPTOR(memmove, dst, src, n);
610 MemoryAccessRange(thr, pc, (uptr)dst, n, true);
611 MemoryAccessRange(thr, pc, (uptr)src, n, false);
612 return REAL(memmove)(dst, src, n);
613 }
614
TSAN_INTERCEPTOR(char *,strchr,char * s,int c)615 TSAN_INTERCEPTOR(char*, strchr, char *s, int c) {
616 SCOPED_TSAN_INTERCEPTOR(strchr, s, c);
617 char *res = REAL(strchr)(s, c);
618 uptr len = res ? (char*)res - (char*)s + 1 : internal_strlen(s) + 1;
619 MemoryAccessRange(thr, pc, (uptr)s, len, false);
620 return res;
621 }
622
TSAN_INTERCEPTOR(char *,strchrnul,char * s,int c)623 TSAN_INTERCEPTOR(char*, strchrnul, char *s, int c) {
624 SCOPED_TSAN_INTERCEPTOR(strchrnul, s, c);
625 char *res = REAL(strchrnul)(s, c);
626 uptr len = (char*)res - (char*)s + 1;
627 MemoryAccessRange(thr, pc, (uptr)s, len, false);
628 return res;
629 }
630
TSAN_INTERCEPTOR(char *,strrchr,char * s,int c)631 TSAN_INTERCEPTOR(char*, strrchr, char *s, int c) {
632 SCOPED_TSAN_INTERCEPTOR(strrchr, s, c);
633 MemoryAccessRange(thr, pc, (uptr)s, internal_strlen(s) + 1, false);
634 return REAL(strrchr)(s, c);
635 }
636
TSAN_INTERCEPTOR(char *,strcpy,char * dst,const char * src)637 TSAN_INTERCEPTOR(char*, strcpy, char *dst, const char *src) { // NOLINT
638 SCOPED_TSAN_INTERCEPTOR(strcpy, dst, src); // NOLINT
639 uptr srclen = internal_strlen(src);
640 MemoryAccessRange(thr, pc, (uptr)dst, srclen + 1, true);
641 MemoryAccessRange(thr, pc, (uptr)src, srclen + 1, false);
642 return REAL(strcpy)(dst, src); // NOLINT
643 }
644
TSAN_INTERCEPTOR(char *,strncpy,char * dst,char * src,uptr n)645 TSAN_INTERCEPTOR(char*, strncpy, char *dst, char *src, uptr n) {
646 SCOPED_TSAN_INTERCEPTOR(strncpy, dst, src, n);
647 uptr srclen = internal_strnlen(src, n);
648 MemoryAccessRange(thr, pc, (uptr)dst, n, true);
649 MemoryAccessRange(thr, pc, (uptr)src, min(srclen + 1, n), false);
650 return REAL(strncpy)(dst, src, n);
651 }
652
TSAN_INTERCEPTOR(const char *,strstr,const char * s1,const char * s2)653 TSAN_INTERCEPTOR(const char*, strstr, const char *s1, const char *s2) {
654 SCOPED_TSAN_INTERCEPTOR(strstr, s1, s2);
655 const char *res = REAL(strstr)(s1, s2);
656 uptr len1 = internal_strlen(s1);
657 uptr len2 = internal_strlen(s2);
658 MemoryAccessRange(thr, pc, (uptr)s1, len1 + 1, false);
659 MemoryAccessRange(thr, pc, (uptr)s2, len2 + 1, false);
660 return res;
661 }
662
fix_mmap_addr(void ** addr,long_t sz,int flags)663 static bool fix_mmap_addr(void **addr, long_t sz, int flags) {
664 if (*addr) {
665 if (!IsAppMem((uptr)*addr) || !IsAppMem((uptr)*addr + sz - 1)) {
666 if (flags & MAP_FIXED) {
667 errno = EINVAL;
668 return false;
669 } else {
670 *addr = 0;
671 }
672 }
673 }
674 return true;
675 }
676
TSAN_INTERCEPTOR(void *,mmap,void * addr,long_t sz,int prot,int flags,int fd,unsigned off)677 TSAN_INTERCEPTOR(void*, mmap, void *addr, long_t sz, int prot,
678 int flags, int fd, unsigned off) {
679 SCOPED_TSAN_INTERCEPTOR(mmap, addr, sz, prot, flags, fd, off);
680 if (!fix_mmap_addr(&addr, sz, flags))
681 return MAP_FAILED;
682 void *res = REAL(mmap)(addr, sz, prot, flags, fd, off);
683 if (res != MAP_FAILED) {
684 if (fd > 0)
685 FdAccess(thr, pc, fd);
686 MemoryRangeImitateWrite(thr, pc, (uptr)res, sz);
687 }
688 return res;
689 }
690
TSAN_INTERCEPTOR(void *,mmap64,void * addr,long_t sz,int prot,int flags,int fd,u64 off)691 TSAN_INTERCEPTOR(void*, mmap64, void *addr, long_t sz, int prot,
692 int flags, int fd, u64 off) {
693 SCOPED_TSAN_INTERCEPTOR(mmap64, addr, sz, prot, flags, fd, off);
694 if (!fix_mmap_addr(&addr, sz, flags))
695 return MAP_FAILED;
696 void *res = REAL(mmap64)(addr, sz, prot, flags, fd, off);
697 if (res != MAP_FAILED) {
698 if (fd > 0)
699 FdAccess(thr, pc, fd);
700 MemoryRangeImitateWrite(thr, pc, (uptr)res, sz);
701 }
702 return res;
703 }
704
TSAN_INTERCEPTOR(int,munmap,void * addr,long_t sz)705 TSAN_INTERCEPTOR(int, munmap, void *addr, long_t sz) {
706 SCOPED_TSAN_INTERCEPTOR(munmap, addr, sz);
707 DontNeedShadowFor((uptr)addr, sz);
708 int res = REAL(munmap)(addr, sz);
709 return res;
710 }
711
TSAN_INTERCEPTOR(void *,memalign,uptr align,uptr sz)712 TSAN_INTERCEPTOR(void*, memalign, uptr align, uptr sz) {
713 SCOPED_TSAN_INTERCEPTOR(memalign, align, sz);
714 return user_alloc(thr, pc, sz, align);
715 }
716
TSAN_INTERCEPTOR(void *,valloc,uptr sz)717 TSAN_INTERCEPTOR(void*, valloc, uptr sz) {
718 SCOPED_TSAN_INTERCEPTOR(valloc, sz);
719 return user_alloc(thr, pc, sz, GetPageSizeCached());
720 }
721
TSAN_INTERCEPTOR(void *,pvalloc,uptr sz)722 TSAN_INTERCEPTOR(void*, pvalloc, uptr sz) {
723 SCOPED_TSAN_INTERCEPTOR(pvalloc, sz);
724 sz = RoundUp(sz, GetPageSizeCached());
725 return user_alloc(thr, pc, sz, GetPageSizeCached());
726 }
727
TSAN_INTERCEPTOR(int,posix_memalign,void ** memptr,uptr align,uptr sz)728 TSAN_INTERCEPTOR(int, posix_memalign, void **memptr, uptr align, uptr sz) {
729 SCOPED_TSAN_INTERCEPTOR(posix_memalign, memptr, align, sz);
730 *memptr = user_alloc(thr, pc, sz, align);
731 return 0;
732 }
733
734 // Used in thread-safe function static initialization.
__cxa_guard_acquire(atomic_uint32_t * g)735 extern "C" int INTERFACE_ATTRIBUTE __cxa_guard_acquire(atomic_uint32_t *g) {
736 SCOPED_INTERCEPTOR_RAW(__cxa_guard_acquire, g);
737 for (;;) {
738 u32 cmp = atomic_load(g, memory_order_acquire);
739 if (cmp == 0) {
740 if (atomic_compare_exchange_strong(g, &cmp, 1<<16, memory_order_relaxed))
741 return 1;
742 } else if (cmp == 1) {
743 Acquire(thr, pc, (uptr)g);
744 return 0;
745 } else {
746 internal_sched_yield();
747 }
748 }
749 }
750
__cxa_guard_release(atomic_uint32_t * g)751 extern "C" void INTERFACE_ATTRIBUTE __cxa_guard_release(atomic_uint32_t *g) {
752 SCOPED_INTERCEPTOR_RAW(__cxa_guard_release, g);
753 Release(thr, pc, (uptr)g);
754 atomic_store(g, 1, memory_order_release);
755 }
756
__cxa_guard_abort(atomic_uint32_t * g)757 extern "C" void INTERFACE_ATTRIBUTE __cxa_guard_abort(atomic_uint32_t *g) {
758 SCOPED_INTERCEPTOR_RAW(__cxa_guard_abort, g);
759 atomic_store(g, 0, memory_order_relaxed);
760 }
761
thread_finalize(void * v)762 static void thread_finalize(void *v) {
763 uptr iter = (uptr)v;
764 if (iter > 1) {
765 if (pthread_setspecific(g_thread_finalize_key, (void*)(iter - 1))) {
766 Printf("ThreadSanitizer: failed to set thread key\n");
767 Die();
768 }
769 return;
770 }
771 {
772 ScopedInRtl in_rtl;
773 ThreadState *thr = cur_thread();
774 ThreadFinish(thr);
775 SignalContext *sctx = thr->signal_ctx;
776 if (sctx) {
777 thr->signal_ctx = 0;
778 UnmapOrDie(sctx, sizeof(*sctx));
779 }
780 }
781 }
782
783
784 struct ThreadParam {
785 void* (*callback)(void *arg);
786 void *param;
787 atomic_uintptr_t tid;
788 };
789
__tsan_thread_start_func(void * arg)790 extern "C" void *__tsan_thread_start_func(void *arg) {
791 ThreadParam *p = (ThreadParam*)arg;
792 void* (*callback)(void *arg) = p->callback;
793 void *param = p->param;
794 int tid = 0;
795 {
796 ThreadState *thr = cur_thread();
797 ScopedInRtl in_rtl;
798 if (pthread_setspecific(g_thread_finalize_key, (void*)4)) {
799 Printf("ThreadSanitizer: failed to set thread key\n");
800 Die();
801 }
802 while ((tid = atomic_load(&p->tid, memory_order_acquire)) == 0)
803 pthread_yield();
804 atomic_store(&p->tid, 0, memory_order_release);
805 ThreadStart(thr, tid, GetTid());
806 CHECK_EQ(thr->in_rtl, 1);
807 }
808 void *res = callback(param);
809 // Prevent the callback from being tail called,
810 // it mixes up stack traces.
811 volatile int foo = 42;
812 foo++;
813 return res;
814 }
815
TSAN_INTERCEPTOR(int,pthread_create,void * th,void * attr,void * (* callback)(void *),void * param)816 TSAN_INTERCEPTOR(int, pthread_create,
817 void *th, void *attr, void *(*callback)(void*), void * param) {
818 SCOPED_TSAN_INTERCEPTOR(pthread_create, th, attr, callback, param);
819 __sanitizer_pthread_attr_t myattr;
820 if (attr == 0) {
821 pthread_attr_init(&myattr);
822 attr = &myattr;
823 }
824 int detached = 0;
825 pthread_attr_getdetachstate(attr, &detached);
826
827 #if defined(TSAN_DEBUG_OUTPUT)
828 int verbosity = (TSAN_DEBUG_OUTPUT);
829 #else
830 int verbosity = 0;
831 #endif
832 AdjustStackSizeLinux(attr, verbosity);
833
834 ThreadParam p;
835 p.callback = callback;
836 p.param = param;
837 atomic_store(&p.tid, 0, memory_order_relaxed);
838 int res = REAL(pthread_create)(th, attr, __tsan_thread_start_func, &p);
839 if (res == 0) {
840 int tid = ThreadCreate(thr, pc, *(uptr*)th, detached);
841 CHECK_NE(tid, 0);
842 atomic_store(&p.tid, tid, memory_order_release);
843 while (atomic_load(&p.tid, memory_order_acquire) != 0)
844 pthread_yield();
845 }
846 if (attr == &myattr)
847 pthread_attr_destroy(&myattr);
848 return res;
849 }
850
TSAN_INTERCEPTOR(int,pthread_join,void * th,void ** ret)851 TSAN_INTERCEPTOR(int, pthread_join, void *th, void **ret) {
852 SCOPED_TSAN_INTERCEPTOR(pthread_join, th, ret);
853 int tid = ThreadTid(thr, pc, (uptr)th);
854 int res = BLOCK_REAL(pthread_join)(th, ret);
855 if (res == 0) {
856 ThreadJoin(thr, pc, tid);
857 }
858 return res;
859 }
860
TSAN_INTERCEPTOR(int,pthread_detach,void * th)861 TSAN_INTERCEPTOR(int, pthread_detach, void *th) {
862 SCOPED_TSAN_INTERCEPTOR(pthread_detach, th);
863 int tid = ThreadTid(thr, pc, (uptr)th);
864 int res = REAL(pthread_detach)(th);
865 if (res == 0) {
866 ThreadDetach(thr, pc, tid);
867 }
868 return res;
869 }
870
TSAN_INTERCEPTOR(int,pthread_mutex_init,void * m,void * a)871 TSAN_INTERCEPTOR(int, pthread_mutex_init, void *m, void *a) {
872 SCOPED_TSAN_INTERCEPTOR(pthread_mutex_init, m, a);
873 int res = REAL(pthread_mutex_init)(m, a);
874 if (res == 0) {
875 bool recursive = false;
876 if (a) {
877 int type = 0;
878 if (pthread_mutexattr_gettype(a, &type) == 0)
879 recursive = (type == PTHREAD_MUTEX_RECURSIVE
880 || type == PTHREAD_MUTEX_RECURSIVE_NP);
881 }
882 MutexCreate(thr, pc, (uptr)m, false, recursive, false);
883 }
884 return res;
885 }
886
TSAN_INTERCEPTOR(int,pthread_mutex_destroy,void * m)887 TSAN_INTERCEPTOR(int, pthread_mutex_destroy, void *m) {
888 SCOPED_TSAN_INTERCEPTOR(pthread_mutex_destroy, m);
889 int res = REAL(pthread_mutex_destroy)(m);
890 if (res == 0 || res == EBUSY) {
891 MutexDestroy(thr, pc, (uptr)m);
892 }
893 return res;
894 }
895
TSAN_INTERCEPTOR(int,pthread_mutex_lock,void * m)896 TSAN_INTERCEPTOR(int, pthread_mutex_lock, void *m) {
897 SCOPED_TSAN_INTERCEPTOR(pthread_mutex_lock, m);
898 int res = REAL(pthread_mutex_lock)(m);
899 if (res == 0) {
900 MutexLock(thr, pc, (uptr)m);
901 }
902 return res;
903 }
904
TSAN_INTERCEPTOR(int,pthread_mutex_trylock,void * m)905 TSAN_INTERCEPTOR(int, pthread_mutex_trylock, void *m) {
906 SCOPED_TSAN_INTERCEPTOR(pthread_mutex_trylock, m);
907 int res = REAL(pthread_mutex_trylock)(m);
908 if (res == 0) {
909 MutexLock(thr, pc, (uptr)m);
910 }
911 return res;
912 }
913
TSAN_INTERCEPTOR(int,pthread_mutex_timedlock,void * m,void * abstime)914 TSAN_INTERCEPTOR(int, pthread_mutex_timedlock, void *m, void *abstime) {
915 SCOPED_TSAN_INTERCEPTOR(pthread_mutex_timedlock, m, abstime);
916 int res = REAL(pthread_mutex_timedlock)(m, abstime);
917 if (res == 0) {
918 MutexLock(thr, pc, (uptr)m);
919 }
920 return res;
921 }
922
TSAN_INTERCEPTOR(int,pthread_mutex_unlock,void * m)923 TSAN_INTERCEPTOR(int, pthread_mutex_unlock, void *m) {
924 SCOPED_TSAN_INTERCEPTOR(pthread_mutex_unlock, m);
925 MutexUnlock(thr, pc, (uptr)m);
926 int res = REAL(pthread_mutex_unlock)(m);
927 return res;
928 }
929
TSAN_INTERCEPTOR(int,pthread_spin_init,void * m,int pshared)930 TSAN_INTERCEPTOR(int, pthread_spin_init, void *m, int pshared) {
931 SCOPED_TSAN_INTERCEPTOR(pthread_spin_init, m, pshared);
932 int res = REAL(pthread_spin_init)(m, pshared);
933 if (res == 0) {
934 MutexCreate(thr, pc, (uptr)m, false, false, false);
935 }
936 return res;
937 }
938
TSAN_INTERCEPTOR(int,pthread_spin_destroy,void * m)939 TSAN_INTERCEPTOR(int, pthread_spin_destroy, void *m) {
940 SCOPED_TSAN_INTERCEPTOR(pthread_spin_destroy, m);
941 int res = REAL(pthread_spin_destroy)(m);
942 if (res == 0) {
943 MutexDestroy(thr, pc, (uptr)m);
944 }
945 return res;
946 }
947
TSAN_INTERCEPTOR(int,pthread_spin_lock,void * m)948 TSAN_INTERCEPTOR(int, pthread_spin_lock, void *m) {
949 SCOPED_TSAN_INTERCEPTOR(pthread_spin_lock, m);
950 int res = REAL(pthread_spin_lock)(m);
951 if (res == 0) {
952 MutexLock(thr, pc, (uptr)m);
953 }
954 return res;
955 }
956
TSAN_INTERCEPTOR(int,pthread_spin_trylock,void * m)957 TSAN_INTERCEPTOR(int, pthread_spin_trylock, void *m) {
958 SCOPED_TSAN_INTERCEPTOR(pthread_spin_trylock, m);
959 int res = REAL(pthread_spin_trylock)(m);
960 if (res == 0) {
961 MutexLock(thr, pc, (uptr)m);
962 }
963 return res;
964 }
965
TSAN_INTERCEPTOR(int,pthread_spin_unlock,void * m)966 TSAN_INTERCEPTOR(int, pthread_spin_unlock, void *m) {
967 SCOPED_TSAN_INTERCEPTOR(pthread_spin_unlock, m);
968 MutexUnlock(thr, pc, (uptr)m);
969 int res = REAL(pthread_spin_unlock)(m);
970 return res;
971 }
972
TSAN_INTERCEPTOR(int,pthread_rwlock_init,void * m,void * a)973 TSAN_INTERCEPTOR(int, pthread_rwlock_init, void *m, void *a) {
974 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_init, m, a);
975 int res = REAL(pthread_rwlock_init)(m, a);
976 if (res == 0) {
977 MutexCreate(thr, pc, (uptr)m, true, false, false);
978 }
979 return res;
980 }
981
TSAN_INTERCEPTOR(int,pthread_rwlock_destroy,void * m)982 TSAN_INTERCEPTOR(int, pthread_rwlock_destroy, void *m) {
983 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_destroy, m);
984 int res = REAL(pthread_rwlock_destroy)(m);
985 if (res == 0) {
986 MutexDestroy(thr, pc, (uptr)m);
987 }
988 return res;
989 }
990
TSAN_INTERCEPTOR(int,pthread_rwlock_rdlock,void * m)991 TSAN_INTERCEPTOR(int, pthread_rwlock_rdlock, void *m) {
992 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_rdlock, m);
993 int res = REAL(pthread_rwlock_rdlock)(m);
994 if (res == 0) {
995 MutexReadLock(thr, pc, (uptr)m);
996 }
997 return res;
998 }
999
TSAN_INTERCEPTOR(int,pthread_rwlock_tryrdlock,void * m)1000 TSAN_INTERCEPTOR(int, pthread_rwlock_tryrdlock, void *m) {
1001 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_tryrdlock, m);
1002 int res = REAL(pthread_rwlock_tryrdlock)(m);
1003 if (res == 0) {
1004 MutexReadLock(thr, pc, (uptr)m);
1005 }
1006 return res;
1007 }
1008
TSAN_INTERCEPTOR(int,pthread_rwlock_timedrdlock,void * m,void * abstime)1009 TSAN_INTERCEPTOR(int, pthread_rwlock_timedrdlock, void *m, void *abstime) {
1010 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_timedrdlock, m, abstime);
1011 int res = REAL(pthread_rwlock_timedrdlock)(m, abstime);
1012 if (res == 0) {
1013 MutexReadLock(thr, pc, (uptr)m);
1014 }
1015 return res;
1016 }
1017
TSAN_INTERCEPTOR(int,pthread_rwlock_wrlock,void * m)1018 TSAN_INTERCEPTOR(int, pthread_rwlock_wrlock, void *m) {
1019 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_wrlock, m);
1020 int res = REAL(pthread_rwlock_wrlock)(m);
1021 if (res == 0) {
1022 MutexLock(thr, pc, (uptr)m);
1023 }
1024 return res;
1025 }
1026
TSAN_INTERCEPTOR(int,pthread_rwlock_trywrlock,void * m)1027 TSAN_INTERCEPTOR(int, pthread_rwlock_trywrlock, void *m) {
1028 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_trywrlock, m);
1029 int res = REAL(pthread_rwlock_trywrlock)(m);
1030 if (res == 0) {
1031 MutexLock(thr, pc, (uptr)m);
1032 }
1033 return res;
1034 }
1035
TSAN_INTERCEPTOR(int,pthread_rwlock_timedwrlock,void * m,void * abstime)1036 TSAN_INTERCEPTOR(int, pthread_rwlock_timedwrlock, void *m, void *abstime) {
1037 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_timedwrlock, m, abstime);
1038 int res = REAL(pthread_rwlock_timedwrlock)(m, abstime);
1039 if (res == 0) {
1040 MutexLock(thr, pc, (uptr)m);
1041 }
1042 return res;
1043 }
1044
TSAN_INTERCEPTOR(int,pthread_rwlock_unlock,void * m)1045 TSAN_INTERCEPTOR(int, pthread_rwlock_unlock, void *m) {
1046 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_unlock, m);
1047 MutexReadOrWriteUnlock(thr, pc, (uptr)m);
1048 int res = REAL(pthread_rwlock_unlock)(m);
1049 return res;
1050 }
1051
1052 // libpthread.so contains several versions of pthread_cond_init symbol.
1053 // When we just dlsym() it, we get the wrong (old) version.
1054 /*
1055 TSAN_INTERCEPTOR(int, pthread_cond_init, void *c, void *a) {
1056 SCOPED_TSAN_INTERCEPTOR(pthread_cond_init, c, a);
1057 int res = REAL(pthread_cond_init)(c, a);
1058 return res;
1059 }
1060 */
1061
TSAN_INTERCEPTOR(int,pthread_cond_destroy,void * c)1062 TSAN_INTERCEPTOR(int, pthread_cond_destroy, void *c) {
1063 SCOPED_TSAN_INTERCEPTOR(pthread_cond_destroy, c);
1064 int res = REAL(pthread_cond_destroy)(c);
1065 return res;
1066 }
1067
TSAN_INTERCEPTOR(int,pthread_cond_signal,void * c)1068 TSAN_INTERCEPTOR(int, pthread_cond_signal, void *c) {
1069 SCOPED_TSAN_INTERCEPTOR(pthread_cond_signal, c);
1070 int res = REAL(pthread_cond_signal)(c);
1071 return res;
1072 }
1073
TSAN_INTERCEPTOR(int,pthread_cond_broadcast,void * c)1074 TSAN_INTERCEPTOR(int, pthread_cond_broadcast, void *c) {
1075 SCOPED_TSAN_INTERCEPTOR(pthread_cond_broadcast, c);
1076 int res = REAL(pthread_cond_broadcast)(c);
1077 return res;
1078 }
1079
TSAN_INTERCEPTOR(int,pthread_cond_wait,void * c,void * m)1080 TSAN_INTERCEPTOR(int, pthread_cond_wait, void *c, void *m) {
1081 SCOPED_TSAN_INTERCEPTOR(pthread_cond_wait, c, m);
1082 MutexUnlock(thr, pc, (uptr)m);
1083 int res = REAL(pthread_cond_wait)(c, m);
1084 MutexLock(thr, pc, (uptr)m);
1085 return res;
1086 }
1087
TSAN_INTERCEPTOR(int,pthread_cond_timedwait,void * c,void * m,void * abstime)1088 TSAN_INTERCEPTOR(int, pthread_cond_timedwait, void *c, void *m, void *abstime) {
1089 SCOPED_TSAN_INTERCEPTOR(pthread_cond_timedwait, c, m, abstime);
1090 MutexUnlock(thr, pc, (uptr)m);
1091 int res = REAL(pthread_cond_timedwait)(c, m, abstime);
1092 MutexLock(thr, pc, (uptr)m);
1093 return res;
1094 }
1095
TSAN_INTERCEPTOR(int,pthread_barrier_init,void * b,void * a,unsigned count)1096 TSAN_INTERCEPTOR(int, pthread_barrier_init, void *b, void *a, unsigned count) {
1097 SCOPED_TSAN_INTERCEPTOR(pthread_barrier_init, b, a, count);
1098 MemoryWrite(thr, pc, (uptr)b, kSizeLog1);
1099 int res = REAL(pthread_barrier_init)(b, a, count);
1100 return res;
1101 }
1102
TSAN_INTERCEPTOR(int,pthread_barrier_destroy,void * b)1103 TSAN_INTERCEPTOR(int, pthread_barrier_destroy, void *b) {
1104 SCOPED_TSAN_INTERCEPTOR(pthread_barrier_destroy, b);
1105 MemoryWrite(thr, pc, (uptr)b, kSizeLog1);
1106 int res = REAL(pthread_barrier_destroy)(b);
1107 return res;
1108 }
1109
TSAN_INTERCEPTOR(int,pthread_barrier_wait,void * b)1110 TSAN_INTERCEPTOR(int, pthread_barrier_wait, void *b) {
1111 SCOPED_TSAN_INTERCEPTOR(pthread_barrier_wait, b);
1112 Release(thr, pc, (uptr)b);
1113 MemoryRead(thr, pc, (uptr)b, kSizeLog1);
1114 int res = REAL(pthread_barrier_wait)(b);
1115 MemoryRead(thr, pc, (uptr)b, kSizeLog1);
1116 if (res == 0 || res == PTHREAD_BARRIER_SERIAL_THREAD) {
1117 Acquire(thr, pc, (uptr)b);
1118 }
1119 return res;
1120 }
1121
TSAN_INTERCEPTOR(int,pthread_once,void * o,void (* f)())1122 TSAN_INTERCEPTOR(int, pthread_once, void *o, void (*f)()) {
1123 SCOPED_TSAN_INTERCEPTOR(pthread_once, o, f);
1124 if (o == 0 || f == 0)
1125 return EINVAL;
1126 atomic_uint32_t *a = static_cast<atomic_uint32_t*>(o);
1127 u32 v = atomic_load(a, memory_order_acquire);
1128 if (v == 0 && atomic_compare_exchange_strong(a, &v, 1,
1129 memory_order_relaxed)) {
1130 const int old_in_rtl = thr->in_rtl;
1131 thr->in_rtl = 0;
1132 (*f)();
1133 CHECK_EQ(thr->in_rtl, 0);
1134 thr->in_rtl = old_in_rtl;
1135 Release(thr, pc, (uptr)o);
1136 atomic_store(a, 2, memory_order_release);
1137 } else {
1138 while (v != 2) {
1139 pthread_yield();
1140 v = atomic_load(a, memory_order_acquire);
1141 }
1142 Acquire(thr, pc, (uptr)o);
1143 }
1144 return 0;
1145 }
1146
TSAN_INTERCEPTOR(int,sem_init,void * s,int pshared,unsigned value)1147 TSAN_INTERCEPTOR(int, sem_init, void *s, int pshared, unsigned value) {
1148 SCOPED_TSAN_INTERCEPTOR(sem_init, s, pshared, value);
1149 int res = REAL(sem_init)(s, pshared, value);
1150 return res;
1151 }
1152
TSAN_INTERCEPTOR(int,sem_destroy,void * s)1153 TSAN_INTERCEPTOR(int, sem_destroy, void *s) {
1154 SCOPED_TSAN_INTERCEPTOR(sem_destroy, s);
1155 int res = REAL(sem_destroy)(s);
1156 return res;
1157 }
1158
TSAN_INTERCEPTOR(int,sem_wait,void * s)1159 TSAN_INTERCEPTOR(int, sem_wait, void *s) {
1160 SCOPED_TSAN_INTERCEPTOR(sem_wait, s);
1161 int res = BLOCK_REAL(sem_wait)(s);
1162 if (res == 0) {
1163 Acquire(thr, pc, (uptr)s);
1164 }
1165 return res;
1166 }
1167
TSAN_INTERCEPTOR(int,sem_trywait,void * s)1168 TSAN_INTERCEPTOR(int, sem_trywait, void *s) {
1169 SCOPED_TSAN_INTERCEPTOR(sem_trywait, s);
1170 int res = BLOCK_REAL(sem_trywait)(s);
1171 if (res == 0) {
1172 Acquire(thr, pc, (uptr)s);
1173 }
1174 return res;
1175 }
1176
TSAN_INTERCEPTOR(int,sem_timedwait,void * s,void * abstime)1177 TSAN_INTERCEPTOR(int, sem_timedwait, void *s, void *abstime) {
1178 SCOPED_TSAN_INTERCEPTOR(sem_timedwait, s, abstime);
1179 int res = BLOCK_REAL(sem_timedwait)(s, abstime);
1180 if (res == 0) {
1181 Acquire(thr, pc, (uptr)s);
1182 }
1183 return res;
1184 }
1185
TSAN_INTERCEPTOR(int,sem_post,void * s)1186 TSAN_INTERCEPTOR(int, sem_post, void *s) {
1187 SCOPED_TSAN_INTERCEPTOR(sem_post, s);
1188 Release(thr, pc, (uptr)s);
1189 int res = REAL(sem_post)(s);
1190 return res;
1191 }
1192
TSAN_INTERCEPTOR(int,sem_getvalue,void * s,int * sval)1193 TSAN_INTERCEPTOR(int, sem_getvalue, void *s, int *sval) {
1194 SCOPED_TSAN_INTERCEPTOR(sem_getvalue, s, sval);
1195 int res = REAL(sem_getvalue)(s, sval);
1196 if (res == 0) {
1197 Acquire(thr, pc, (uptr)s);
1198 }
1199 return res;
1200 }
1201
TSAN_INTERCEPTOR(int,__xstat,int version,const char * path,void * buf)1202 TSAN_INTERCEPTOR(int, __xstat, int version, const char *path, void *buf) {
1203 SCOPED_TSAN_INTERCEPTOR(__xstat, version, path, buf);
1204 return REAL(__xstat)(version, path, buf);
1205 }
1206
TSAN_INTERCEPTOR(int,stat,const char * path,void * buf)1207 TSAN_INTERCEPTOR(int, stat, const char *path, void *buf) {
1208 SCOPED_TSAN_INTERCEPTOR(__xstat, 0, path, buf);
1209 return REAL(__xstat)(0, path, buf);
1210 }
1211
TSAN_INTERCEPTOR(int,__xstat64,int version,const char * path,void * buf)1212 TSAN_INTERCEPTOR(int, __xstat64, int version, const char *path, void *buf) {
1213 SCOPED_TSAN_INTERCEPTOR(__xstat64, version, path, buf);
1214 return REAL(__xstat64)(version, path, buf);
1215 }
1216
TSAN_INTERCEPTOR(int,stat64,const char * path,void * buf)1217 TSAN_INTERCEPTOR(int, stat64, const char *path, void *buf) {
1218 SCOPED_TSAN_INTERCEPTOR(__xstat64, 0, path, buf);
1219 return REAL(__xstat64)(0, path, buf);
1220 }
1221
TSAN_INTERCEPTOR(int,__lxstat,int version,const char * path,void * buf)1222 TSAN_INTERCEPTOR(int, __lxstat, int version, const char *path, void *buf) {
1223 SCOPED_TSAN_INTERCEPTOR(__lxstat, version, path, buf);
1224 return REAL(__lxstat)(version, path, buf);
1225 }
1226
TSAN_INTERCEPTOR(int,lstat,const char * path,void * buf)1227 TSAN_INTERCEPTOR(int, lstat, const char *path, void *buf) {
1228 SCOPED_TSAN_INTERCEPTOR(__lxstat, 0, path, buf);
1229 return REAL(__lxstat)(0, path, buf);
1230 }
1231
TSAN_INTERCEPTOR(int,__lxstat64,int version,const char * path,void * buf)1232 TSAN_INTERCEPTOR(int, __lxstat64, int version, const char *path, void *buf) {
1233 SCOPED_TSAN_INTERCEPTOR(__lxstat64, version, path, buf);
1234 return REAL(__lxstat64)(version, path, buf);
1235 }
1236
TSAN_INTERCEPTOR(int,lstat64,const char * path,void * buf)1237 TSAN_INTERCEPTOR(int, lstat64, const char *path, void *buf) {
1238 SCOPED_TSAN_INTERCEPTOR(__lxstat64, 0, path, buf);
1239 return REAL(__lxstat64)(0, path, buf);
1240 }
1241
TSAN_INTERCEPTOR(int,__fxstat,int version,int fd,void * buf)1242 TSAN_INTERCEPTOR(int, __fxstat, int version, int fd, void *buf) {
1243 SCOPED_TSAN_INTERCEPTOR(__fxstat, version, fd, buf);
1244 if (fd > 0)
1245 FdAccess(thr, pc, fd);
1246 return REAL(__fxstat)(version, fd, buf);
1247 }
1248
TSAN_INTERCEPTOR(int,fstat,int fd,void * buf)1249 TSAN_INTERCEPTOR(int, fstat, int fd, void *buf) {
1250 SCOPED_TSAN_INTERCEPTOR(__fxstat, 0, fd, buf);
1251 if (fd > 0)
1252 FdAccess(thr, pc, fd);
1253 return REAL(__fxstat)(0, fd, buf);
1254 }
1255
TSAN_INTERCEPTOR(int,__fxstat64,int version,int fd,void * buf)1256 TSAN_INTERCEPTOR(int, __fxstat64, int version, int fd, void *buf) {
1257 SCOPED_TSAN_INTERCEPTOR(__fxstat64, version, fd, buf);
1258 if (fd > 0)
1259 FdAccess(thr, pc, fd);
1260 return REAL(__fxstat64)(version, fd, buf);
1261 }
1262
TSAN_INTERCEPTOR(int,fstat64,int fd,void * buf)1263 TSAN_INTERCEPTOR(int, fstat64, int fd, void *buf) {
1264 SCOPED_TSAN_INTERCEPTOR(__fxstat64, 0, fd, buf);
1265 if (fd > 0)
1266 FdAccess(thr, pc, fd);
1267 return REAL(__fxstat64)(0, fd, buf);
1268 }
1269
TSAN_INTERCEPTOR(int,open,const char * name,int flags,int mode)1270 TSAN_INTERCEPTOR(int, open, const char *name, int flags, int mode) {
1271 SCOPED_TSAN_INTERCEPTOR(open, name, flags, mode);
1272 int fd = REAL(open)(name, flags, mode);
1273 if (fd >= 0)
1274 FdFileCreate(thr, pc, fd);
1275 return fd;
1276 }
1277
TSAN_INTERCEPTOR(int,open64,const char * name,int flags,int mode)1278 TSAN_INTERCEPTOR(int, open64, const char *name, int flags, int mode) {
1279 SCOPED_TSAN_INTERCEPTOR(open64, name, flags, mode);
1280 int fd = REAL(open64)(name, flags, mode);
1281 if (fd >= 0)
1282 FdFileCreate(thr, pc, fd);
1283 return fd;
1284 }
1285
TSAN_INTERCEPTOR(int,creat,const char * name,int mode)1286 TSAN_INTERCEPTOR(int, creat, const char *name, int mode) {
1287 SCOPED_TSAN_INTERCEPTOR(creat, name, mode);
1288 int fd = REAL(creat)(name, mode);
1289 if (fd >= 0)
1290 FdFileCreate(thr, pc, fd);
1291 return fd;
1292 }
1293
TSAN_INTERCEPTOR(int,creat64,const char * name,int mode)1294 TSAN_INTERCEPTOR(int, creat64, const char *name, int mode) {
1295 SCOPED_TSAN_INTERCEPTOR(creat64, name, mode);
1296 int fd = REAL(creat64)(name, mode);
1297 if (fd >= 0)
1298 FdFileCreate(thr, pc, fd);
1299 return fd;
1300 }
1301
TSAN_INTERCEPTOR(int,dup,int oldfd)1302 TSAN_INTERCEPTOR(int, dup, int oldfd) {
1303 SCOPED_TSAN_INTERCEPTOR(dup, oldfd);
1304 int newfd = REAL(dup)(oldfd);
1305 if (oldfd >= 0 && newfd >= 0 && newfd != oldfd)
1306 FdDup(thr, pc, oldfd, newfd);
1307 return newfd;
1308 }
1309
TSAN_INTERCEPTOR(int,dup2,int oldfd,int newfd)1310 TSAN_INTERCEPTOR(int, dup2, int oldfd, int newfd) {
1311 SCOPED_TSAN_INTERCEPTOR(dup2, oldfd, newfd);
1312 int newfd2 = REAL(dup2)(oldfd, newfd);
1313 if (oldfd >= 0 && newfd2 >= 0 && newfd2 != oldfd)
1314 FdDup(thr, pc, oldfd, newfd2);
1315 return newfd2;
1316 }
1317
TSAN_INTERCEPTOR(int,dup3,int oldfd,int newfd,int flags)1318 TSAN_INTERCEPTOR(int, dup3, int oldfd, int newfd, int flags) {
1319 SCOPED_TSAN_INTERCEPTOR(dup3, oldfd, newfd, flags);
1320 int newfd2 = REAL(dup3)(oldfd, newfd, flags);
1321 if (oldfd >= 0 && newfd2 >= 0 && newfd2 != oldfd)
1322 FdDup(thr, pc, oldfd, newfd2);
1323 return newfd2;
1324 }
1325
TSAN_INTERCEPTOR(int,eventfd,unsigned initval,int flags)1326 TSAN_INTERCEPTOR(int, eventfd, unsigned initval, int flags) {
1327 SCOPED_TSAN_INTERCEPTOR(eventfd, initval, flags);
1328 int fd = REAL(eventfd)(initval, flags);
1329 if (fd >= 0)
1330 FdEventCreate(thr, pc, fd);
1331 return fd;
1332 }
1333
TSAN_INTERCEPTOR(int,signalfd,int fd,void * mask,int flags)1334 TSAN_INTERCEPTOR(int, signalfd, int fd, void *mask, int flags) {
1335 SCOPED_TSAN_INTERCEPTOR(signalfd, fd, mask, flags);
1336 if (fd >= 0)
1337 FdClose(thr, pc, fd);
1338 fd = REAL(signalfd)(fd, mask, flags);
1339 if (fd >= 0)
1340 FdSignalCreate(thr, pc, fd);
1341 return fd;
1342 }
1343
TSAN_INTERCEPTOR(int,inotify_init,int fake)1344 TSAN_INTERCEPTOR(int, inotify_init, int fake) {
1345 SCOPED_TSAN_INTERCEPTOR(inotify_init, fake);
1346 int fd = REAL(inotify_init)(fake);
1347 if (fd >= 0)
1348 FdInotifyCreate(thr, pc, fd);
1349 return fd;
1350 }
1351
TSAN_INTERCEPTOR(int,inotify_init1,int flags)1352 TSAN_INTERCEPTOR(int, inotify_init1, int flags) {
1353 SCOPED_TSAN_INTERCEPTOR(inotify_init1, flags);
1354 int fd = REAL(inotify_init1)(flags);
1355 if (fd >= 0)
1356 FdInotifyCreate(thr, pc, fd);
1357 return fd;
1358 }
1359
TSAN_INTERCEPTOR(int,socket,int domain,int type,int protocol)1360 TSAN_INTERCEPTOR(int, socket, int domain, int type, int protocol) {
1361 SCOPED_TSAN_INTERCEPTOR(socket, domain, type, protocol);
1362 int fd = REAL(socket)(domain, type, protocol);
1363 if (fd >= 0)
1364 FdSocketCreate(thr, pc, fd);
1365 return fd;
1366 }
1367
TSAN_INTERCEPTOR(int,socketpair,int domain,int type,int protocol,int * fd)1368 TSAN_INTERCEPTOR(int, socketpair, int domain, int type, int protocol, int *fd) {
1369 SCOPED_TSAN_INTERCEPTOR(socketpair, domain, type, protocol, fd);
1370 int res = REAL(socketpair)(domain, type, protocol, fd);
1371 if (res == 0 && fd[0] >= 0 && fd[1] >= 0)
1372 FdPipeCreate(thr, pc, fd[0], fd[1]);
1373 return res;
1374 }
1375
TSAN_INTERCEPTOR(int,connect,int fd,void * addr,unsigned addrlen)1376 TSAN_INTERCEPTOR(int, connect, int fd, void *addr, unsigned addrlen) {
1377 SCOPED_TSAN_INTERCEPTOR(connect, fd, addr, addrlen);
1378 FdSocketConnecting(thr, pc, fd);
1379 int res = REAL(connect)(fd, addr, addrlen);
1380 if (res == 0 && fd >= 0)
1381 FdSocketConnect(thr, pc, fd);
1382 return res;
1383 }
1384
TSAN_INTERCEPTOR(int,bind,int fd,void * addr,unsigned addrlen)1385 TSAN_INTERCEPTOR(int, bind, int fd, void *addr, unsigned addrlen) {
1386 SCOPED_TSAN_INTERCEPTOR(bind, fd, addr, addrlen);
1387 int res = REAL(bind)(fd, addr, addrlen);
1388 if (fd > 0 && res == 0)
1389 FdAccess(thr, pc, fd);
1390 return res;
1391 }
1392
TSAN_INTERCEPTOR(int,listen,int fd,int backlog)1393 TSAN_INTERCEPTOR(int, listen, int fd, int backlog) {
1394 SCOPED_TSAN_INTERCEPTOR(listen, fd, backlog);
1395 int res = REAL(listen)(fd, backlog);
1396 if (fd > 0 && res == 0)
1397 FdAccess(thr, pc, fd);
1398 return res;
1399 }
1400
TSAN_INTERCEPTOR(int,epoll_create,int size)1401 TSAN_INTERCEPTOR(int, epoll_create, int size) {
1402 SCOPED_TSAN_INTERCEPTOR(epoll_create, size);
1403 int fd = REAL(epoll_create)(size);
1404 if (fd >= 0)
1405 FdPollCreate(thr, pc, fd);
1406 return fd;
1407 }
1408
TSAN_INTERCEPTOR(int,epoll_create1,int flags)1409 TSAN_INTERCEPTOR(int, epoll_create1, int flags) {
1410 SCOPED_TSAN_INTERCEPTOR(epoll_create1, flags);
1411 int fd = REAL(epoll_create1)(flags);
1412 if (fd >= 0)
1413 FdPollCreate(thr, pc, fd);
1414 return fd;
1415 }
1416
TSAN_INTERCEPTOR(int,close,int fd)1417 TSAN_INTERCEPTOR(int, close, int fd) {
1418 SCOPED_TSAN_INTERCEPTOR(close, fd);
1419 if (fd >= 0)
1420 FdClose(thr, pc, fd);
1421 return REAL(close)(fd);
1422 }
1423
TSAN_INTERCEPTOR(int,__close,int fd)1424 TSAN_INTERCEPTOR(int, __close, int fd) {
1425 SCOPED_TSAN_INTERCEPTOR(__close, fd);
1426 if (fd >= 0)
1427 FdClose(thr, pc, fd);
1428 return REAL(__close)(fd);
1429 }
1430
1431 // glibc guts
TSAN_INTERCEPTOR(void,__res_iclose,void * state,bool free_addr)1432 TSAN_INTERCEPTOR(void, __res_iclose, void *state, bool free_addr) {
1433 SCOPED_TSAN_INTERCEPTOR(__res_iclose, state, free_addr);
1434 int fds[64];
1435 int cnt = ExtractResolvFDs(state, fds, ARRAY_SIZE(fds));
1436 for (int i = 0; i < cnt; i++) {
1437 if (fds[i] > 0)
1438 FdClose(thr, pc, fds[i]);
1439 }
1440 REAL(__res_iclose)(state, free_addr);
1441 }
1442
TSAN_INTERCEPTOR(int,pipe,int * pipefd)1443 TSAN_INTERCEPTOR(int, pipe, int *pipefd) {
1444 SCOPED_TSAN_INTERCEPTOR(pipe, pipefd);
1445 int res = REAL(pipe)(pipefd);
1446 if (res == 0 && pipefd[0] >= 0 && pipefd[1] >= 0)
1447 FdPipeCreate(thr, pc, pipefd[0], pipefd[1]);
1448 return res;
1449 }
1450
TSAN_INTERCEPTOR(int,pipe2,int * pipefd,int flags)1451 TSAN_INTERCEPTOR(int, pipe2, int *pipefd, int flags) {
1452 SCOPED_TSAN_INTERCEPTOR(pipe2, pipefd, flags);
1453 int res = REAL(pipe2)(pipefd, flags);
1454 if (res == 0 && pipefd[0] >= 0 && pipefd[1] >= 0)
1455 FdPipeCreate(thr, pc, pipefd[0], pipefd[1]);
1456 return res;
1457 }
1458
TSAN_INTERCEPTOR(long_t,send,int fd,void * buf,long_t len,int flags)1459 TSAN_INTERCEPTOR(long_t, send, int fd, void *buf, long_t len, int flags) {
1460 SCOPED_TSAN_INTERCEPTOR(send, fd, buf, len, flags);
1461 if (fd >= 0)
1462 FdRelease(thr, pc, fd);
1463 int res = REAL(send)(fd, buf, len, flags);
1464 return res;
1465 }
1466
TSAN_INTERCEPTOR(long_t,sendmsg,int fd,void * msg,int flags)1467 TSAN_INTERCEPTOR(long_t, sendmsg, int fd, void *msg, int flags) {
1468 SCOPED_TSAN_INTERCEPTOR(sendmsg, fd, msg, flags);
1469 if (fd >= 0)
1470 FdRelease(thr, pc, fd);
1471 int res = REAL(sendmsg)(fd, msg, flags);
1472 return res;
1473 }
1474
TSAN_INTERCEPTOR(long_t,recv,int fd,void * buf,long_t len,int flags)1475 TSAN_INTERCEPTOR(long_t, recv, int fd, void *buf, long_t len, int flags) {
1476 SCOPED_TSAN_INTERCEPTOR(recv, fd, buf, len, flags);
1477 int res = REAL(recv)(fd, buf, len, flags);
1478 if (res >= 0 && fd >= 0) {
1479 FdAcquire(thr, pc, fd);
1480 }
1481 return res;
1482 }
1483
TSAN_INTERCEPTOR(int,unlink,char * path)1484 TSAN_INTERCEPTOR(int, unlink, char *path) {
1485 SCOPED_TSAN_INTERCEPTOR(unlink, path);
1486 Release(thr, pc, File2addr(path));
1487 int res = REAL(unlink)(path);
1488 return res;
1489 }
1490
TSAN_INTERCEPTOR(void *,fopen,char * path,char * mode)1491 TSAN_INTERCEPTOR(void*, fopen, char *path, char *mode) {
1492 SCOPED_TSAN_INTERCEPTOR(fopen, path, mode);
1493 void *res = REAL(fopen)(path, mode);
1494 Acquire(thr, pc, File2addr(path));
1495 if (res) {
1496 int fd = fileno_unlocked(res);
1497 if (fd >= 0)
1498 FdFileCreate(thr, pc, fd);
1499 }
1500 return res;
1501 }
1502
TSAN_INTERCEPTOR(void *,freopen,char * path,char * mode,void * stream)1503 TSAN_INTERCEPTOR(void*, freopen, char *path, char *mode, void *stream) {
1504 SCOPED_TSAN_INTERCEPTOR(freopen, path, mode, stream);
1505 if (stream) {
1506 int fd = fileno_unlocked(stream);
1507 if (fd >= 0)
1508 FdClose(thr, pc, fd);
1509 }
1510 void *res = REAL(freopen)(path, mode, stream);
1511 Acquire(thr, pc, File2addr(path));
1512 if (res) {
1513 int fd = fileno_unlocked(res);
1514 if (fd >= 0)
1515 FdFileCreate(thr, pc, fd);
1516 }
1517 return res;
1518 }
1519
TSAN_INTERCEPTOR(int,fclose,void * stream)1520 TSAN_INTERCEPTOR(int, fclose, void *stream) {
1521 {
1522 SCOPED_TSAN_INTERCEPTOR(fclose, stream);
1523 if (stream) {
1524 int fd = fileno_unlocked(stream);
1525 if (fd >= 0)
1526 FdClose(thr, pc, fd);
1527 }
1528 }
1529 return REAL(fclose)(stream);
1530 }
1531
TSAN_INTERCEPTOR(uptr,fread,void * ptr,uptr size,uptr nmemb,void * f)1532 TSAN_INTERCEPTOR(uptr, fread, void *ptr, uptr size, uptr nmemb, void *f) {
1533 {
1534 SCOPED_TSAN_INTERCEPTOR(fread, ptr, size, nmemb, f);
1535 MemoryAccessRange(thr, pc, (uptr)ptr, size * nmemb, true);
1536 }
1537 return REAL(fread)(ptr, size, nmemb, f);
1538 }
1539
TSAN_INTERCEPTOR(uptr,fwrite,const void * p,uptr size,uptr nmemb,void * f)1540 TSAN_INTERCEPTOR(uptr, fwrite, const void *p, uptr size, uptr nmemb, void *f) {
1541 {
1542 SCOPED_TSAN_INTERCEPTOR(fwrite, p, size, nmemb, f);
1543 MemoryAccessRange(thr, pc, (uptr)p, size * nmemb, false);
1544 }
1545 return REAL(fwrite)(p, size, nmemb, f);
1546 }
1547
TSAN_INTERCEPTOR(int,fflush,void * stream)1548 TSAN_INTERCEPTOR(int, fflush, void *stream) {
1549 SCOPED_TSAN_INTERCEPTOR(fflush, stream);
1550 return REAL(fflush)(stream);
1551 }
1552
TSAN_INTERCEPTOR(void,abort,int fake)1553 TSAN_INTERCEPTOR(void, abort, int fake) {
1554 SCOPED_TSAN_INTERCEPTOR(abort, fake);
1555 REAL(fflush)(0);
1556 REAL(abort)(fake);
1557 }
1558
TSAN_INTERCEPTOR(int,puts,const char * s)1559 TSAN_INTERCEPTOR(int, puts, const char *s) {
1560 SCOPED_TSAN_INTERCEPTOR(puts, s);
1561 MemoryAccessRange(thr, pc, (uptr)s, internal_strlen(s), false);
1562 return REAL(puts)(s);
1563 }
1564
TSAN_INTERCEPTOR(int,rmdir,char * path)1565 TSAN_INTERCEPTOR(int, rmdir, char *path) {
1566 SCOPED_TSAN_INTERCEPTOR(rmdir, path);
1567 Release(thr, pc, Dir2addr(path));
1568 int res = REAL(rmdir)(path);
1569 return res;
1570 }
1571
TSAN_INTERCEPTOR(void *,opendir,char * path)1572 TSAN_INTERCEPTOR(void*, opendir, char *path) {
1573 SCOPED_TSAN_INTERCEPTOR(opendir, path);
1574 void *res = REAL(opendir)(path);
1575 if (res != 0)
1576 Acquire(thr, pc, Dir2addr(path));
1577 return res;
1578 }
1579
TSAN_INTERCEPTOR(int,epoll_ctl,int epfd,int op,int fd,void * ev)1580 TSAN_INTERCEPTOR(int, epoll_ctl, int epfd, int op, int fd, void *ev) {
1581 SCOPED_TSAN_INTERCEPTOR(epoll_ctl, epfd, op, fd, ev);
1582 if (op == EPOLL_CTL_ADD && epfd >= 0) {
1583 FdRelease(thr, pc, epfd);
1584 }
1585 int res = REAL(epoll_ctl)(epfd, op, fd, ev);
1586 if (fd >= 0)
1587 FdAccess(thr, pc, fd);
1588 return res;
1589 }
1590
TSAN_INTERCEPTOR(int,epoll_wait,int epfd,void * ev,int cnt,int timeout)1591 TSAN_INTERCEPTOR(int, epoll_wait, int epfd, void *ev, int cnt, int timeout) {
1592 SCOPED_TSAN_INTERCEPTOR(epoll_wait, epfd, ev, cnt, timeout);
1593 int res = BLOCK_REAL(epoll_wait)(epfd, ev, cnt, timeout);
1594 if (res > 0 && epfd >= 0) {
1595 FdAcquire(thr, pc, epfd);
1596 }
1597 return res;
1598 }
1599
TSAN_INTERCEPTOR(int,poll,void * fds,long_t nfds,int timeout)1600 TSAN_INTERCEPTOR(int, poll, void *fds, long_t nfds, int timeout) {
1601 SCOPED_TSAN_INTERCEPTOR(poll, fds, nfds, timeout);
1602 int res = BLOCK_REAL(poll)(fds, nfds, timeout);
1603 return res;
1604 }
1605
rtl_generic_sighandler(bool sigact,int sig,my_siginfo_t * info,void * ctx)1606 void ALWAYS_INLINE rtl_generic_sighandler(bool sigact, int sig,
1607 my_siginfo_t *info, void *ctx) {
1608 ThreadState *thr = cur_thread();
1609 SignalContext *sctx = SigCtx(thr);
1610 // Don't mess with synchronous signals.
1611 if (sig == SIGSEGV || sig == SIGBUS || sig == SIGILL ||
1612 sig == SIGABRT || sig == SIGFPE || sig == SIGPIPE || sig == SIGSYS ||
1613 // If we are sending signal to ourselves, we must process it now.
1614 (sctx && sig == sctx->int_signal_send) ||
1615 // If we are in blocking function, we can safely process it now
1616 // (but check if we are in a recursive interceptor,
1617 // i.e. pthread_join()->munmap()).
1618 (sctx && sctx->in_blocking_func == 1 && thr->in_rtl == 1)) {
1619 int in_rtl = thr->in_rtl;
1620 thr->in_rtl = 0;
1621 CHECK_EQ(thr->in_signal_handler, false);
1622 thr->in_signal_handler = true;
1623 if (sigact)
1624 sigactions[sig].sa_sigaction(sig, info, ctx);
1625 else
1626 sigactions[sig].sa_handler(sig);
1627 CHECK_EQ(thr->in_signal_handler, true);
1628 thr->in_signal_handler = false;
1629 thr->in_rtl = in_rtl;
1630 return;
1631 }
1632
1633 if (sctx == 0)
1634 return;
1635 SignalDesc *signal = &sctx->pending_signals[sig];
1636 if (signal->armed == false) {
1637 signal->armed = true;
1638 signal->sigaction = sigact;
1639 if (info)
1640 internal_memcpy(&signal->siginfo, info, sizeof(*info));
1641 if (ctx)
1642 internal_memcpy(&signal->ctx, ctx, sizeof(signal->ctx));
1643 sctx->pending_signal_count++;
1644 }
1645 }
1646
rtl_sighandler(int sig)1647 static void rtl_sighandler(int sig) {
1648 rtl_generic_sighandler(false, sig, 0, 0);
1649 }
1650
rtl_sigaction(int sig,my_siginfo_t * info,void * ctx)1651 static void rtl_sigaction(int sig, my_siginfo_t *info, void *ctx) {
1652 rtl_generic_sighandler(true, sig, info, ctx);
1653 }
1654
TSAN_INTERCEPTOR(int,sigaction,int sig,sigaction_t * act,sigaction_t * old)1655 TSAN_INTERCEPTOR(int, sigaction, int sig, sigaction_t *act, sigaction_t *old) {
1656 SCOPED_TSAN_INTERCEPTOR(sigaction, sig, act, old);
1657 if (old)
1658 internal_memcpy(old, &sigactions[sig], sizeof(*old));
1659 if (act == 0)
1660 return 0;
1661 internal_memcpy(&sigactions[sig], act, sizeof(*act));
1662 sigaction_t newact;
1663 internal_memcpy(&newact, act, sizeof(newact));
1664 sigfillset(&newact.sa_mask);
1665 if (act->sa_handler != SIG_IGN && act->sa_handler != SIG_DFL) {
1666 if (newact.sa_flags & SA_SIGINFO)
1667 newact.sa_sigaction = rtl_sigaction;
1668 else
1669 newact.sa_handler = rtl_sighandler;
1670 }
1671 int res = REAL(sigaction)(sig, &newact, 0);
1672 return res;
1673 }
1674
TSAN_INTERCEPTOR(sighandler_t,signal,int sig,sighandler_t h)1675 TSAN_INTERCEPTOR(sighandler_t, signal, int sig, sighandler_t h) {
1676 sigaction_t act;
1677 act.sa_handler = h;
1678 REAL(memset)(&act.sa_mask, -1, sizeof(act.sa_mask));
1679 act.sa_flags = 0;
1680 sigaction_t old;
1681 int res = sigaction(sig, &act, &old);
1682 if (res)
1683 return SIG_ERR;
1684 return old.sa_handler;
1685 }
1686
TSAN_INTERCEPTOR(int,sigsuspend,const sigset_t * mask)1687 TSAN_INTERCEPTOR(int, sigsuspend, const sigset_t *mask) {
1688 SCOPED_TSAN_INTERCEPTOR(sigsuspend, mask);
1689 return REAL(sigsuspend)(mask);
1690 }
1691
TSAN_INTERCEPTOR(int,raise,int sig)1692 TSAN_INTERCEPTOR(int, raise, int sig) {
1693 SCOPED_TSAN_INTERCEPTOR(raise, sig);
1694 SignalContext *sctx = SigCtx(thr);
1695 CHECK_NE(sctx, 0);
1696 int prev = sctx->int_signal_send;
1697 sctx->int_signal_send = sig;
1698 int res = REAL(raise)(sig);
1699 CHECK_EQ(sctx->int_signal_send, sig);
1700 sctx->int_signal_send = prev;
1701 return res;
1702 }
1703
TSAN_INTERCEPTOR(int,kill,int pid,int sig)1704 TSAN_INTERCEPTOR(int, kill, int pid, int sig) {
1705 SCOPED_TSAN_INTERCEPTOR(kill, pid, sig);
1706 SignalContext *sctx = SigCtx(thr);
1707 CHECK_NE(sctx, 0);
1708 int prev = sctx->int_signal_send;
1709 if (pid == (int)internal_getpid()) {
1710 sctx->int_signal_send = sig;
1711 }
1712 int res = REAL(kill)(pid, sig);
1713 if (pid == (int)internal_getpid()) {
1714 CHECK_EQ(sctx->int_signal_send, sig);
1715 sctx->int_signal_send = prev;
1716 }
1717 return res;
1718 }
1719
TSAN_INTERCEPTOR(int,pthread_kill,void * tid,int sig)1720 TSAN_INTERCEPTOR(int, pthread_kill, void *tid, int sig) {
1721 SCOPED_TSAN_INTERCEPTOR(pthread_kill, tid, sig);
1722 SignalContext *sctx = SigCtx(thr);
1723 CHECK_NE(sctx, 0);
1724 int prev = sctx->int_signal_send;
1725 if (tid == pthread_self()) {
1726 sctx->int_signal_send = sig;
1727 }
1728 int res = REAL(pthread_kill)(tid, sig);
1729 if (tid == pthread_self()) {
1730 CHECK_EQ(sctx->int_signal_send, sig);
1731 sctx->int_signal_send = prev;
1732 }
1733 return res;
1734 }
1735
TSAN_INTERCEPTOR(int,gettimeofday,void * tv,void * tz)1736 TSAN_INTERCEPTOR(int, gettimeofday, void *tv, void *tz) {
1737 SCOPED_TSAN_INTERCEPTOR(gettimeofday, tv, tz);
1738 // It's intercepted merely to process pending signals.
1739 return REAL(gettimeofday)(tv, tz);
1740 }
1741
1742 // Linux kernel has a bug that leads to kernel deadlock if a process
1743 // maps TBs of memory and then calls mlock().
MlockIsUnsupported()1744 static void MlockIsUnsupported() {
1745 static atomic_uint8_t printed;
1746 if (atomic_exchange(&printed, 1, memory_order_relaxed))
1747 return;
1748 if (flags()->verbosity > 0)
1749 Printf("INFO: ThreadSanitizer ignores mlock/mlockall/munlock/munlockall\n");
1750 }
1751
TSAN_INTERCEPTOR(int,mlock,const void * addr,uptr len)1752 TSAN_INTERCEPTOR(int, mlock, const void *addr, uptr len) {
1753 MlockIsUnsupported();
1754 return 0;
1755 }
1756
TSAN_INTERCEPTOR(int,munlock,const void * addr,uptr len)1757 TSAN_INTERCEPTOR(int, munlock, const void *addr, uptr len) {
1758 MlockIsUnsupported();
1759 return 0;
1760 }
1761
TSAN_INTERCEPTOR(int,mlockall,int flags)1762 TSAN_INTERCEPTOR(int, mlockall, int flags) {
1763 MlockIsUnsupported();
1764 return 0;
1765 }
1766
TSAN_INTERCEPTOR(int,munlockall,void)1767 TSAN_INTERCEPTOR(int, munlockall, void) {
1768 MlockIsUnsupported();
1769 return 0;
1770 }
1771
TSAN_INTERCEPTOR(int,fork,int fake)1772 TSAN_INTERCEPTOR(int, fork, int fake) {
1773 SCOPED_TSAN_INTERCEPTOR(fork, fake);
1774 // It's intercepted merely to process pending signals.
1775 int pid = REAL(fork)(fake);
1776 if (pid == 0) {
1777 // child
1778 FdOnFork(thr, pc);
1779 } else if (pid > 0) {
1780 // parent
1781 }
1782 return pid;
1783 }
1784
1785 struct TsanInterceptorContext {
1786 ThreadState *thr;
1787 const uptr caller_pc;
1788 const uptr pc;
1789 };
1790
1791 #include "sanitizer_common/sanitizer_platform_interceptors.h"
1792 // Causes interceptor recursion (getpwuid_r() calls fopen())
1793 #undef SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS
1794 #undef SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
1795 // Causes interceptor recursion (getaddrinfo() and fopen())
1796 #undef SANITIZER_INTERCEPT_GETADDRINFO
1797 #undef SANITIZER_INTERCEPT_GETNAMEINFO
1798 // Causes interceptor recursion (glob64() calls lstat64())
1799 #undef SANITIZER_INTERCEPT_GLOB
1800
1801 #define COMMON_INTERCEPTOR_UNPOISON_PARAM(ctx, count) \
1802 do { \
1803 } while (false)
1804 #define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
1805 MemoryAccessRange(((TsanInterceptorContext *)ctx)->thr, \
1806 ((TsanInterceptorContext *)ctx)->pc, (uptr)ptr, size, \
1807 true)
1808 #define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \
1809 MemoryAccessRange(((TsanInterceptorContext *) ctx)->thr, \
1810 ((TsanInterceptorContext *) ctx)->pc, (uptr) ptr, size, \
1811 false)
1812 #define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \
1813 SCOPED_TSAN_INTERCEPTOR(func, __VA_ARGS__); \
1814 TsanInterceptorContext _ctx = {thr, caller_pc, pc}; \
1815 ctx = (void *)&_ctx; \
1816 (void) ctx;
1817 #define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \
1818 FdAcquire(((TsanInterceptorContext *) ctx)->thr, pc, fd)
1819 #define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \
1820 FdRelease(((TsanInterceptorContext *) ctx)->thr, pc, fd)
1821 #define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \
1822 FdSocketAccept(((TsanInterceptorContext *) ctx)->thr, pc, fd, newfd)
1823 #define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) \
1824 ThreadSetName(((TsanInterceptorContext *) ctx)->thr, name)
1825 #include "sanitizer_common/sanitizer_common_interceptors.inc"
1826
1827 // FIXME: Implement these with MemoryAccessRange().
1828 #define COMMON_SYSCALL_PRE_READ_RANGE(p, s)
1829 #define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s)
1830 #define COMMON_SYSCALL_POST_READ_RANGE(p, s)
1831 #define COMMON_SYSCALL_POST_WRITE_RANGE(p, s)
1832 #include "sanitizer_common/sanitizer_common_syscalls.inc"
1833
1834 namespace __tsan {
1835
ProcessPendingSignals(ThreadState * thr)1836 void ProcessPendingSignals(ThreadState *thr) {
1837 CHECK_EQ(thr->in_rtl, 0);
1838 SignalContext *sctx = SigCtx(thr);
1839 if (sctx == 0 || sctx->pending_signal_count == 0 || thr->in_signal_handler)
1840 return;
1841 Context *ctx = CTX();
1842 thr->in_signal_handler = true;
1843 sctx->pending_signal_count = 0;
1844 // These are too big for stack.
1845 static THREADLOCAL sigset_t emptyset, oldset;
1846 sigfillset(&emptyset);
1847 pthread_sigmask(SIG_SETMASK, &emptyset, &oldset);
1848 for (int sig = 0; sig < kSigCount; sig++) {
1849 SignalDesc *signal = &sctx->pending_signals[sig];
1850 if (signal->armed) {
1851 signal->armed = false;
1852 if (sigactions[sig].sa_handler != SIG_DFL
1853 && sigactions[sig].sa_handler != SIG_IGN) {
1854 // Insure that the handler does not spoil errno.
1855 const int saved_errno = errno;
1856 errno = 0;
1857 if (signal->sigaction)
1858 sigactions[sig].sa_sigaction(sig, &signal->siginfo, &signal->ctx);
1859 else
1860 sigactions[sig].sa_handler(sig);
1861 if (flags()->report_bugs && errno != 0) {
1862 ScopedInRtl in_rtl;
1863 __tsan::StackTrace stack;
1864 uptr pc = signal->sigaction ?
1865 (uptr)sigactions[sig].sa_sigaction :
1866 (uptr)sigactions[sig].sa_handler;
1867 pc += 1; // return address is expected, OutputReport() will undo this
1868 stack.Init(&pc, 1);
1869 ThreadRegistryLock l(ctx->thread_registry);
1870 ScopedReport rep(ReportTypeErrnoInSignal);
1871 if (!IsFiredSuppression(ctx, rep, stack)) {
1872 rep.AddStack(&stack);
1873 OutputReport(ctx, rep, rep.GetReport()->stacks[0]);
1874 }
1875 }
1876 errno = saved_errno;
1877 }
1878 }
1879 }
1880 pthread_sigmask(SIG_SETMASK, &oldset, 0);
1881 CHECK_EQ(thr->in_signal_handler, true);
1882 thr->in_signal_handler = false;
1883 }
1884
finalize(void * arg)1885 static void finalize(void *arg) {
1886 ThreadState * thr = cur_thread();
1887 uptr pc = 0;
1888 atexit_ctx->exit(thr, pc);
1889 int status = Finalize(cur_thread());
1890 REAL(fflush)(0);
1891 if (status)
1892 _exit(status);
1893 }
1894
unreachable()1895 static void unreachable() {
1896 Printf("FATAL: ThreadSanitizer: unreachable called\n");
1897 Die();
1898 }
1899
InitializeInterceptors()1900 void InitializeInterceptors() {
1901 CHECK_GT(cur_thread()->in_rtl, 0);
1902
1903 // We need to setup it early, because functions like dlsym() can call it.
1904 REAL(memset) = internal_memset;
1905 REAL(memcpy) = internal_memcpy;
1906 REAL(memcmp) = internal_memcmp;
1907
1908 // Instruct libc malloc to consume less memory.
1909 mallopt(1, 0); // M_MXFAST
1910 mallopt(-3, 32*1024); // M_MMAP_THRESHOLD
1911
1912 SANITIZER_COMMON_INTERCEPTORS_INIT;
1913
1914 TSAN_INTERCEPT(setjmp);
1915 TSAN_INTERCEPT(_setjmp);
1916 TSAN_INTERCEPT(sigsetjmp);
1917 TSAN_INTERCEPT(__sigsetjmp);
1918 TSAN_INTERCEPT(longjmp);
1919 TSAN_INTERCEPT(siglongjmp);
1920
1921 TSAN_INTERCEPT(malloc);
1922 TSAN_INTERCEPT(__libc_memalign);
1923 TSAN_INTERCEPT(calloc);
1924 TSAN_INTERCEPT(realloc);
1925 TSAN_INTERCEPT(free);
1926 TSAN_INTERCEPT(cfree);
1927 TSAN_INTERCEPT(mmap);
1928 TSAN_INTERCEPT(mmap64);
1929 TSAN_INTERCEPT(munmap);
1930 TSAN_INTERCEPT(memalign);
1931 TSAN_INTERCEPT(valloc);
1932 TSAN_INTERCEPT(pvalloc);
1933 TSAN_INTERCEPT(posix_memalign);
1934
1935 TSAN_INTERCEPT(strlen);
1936 TSAN_INTERCEPT(memset);
1937 TSAN_INTERCEPT(memcpy);
1938 TSAN_INTERCEPT(memchr);
1939 TSAN_INTERCEPT(memrchr);
1940 TSAN_INTERCEPT(memmove);
1941 TSAN_INTERCEPT(memcmp);
1942 TSAN_INTERCEPT(strchr);
1943 TSAN_INTERCEPT(strchrnul);
1944 TSAN_INTERCEPT(strrchr);
1945 TSAN_INTERCEPT(strcpy); // NOLINT
1946 TSAN_INTERCEPT(strncpy);
1947 TSAN_INTERCEPT(strstr);
1948
1949 TSAN_INTERCEPT(pthread_create);
1950 TSAN_INTERCEPT(pthread_join);
1951 TSAN_INTERCEPT(pthread_detach);
1952
1953 TSAN_INTERCEPT(pthread_mutex_init);
1954 TSAN_INTERCEPT(pthread_mutex_destroy);
1955 TSAN_INTERCEPT(pthread_mutex_lock);
1956 TSAN_INTERCEPT(pthread_mutex_trylock);
1957 TSAN_INTERCEPT(pthread_mutex_timedlock);
1958 TSAN_INTERCEPT(pthread_mutex_unlock);
1959
1960 TSAN_INTERCEPT(pthread_spin_init);
1961 TSAN_INTERCEPT(pthread_spin_destroy);
1962 TSAN_INTERCEPT(pthread_spin_lock);
1963 TSAN_INTERCEPT(pthread_spin_trylock);
1964 TSAN_INTERCEPT(pthread_spin_unlock);
1965
1966 TSAN_INTERCEPT(pthread_rwlock_init);
1967 TSAN_INTERCEPT(pthread_rwlock_destroy);
1968 TSAN_INTERCEPT(pthread_rwlock_rdlock);
1969 TSAN_INTERCEPT(pthread_rwlock_tryrdlock);
1970 TSAN_INTERCEPT(pthread_rwlock_timedrdlock);
1971 TSAN_INTERCEPT(pthread_rwlock_wrlock);
1972 TSAN_INTERCEPT(pthread_rwlock_trywrlock);
1973 TSAN_INTERCEPT(pthread_rwlock_timedwrlock);
1974 TSAN_INTERCEPT(pthread_rwlock_unlock);
1975
1976 // TSAN_INTERCEPT(pthread_cond_init);
1977 TSAN_INTERCEPT(pthread_cond_destroy);
1978 TSAN_INTERCEPT(pthread_cond_signal);
1979 TSAN_INTERCEPT(pthread_cond_broadcast);
1980 TSAN_INTERCEPT(pthread_cond_wait);
1981 TSAN_INTERCEPT(pthread_cond_timedwait);
1982
1983 TSAN_INTERCEPT(pthread_barrier_init);
1984 TSAN_INTERCEPT(pthread_barrier_destroy);
1985 TSAN_INTERCEPT(pthread_barrier_wait);
1986
1987 TSAN_INTERCEPT(pthread_once);
1988
1989 TSAN_INTERCEPT(sem_init);
1990 TSAN_INTERCEPT(sem_destroy);
1991 TSAN_INTERCEPT(sem_wait);
1992 TSAN_INTERCEPT(sem_trywait);
1993 TSAN_INTERCEPT(sem_timedwait);
1994 TSAN_INTERCEPT(sem_post);
1995 TSAN_INTERCEPT(sem_getvalue);
1996
1997 TSAN_INTERCEPT(stat);
1998 TSAN_INTERCEPT(__xstat);
1999 TSAN_INTERCEPT(stat64);
2000 TSAN_INTERCEPT(__xstat64);
2001 TSAN_INTERCEPT(lstat);
2002 TSAN_INTERCEPT(__lxstat);
2003 TSAN_INTERCEPT(lstat64);
2004 TSAN_INTERCEPT(__lxstat64);
2005 TSAN_INTERCEPT(fstat);
2006 TSAN_INTERCEPT(__fxstat);
2007 TSAN_INTERCEPT(fstat64);
2008 TSAN_INTERCEPT(__fxstat64);
2009 TSAN_INTERCEPT(open);
2010 TSAN_INTERCEPT(open64);
2011 TSAN_INTERCEPT(creat);
2012 TSAN_INTERCEPT(creat64);
2013 TSAN_INTERCEPT(dup);
2014 TSAN_INTERCEPT(dup2);
2015 TSAN_INTERCEPT(dup3);
2016 TSAN_INTERCEPT(eventfd);
2017 TSAN_INTERCEPT(signalfd);
2018 TSAN_INTERCEPT(inotify_init);
2019 TSAN_INTERCEPT(inotify_init1);
2020 TSAN_INTERCEPT(socket);
2021 TSAN_INTERCEPT(socketpair);
2022 TSAN_INTERCEPT(connect);
2023 TSAN_INTERCEPT(bind);
2024 TSAN_INTERCEPT(listen);
2025 TSAN_INTERCEPT(epoll_create);
2026 TSAN_INTERCEPT(epoll_create1);
2027 TSAN_INTERCEPT(close);
2028 TSAN_INTERCEPT(__close);
2029 TSAN_INTERCEPT(__res_iclose);
2030 TSAN_INTERCEPT(pipe);
2031 TSAN_INTERCEPT(pipe2);
2032
2033 TSAN_INTERCEPT(send);
2034 TSAN_INTERCEPT(sendmsg);
2035 TSAN_INTERCEPT(recv);
2036
2037 TSAN_INTERCEPT(unlink);
2038 TSAN_INTERCEPT(fopen);
2039 TSAN_INTERCEPT(freopen);
2040 TSAN_INTERCEPT(fclose);
2041 TSAN_INTERCEPT(fread);
2042 TSAN_INTERCEPT(fwrite);
2043 TSAN_INTERCEPT(fflush);
2044 TSAN_INTERCEPT(abort);
2045 TSAN_INTERCEPT(puts);
2046 TSAN_INTERCEPT(rmdir);
2047 TSAN_INTERCEPT(opendir);
2048
2049 TSAN_INTERCEPT(epoll_ctl);
2050 TSAN_INTERCEPT(epoll_wait);
2051 TSAN_INTERCEPT(poll);
2052
2053 TSAN_INTERCEPT(sigaction);
2054 TSAN_INTERCEPT(signal);
2055 TSAN_INTERCEPT(sigsuspend);
2056 TSAN_INTERCEPT(raise);
2057 TSAN_INTERCEPT(kill);
2058 TSAN_INTERCEPT(pthread_kill);
2059 TSAN_INTERCEPT(sleep);
2060 TSAN_INTERCEPT(usleep);
2061 TSAN_INTERCEPT(nanosleep);
2062 TSAN_INTERCEPT(gettimeofday);
2063
2064 TSAN_INTERCEPT(mlock);
2065 TSAN_INTERCEPT(munlock);
2066 TSAN_INTERCEPT(mlockall);
2067 TSAN_INTERCEPT(munlockall);
2068
2069 TSAN_INTERCEPT(fork);
2070 TSAN_INTERCEPT(on_exit);
2071 TSAN_INTERCEPT(__cxa_atexit);
2072
2073 // Need to setup it, because interceptors check that the function is resolved.
2074 // But atexit is emitted directly into the module, so can't be resolved.
2075 REAL(atexit) = (int(*)(void(*)()))unreachable;
2076 atexit_ctx = new(internal_alloc(MBlockAtExit, sizeof(AtExitContext)))
2077 AtExitContext();
2078
2079 if (REAL(__cxa_atexit)(&finalize, 0, 0)) {
2080 Printf("ThreadSanitizer: failed to setup atexit callback\n");
2081 Die();
2082 }
2083
2084 if (pthread_key_create(&g_thread_finalize_key, &thread_finalize)) {
2085 Printf("ThreadSanitizer: failed to create thread key\n");
2086 Die();
2087 }
2088
2089 FdInit();
2090 }
2091
internal_start_thread(void (* func)(void * arg),void * arg)2092 void internal_start_thread(void(*func)(void *arg), void *arg) {
2093 void *th;
2094 REAL(pthread_create)(&th, 0, (void*(*)(void *arg))func, arg);
2095 REAL(pthread_detach)(th);
2096 }
2097
2098 } // namespace __tsan
2099