1 //===-- tsan_interceptors.cc ----------------------------------------------===//
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
6 //===----------------------------------------------------------------------===//
8 // This file is a part of ThreadSanitizer (TSan), a race detector.
10 // FIXME: move as many interceptors as possible into
11 // sanitizer_common/sanitizer_common_interceptors.inc
12 //===----------------------------------------------------------------------===//
14 #include "sanitizer_common/sanitizer_atomic.h"
15 #include "sanitizer_common/sanitizer_libc.h"
16 #include "sanitizer_common/sanitizer_linux.h"
17 #include "sanitizer_common/sanitizer_platform_limits_posix.h"
18 #include "sanitizer_common/sanitizer_placement_new.h"
19 #include "sanitizer_common/sanitizer_stacktrace.h"
20 #include "interception/interception.h"
21 #include "tsan_interface.h"
22 #include "tsan_platform.h"
23 #include "tsan_suppressions.h"
25 #include "tsan_mman.h"
28 using namespace __tsan
; // NOLINT
30 const int kSigCount
= 65;
33 // The size is determined by looking at sizeof of real siginfo_t on linux.
34 u64 opaque
[128 / sizeof(u64
)];
38 // The size is determined by looking at sizeof of real ucontext_t on linux.
39 u64 opaque
[936 / sizeof(u64
) + 1];
42 extern "C" int pthread_attr_init(void *attr
);
43 extern "C" int pthread_attr_destroy(void *attr
);
44 DECLARE_REAL(int, pthread_attr_getdetachstate
, void *, void *)
45 extern "C" int pthread_attr_setstacksize(void *attr
, uptr stacksize
);
46 extern "C" int pthread_key_create(unsigned *key
, void (*destructor
)(void* v
));
47 extern "C" int pthread_setspecific(unsigned key
, const void *v
);
48 DECLARE_REAL(int, pthread_mutexattr_gettype
, void *, void *)
49 extern "C" int pthread_yield();
50 extern "C" int pthread_sigmask(int how
, const __sanitizer_sigset_t
*set
,
51 __sanitizer_sigset_t
*oldset
);
52 // REAL(sigfillset) defined in common interceptors.
53 DECLARE_REAL(int, sigfillset
, __sanitizer_sigset_t
*set
)
54 DECLARE_REAL(int, fflush
, __sanitizer_FILE
*fp
)
55 extern "C" void *pthread_self();
56 extern "C" void _exit(int status
);
57 extern "C" int *__errno_location();
58 extern "C" int fileno_unlocked(void *stream
);
59 extern "C" void *__libc_malloc(uptr size
);
60 extern "C" void *__libc_calloc(uptr size
, uptr n
);
61 extern "C" void *__libc_realloc(void *ptr
, uptr size
);
62 extern "C" void __libc_free(void *ptr
);
63 extern "C" int mallopt(int param
, int value
);
64 extern __sanitizer_FILE
*stdout
, *stderr
;
65 const int PTHREAD_MUTEX_RECURSIVE
= 1;
66 const int PTHREAD_MUTEX_RECURSIVE_NP
= 1;
67 const int EINVAL
= 22;
69 const int EOWNERDEAD
= 130;
70 const int EPOLL_CTL_ADD
= 1;
72 const int SIGABRT
= 6;
74 const int SIGSEGV
= 11;
75 const int SIGPIPE
= 13;
76 const int SIGTERM
= 15;
78 const int SIGSYS
= 31;
79 void *const MAP_FAILED
= (void*)-1;
80 const int PTHREAD_BARRIER_SERIAL_THREAD
= -1;
81 const int MAP_FIXED
= 0x10;
82 typedef long long_t
; // NOLINT
84 // From /usr/include/unistd.h
85 # define F_ULOCK 0 /* Unlock a previously locked region. */
86 # define F_LOCK 1 /* Lock a region for exclusive use. */
87 # define F_TLOCK 2 /* Test and lock a region for exclusive use. */
88 # define F_TEST 3 /* Test a region for other processes locks. */
90 typedef void (*sighandler_t
)(int sig
);
92 #define errno (*__errno_location())
94 // 16K loaded modules should be enough for everyone.
95 static const uptr kMaxModules
= 1 << 14;
96 static LoadedModule
*modules
;
101 sighandler_t sa_handler
;
102 void (*sa_sigaction
)(int sig
, my_siginfo_t
*siginfo
, void *uctx
);
104 __sanitizer_sigset_t sa_mask
;
106 void (*sa_restorer
)();
109 const sighandler_t SIG_DFL
= (sighandler_t
)0;
110 const sighandler_t SIG_IGN
= (sighandler_t
)1;
111 const sighandler_t SIG_ERR
= (sighandler_t
)-1;
112 const int SA_SIGINFO
= 4;
113 const int SIG_SETMASK
= 2;
119 static sigaction_t sigactions
[kSigCount
];
125 my_siginfo_t siginfo
;
129 struct SignalContext
{
131 atomic_uintptr_t in_blocking_func
;
132 atomic_uintptr_t have_pending_signals
;
133 SignalDesc pending_signals
[kSigCount
];
136 // The object is 64-byte aligned, because we want hot data to be located in
137 // a single cache line if possible (it's accessed in every interceptor).
138 static ALIGNED(64) char libignore_placeholder
[sizeof(LibIgnore
)];
139 static LibIgnore
*libignore() {
140 return reinterpret_cast<LibIgnore
*>(&libignore_placeholder
[0]);
143 void InitializeLibIgnore() {
144 libignore()->Init(*SuppressionContext::Get());
145 libignore()->OnLibraryLoaded(0);
148 } // namespace __tsan
150 static SignalContext
*SigCtx(ThreadState
*thr
) {
151 SignalContext
*ctx
= (SignalContext
*)thr
->signal_ctx
;
152 if (ctx
== 0 && !thr
->is_dead
) {
153 ctx
= (SignalContext
*)MmapOrDie(sizeof(*ctx
), "SignalContext");
154 MemoryResetRange(thr
, (uptr
)&SigCtx
, (uptr
)ctx
, sizeof(*ctx
));
155 thr
->signal_ctx
= ctx
;
160 static unsigned g_thread_finalize_key
;
162 class ScopedInterceptor
{
164 ScopedInterceptor(ThreadState
*thr
, const char *fname
, uptr pc
);
165 ~ScopedInterceptor();
167 ThreadState
*const thr_
;
169 bool in_ignored_lib_
;
172 ScopedInterceptor::ScopedInterceptor(ThreadState
*thr
, const char *fname
,
176 , in_ignored_lib_(false) {
177 if (!thr_
->ignore_interceptors
) {
181 DPrintf("#%d: intercept %s()\n", thr_
->tid
, fname
);
182 if (!thr_
->in_ignored_lib
&& libignore()->IsIgnored(pc
)) {
183 in_ignored_lib_
= true;
184 thr_
->in_ignored_lib
= true;
185 ThreadIgnoreBegin(thr_
, pc_
);
189 ScopedInterceptor::~ScopedInterceptor() {
190 if (in_ignored_lib_
) {
191 thr_
->in_ignored_lib
= false;
192 ThreadIgnoreEnd(thr_
, pc_
);
194 if (!thr_
->ignore_interceptors
) {
195 ProcessPendingSignals(thr_
);
201 #define SCOPED_INTERCEPTOR_RAW(func, ...) \
202 ThreadState *thr = cur_thread(); \
203 const uptr caller_pc = GET_CALLER_PC(); \
204 ScopedInterceptor si(thr, #func, caller_pc); \
205 const uptr pc = __sanitizer::StackTrace::GetCurrentPc(); \
209 #define SCOPED_TSAN_INTERCEPTOR(func, ...) \
210 SCOPED_INTERCEPTOR_RAW(func, __VA_ARGS__); \
211 if (REAL(func) == 0) { \
212 Report("FATAL: ThreadSanitizer: failed to intercept %s\n", #func); \
215 if (thr->ignore_interceptors || thr->in_ignored_lib) \
216 return REAL(func)(__VA_ARGS__); \
219 #define TSAN_INTERCEPTOR(ret, func, ...) INTERCEPTOR(ret, func, __VA_ARGS__)
220 #define TSAN_INTERCEPT(func) INTERCEPT_FUNCTION(func)
221 #define TSAN_INTERCEPT_VER(func, ver) INTERCEPT_FUNCTION_VER(func, ver)
223 #define BLOCK_REAL(name) (BlockingCall(thr), REAL(name))
225 struct BlockingCall
{
226 explicit BlockingCall(ThreadState
*thr
)
230 atomic_store(&ctx
->in_blocking_func
, 1, memory_order_relaxed
);
231 if (atomic_load(&ctx
->have_pending_signals
, memory_order_relaxed
) == 0)
233 atomic_store(&ctx
->in_blocking_func
, 0, memory_order_relaxed
);
234 ProcessPendingSignals(thr
);
236 // When we are in a "blocking call", we process signals asynchronously
237 // (right when they arrive). In this context we do not expect to be
238 // executing any user/runtime code. The known interceptor sequence when
239 // this is not true is: pthread_join -> munmap(stack). It's fine
240 // to ignore munmap in this case -- we handle stack shadow separately.
241 thr
->ignore_interceptors
++;
245 thr
->ignore_interceptors
--;
246 atomic_store(&ctx
->in_blocking_func
, 0, memory_order_relaxed
);
253 TSAN_INTERCEPTOR(unsigned, sleep
, unsigned sec
) {
254 SCOPED_TSAN_INTERCEPTOR(sleep
, sec
);
255 unsigned res
= BLOCK_REAL(sleep
)(sec
);
260 TSAN_INTERCEPTOR(int, usleep
, long_t usec
) {
261 SCOPED_TSAN_INTERCEPTOR(usleep
, usec
);
262 int res
= BLOCK_REAL(usleep
)(usec
);
267 TSAN_INTERCEPTOR(int, nanosleep
, void *req
, void *rem
) {
268 SCOPED_TSAN_INTERCEPTOR(nanosleep
, req
, rem
);
269 int res
= BLOCK_REAL(nanosleep
)(req
, rem
);
274 class AtExitContext
{
277 : mtx_(MutexTypeAtExit
, StatMtxAtExit
)
278 , stack_(MBlockAtExit
) {
281 typedef void(*atexit_cb_t
)();
283 int atexit(ThreadState
*thr
, uptr pc
, bool is_on_exit
,
284 atexit_cb_t f
, void *arg
, void *dso
) {
286 Release(thr
, pc
, (uptr
)this);
287 atexit_t
*a
= stack_
.PushBack();
291 a
->is_on_exit
= is_on_exit
;
295 void exit(ThreadState
*thr
, uptr pc
) {
300 if (stack_
.Size() != 0) {
301 a
= stack_
[stack_
.Size() - 1];
303 Acquire(thr
, pc
, (uptr
)this);
308 VPrintf(2, "#%d: executing atexit func %p(%p) dso=%p\n",
309 thr
->tid
, a
.cb
, a
.arg
, a
.dso
);
311 ((void(*)(int status
, void *arg
))a
.cb
)(0, a
.arg
);
313 ((void(*)(void *arg
, void *dso
))a
.cb
)(a
.arg
, a
.dso
);
325 static const int kMaxAtExit
= 1024;
327 Vector
<atexit_t
> stack_
;
330 static AtExitContext
*atexit_ctx
;
332 TSAN_INTERCEPTOR(int, atexit
, void (*f
)()) {
333 if (cur_thread()->in_symbolizer
)
335 // We want to setup the atexit callback even if we are in ignored lib
337 SCOPED_INTERCEPTOR_RAW(atexit
, f
);
338 return atexit_ctx
->atexit(thr
, pc
, false, (void(*)())f
, 0, 0);
341 TSAN_INTERCEPTOR(int, on_exit
, void(*f
)(int, void*), void *arg
) {
342 if (cur_thread()->in_symbolizer
)
344 SCOPED_TSAN_INTERCEPTOR(on_exit
, f
, arg
);
345 return atexit_ctx
->atexit(thr
, pc
, true, (void(*)())f
, arg
, 0);
348 bool IsSaticModule(void *dso
) {
351 for (uptr i
= 0; i
< nmodules
; i
++) {
352 if (modules
[i
].containsAddress((uptr
)dso
))
358 TSAN_INTERCEPTOR(int, __cxa_atexit
, void (*f
)(void *a
), void *arg
, void *dso
) {
359 if (cur_thread()->in_symbolizer
)
361 SCOPED_TSAN_INTERCEPTOR(__cxa_atexit
, f
, arg
, dso
);
362 // If it's the main executable or a statically loaded library,
363 // we will call the callback.
364 if (dso
== 0 || IsSaticModule(dso
))
365 return atexit_ctx
->atexit(thr
, pc
, false, (void(*)())f
, arg
, dso
);
367 // Dynamically load module, don't know when to call the callback for it.
368 // Memory allocation in __cxa_atexit will race with free during exit,
369 // because we do not see synchronization around atexit callback list.
370 ThreadIgnoreBegin(thr
, pc
);
371 int res
= REAL(__cxa_atexit
)(f
, arg
, dso
);
372 ThreadIgnoreEnd(thr
, pc
);
377 static void JmpBufGarbageCollect(ThreadState
*thr
, uptr sp
) {
378 for (uptr i
= 0; i
< thr
->jmp_bufs
.Size(); i
++) {
379 JmpBuf
*buf
= &thr
->jmp_bufs
[i
];
381 uptr sz
= thr
->jmp_bufs
.Size();
382 thr
->jmp_bufs
[i
] = thr
->jmp_bufs
[sz
- 1];
383 thr
->jmp_bufs
.PopBack();
389 static void SetJmp(ThreadState
*thr
, uptr sp
, uptr mangled_sp
) {
390 if (thr
->shadow_stack_pos
== 0) // called from libc guts during bootstrap
393 JmpBufGarbageCollect(thr
, sp
);
395 JmpBuf
*buf
= thr
->jmp_bufs
.PushBack();
397 buf
->mangled_sp
= mangled_sp
;
398 buf
->shadow_stack_pos
= thr
->shadow_stack_pos
;
399 SignalContext
*sctx
= SigCtx(thr
);
400 buf
->int_signal_send
= sctx
? sctx
->int_signal_send
: 0;
401 buf
->in_blocking_func
= sctx
?
402 atomic_load(&sctx
->in_blocking_func
, memory_order_relaxed
) :
404 buf
->in_signal_handler
= atomic_load(&thr
->in_signal_handler
,
405 memory_order_relaxed
);
408 static void LongJmp(ThreadState
*thr
, uptr
*env
) {
409 uptr mangled_sp
= env
[6];
410 // Find the saved buf by mangled_sp.
411 for (uptr i
= 0; i
< thr
->jmp_bufs
.Size(); i
++) {
412 JmpBuf
*buf
= &thr
->jmp_bufs
[i
];
413 if (buf
->mangled_sp
== mangled_sp
) {
414 CHECK_GE(thr
->shadow_stack_pos
, buf
->shadow_stack_pos
);
416 while (thr
->shadow_stack_pos
> buf
->shadow_stack_pos
)
418 SignalContext
*sctx
= SigCtx(thr
);
420 sctx
->int_signal_send
= buf
->int_signal_send
;
421 atomic_store(&sctx
->in_blocking_func
, buf
->in_blocking_func
,
422 memory_order_relaxed
);
424 atomic_store(&thr
->in_signal_handler
, buf
->in_signal_handler
,
425 memory_order_relaxed
);
426 JmpBufGarbageCollect(thr
, buf
->sp
- 1); // do not collect buf->sp
430 Printf("ThreadSanitizer: can't find longjmp buf\n");
434 // FIXME: put everything below into a common extern "C" block?
435 extern "C" void __tsan_setjmp(uptr sp
, uptr mangled_sp
) {
436 SetJmp(cur_thread(), sp
, mangled_sp
);
439 // Not called. Merely to satisfy TSAN_INTERCEPT().
440 extern "C" SANITIZER_INTERFACE_ATTRIBUTE
441 int __interceptor_setjmp(void *env
);
442 extern "C" int __interceptor_setjmp(void *env
) {
447 // FIXME: any reason to have a separate declaration?
448 extern "C" SANITIZER_INTERFACE_ATTRIBUTE
449 int __interceptor__setjmp(void *env
);
450 extern "C" int __interceptor__setjmp(void *env
) {
455 extern "C" SANITIZER_INTERFACE_ATTRIBUTE
456 int __interceptor_sigsetjmp(void *env
);
457 extern "C" int __interceptor_sigsetjmp(void *env
) {
462 extern "C" SANITIZER_INTERFACE_ATTRIBUTE
463 int __interceptor___sigsetjmp(void *env
);
464 extern "C" int __interceptor___sigsetjmp(void *env
) {
469 extern "C" int setjmp(void *env
);
470 extern "C" int _setjmp(void *env
);
471 extern "C" int sigsetjmp(void *env
);
472 extern "C" int __sigsetjmp(void *env
);
473 DEFINE_REAL(int, setjmp
, void *env
)
474 DEFINE_REAL(int, _setjmp
, void *env
)
475 DEFINE_REAL(int, sigsetjmp
, void *env
)
476 DEFINE_REAL(int, __sigsetjmp
, void *env
)
478 TSAN_INTERCEPTOR(void, longjmp
, uptr
*env
, int val
) {
480 SCOPED_TSAN_INTERCEPTOR(longjmp
, env
, val
);
482 LongJmp(cur_thread(), env
);
483 REAL(longjmp
)(env
, val
);
486 TSAN_INTERCEPTOR(void, siglongjmp
, uptr
*env
, int val
) {
488 SCOPED_TSAN_INTERCEPTOR(siglongjmp
, env
, val
);
490 LongJmp(cur_thread(), env
);
491 REAL(siglongjmp
)(env
, val
);
494 TSAN_INTERCEPTOR(void*, malloc
, uptr size
) {
495 if (cur_thread()->in_symbolizer
)
496 return __libc_malloc(size
);
499 SCOPED_INTERCEPTOR_RAW(malloc
, size
);
500 p
= user_alloc(thr
, pc
, size
);
502 invoke_malloc_hook(p
, size
);
506 TSAN_INTERCEPTOR(void*, __libc_memalign
, uptr align
, uptr sz
) {
507 SCOPED_TSAN_INTERCEPTOR(__libc_memalign
, align
, sz
);
508 return user_alloc(thr
, pc
, sz
, align
);
511 TSAN_INTERCEPTOR(void*, calloc
, uptr size
, uptr n
) {
512 if (cur_thread()->in_symbolizer
)
513 return __libc_calloc(size
, n
);
514 if (__sanitizer::CallocShouldReturnNullDueToOverflow(size
, n
))
515 return AllocatorReturnNull();
518 SCOPED_INTERCEPTOR_RAW(calloc
, size
, n
);
519 p
= user_alloc(thr
, pc
, n
* size
);
521 internal_memset(p
, 0, n
* size
);
523 invoke_malloc_hook(p
, n
* size
);
527 TSAN_INTERCEPTOR(void*, realloc
, void *p
, uptr size
) {
528 if (cur_thread()->in_symbolizer
)
529 return __libc_realloc(p
, size
);
533 SCOPED_INTERCEPTOR_RAW(realloc
, p
, size
);
534 p
= user_realloc(thr
, pc
, p
, size
);
536 invoke_malloc_hook(p
, size
);
540 TSAN_INTERCEPTOR(void, free
, void *p
) {
543 if (cur_thread()->in_symbolizer
)
544 return __libc_free(p
);
546 SCOPED_INTERCEPTOR_RAW(free
, p
);
547 user_free(thr
, pc
, p
);
550 TSAN_INTERCEPTOR(void, cfree
, void *p
) {
553 if (cur_thread()->in_symbolizer
)
554 return __libc_free(p
);
556 SCOPED_INTERCEPTOR_RAW(cfree
, p
);
557 user_free(thr
, pc
, p
);
560 TSAN_INTERCEPTOR(uptr
, malloc_usable_size
, void *p
) {
561 SCOPED_INTERCEPTOR_RAW(malloc_usable_size
, p
);
562 return user_alloc_usable_size(p
);
565 #define OPERATOR_NEW_BODY(mangled_name) \
566 if (cur_thread()->in_symbolizer) \
567 return __libc_malloc(size); \
570 SCOPED_INTERCEPTOR_RAW(mangled_name, size); \
571 p = user_alloc(thr, pc, size); \
573 invoke_malloc_hook(p, size); \
576 SANITIZER_INTERFACE_ATTRIBUTE
577 void *operator new(__sanitizer::uptr size
);
578 void *operator new(__sanitizer::uptr size
) {
579 OPERATOR_NEW_BODY(_Znwm
);
582 SANITIZER_INTERFACE_ATTRIBUTE
583 void *operator new[](__sanitizer::uptr size
);
584 void *operator new[](__sanitizer::uptr size
) {
585 OPERATOR_NEW_BODY(_Znam
);
588 SANITIZER_INTERFACE_ATTRIBUTE
589 void *operator new(__sanitizer::uptr size
, std::nothrow_t
const&);
590 void *operator new(__sanitizer::uptr size
, std::nothrow_t
const&) {
591 OPERATOR_NEW_BODY(_ZnwmRKSt9nothrow_t
);
594 SANITIZER_INTERFACE_ATTRIBUTE
595 void *operator new[](__sanitizer::uptr size
, std::nothrow_t
const&);
596 void *operator new[](__sanitizer::uptr size
, std::nothrow_t
const&) {
597 OPERATOR_NEW_BODY(_ZnamRKSt9nothrow_t
);
600 #define OPERATOR_DELETE_BODY(mangled_name) \
601 if (ptr == 0) return; \
602 if (cur_thread()->in_symbolizer) \
603 return __libc_free(ptr); \
604 invoke_free_hook(ptr); \
605 SCOPED_INTERCEPTOR_RAW(mangled_name, ptr); \
606 user_free(thr, pc, ptr);
608 SANITIZER_INTERFACE_ATTRIBUTE
609 void operator delete(void *ptr
) throw();
610 void operator delete(void *ptr
) throw() {
611 OPERATOR_DELETE_BODY(_ZdlPv
);
614 SANITIZER_INTERFACE_ATTRIBUTE
615 void operator delete[](void *ptr
) throw();
616 void operator delete[](void *ptr
) throw() {
617 OPERATOR_DELETE_BODY(_ZdaPv
);
620 SANITIZER_INTERFACE_ATTRIBUTE
621 void operator delete(void *ptr
, std::nothrow_t
const&);
622 void operator delete(void *ptr
, std::nothrow_t
const&) {
623 OPERATOR_DELETE_BODY(_ZdlPvRKSt9nothrow_t
);
626 SANITIZER_INTERFACE_ATTRIBUTE
627 void operator delete[](void *ptr
, std::nothrow_t
const&);
628 void operator delete[](void *ptr
, std::nothrow_t
const&) {
629 OPERATOR_DELETE_BODY(_ZdaPvRKSt9nothrow_t
);
632 TSAN_INTERCEPTOR(uptr
, strlen
, const char *s
) {
633 SCOPED_TSAN_INTERCEPTOR(strlen
, s
);
634 uptr len
= internal_strlen(s
);
635 MemoryAccessRange(thr
, pc
, (uptr
)s
, len
+ 1, false);
639 TSAN_INTERCEPTOR(void*, memset
, void *dst
, int v
, uptr size
) {
640 SCOPED_TSAN_INTERCEPTOR(memset
, dst
, v
, size
);
641 MemoryAccessRange(thr
, pc
, (uptr
)dst
, size
, true);
642 return internal_memset(dst
, v
, size
);
645 TSAN_INTERCEPTOR(void*, memcpy
, void *dst
, const void *src
, uptr size
) {
646 SCOPED_TSAN_INTERCEPTOR(memcpy
, dst
, src
, size
);
647 MemoryAccessRange(thr
, pc
, (uptr
)dst
, size
, true);
648 MemoryAccessRange(thr
, pc
, (uptr
)src
, size
, false);
649 return internal_memcpy(dst
, src
, size
);
652 TSAN_INTERCEPTOR(int, memcmp
, const void *s1
, const void *s2
, uptr n
) {
653 SCOPED_TSAN_INTERCEPTOR(memcmp
, s1
, s2
, n
);
656 for (; len
< n
; len
++) {
657 if ((res
= ((unsigned char*)s1
)[len
] - ((unsigned char*)s2
)[len
]))
660 MemoryAccessRange(thr
, pc
, (uptr
)s1
, len
< n
? len
+ 1 : n
, false);
661 MemoryAccessRange(thr
, pc
, (uptr
)s2
, len
< n
? len
+ 1 : n
, false);
665 TSAN_INTERCEPTOR(void*, memmove
, void *dst
, void *src
, uptr n
) {
666 SCOPED_TSAN_INTERCEPTOR(memmove
, dst
, src
, n
);
667 MemoryAccessRange(thr
, pc
, (uptr
)dst
, n
, true);
668 MemoryAccessRange(thr
, pc
, (uptr
)src
, n
, false);
669 return REAL(memmove
)(dst
, src
, n
);
672 TSAN_INTERCEPTOR(char*, strchr
, char *s
, int c
) {
673 SCOPED_TSAN_INTERCEPTOR(strchr
, s
, c
);
674 char *res
= REAL(strchr
)(s
, c
);
675 uptr len
= res
? (char*)res
- (char*)s
+ 1 : internal_strlen(s
) + 1;
676 MemoryAccessRange(thr
, pc
, (uptr
)s
, len
, false);
680 TSAN_INTERCEPTOR(char*, strchrnul
, char *s
, int c
) {
681 SCOPED_TSAN_INTERCEPTOR(strchrnul
, s
, c
);
682 char *res
= REAL(strchrnul
)(s
, c
);
683 uptr len
= (char*)res
- (char*)s
+ 1;
684 MemoryAccessRange(thr
, pc
, (uptr
)s
, len
, false);
688 TSAN_INTERCEPTOR(char*, strrchr
, char *s
, int c
) {
689 SCOPED_TSAN_INTERCEPTOR(strrchr
, s
, c
);
690 MemoryAccessRange(thr
, pc
, (uptr
)s
, internal_strlen(s
) + 1, false);
691 return REAL(strrchr
)(s
, c
);
694 TSAN_INTERCEPTOR(char*, strcpy
, char *dst
, const char *src
) { // NOLINT
695 SCOPED_TSAN_INTERCEPTOR(strcpy
, dst
, src
); // NOLINT
696 uptr srclen
= internal_strlen(src
);
697 MemoryAccessRange(thr
, pc
, (uptr
)dst
, srclen
+ 1, true);
698 MemoryAccessRange(thr
, pc
, (uptr
)src
, srclen
+ 1, false);
699 return REAL(strcpy
)(dst
, src
); // NOLINT
702 TSAN_INTERCEPTOR(char*, strncpy
, char *dst
, char *src
, uptr n
) {
703 SCOPED_TSAN_INTERCEPTOR(strncpy
, dst
, src
, n
);
704 uptr srclen
= internal_strnlen(src
, n
);
705 MemoryAccessRange(thr
, pc
, (uptr
)dst
, n
, true);
706 MemoryAccessRange(thr
, pc
, (uptr
)src
, min(srclen
+ 1, n
), false);
707 return REAL(strncpy
)(dst
, src
, n
);
710 TSAN_INTERCEPTOR(const char*, strstr
, const char *s1
, const char *s2
) {
711 SCOPED_TSAN_INTERCEPTOR(strstr
, s1
, s2
);
712 const char *res
= REAL(strstr
)(s1
, s2
);
713 uptr len1
= internal_strlen(s1
);
714 uptr len2
= internal_strlen(s2
);
715 MemoryAccessRange(thr
, pc
, (uptr
)s1
, len1
+ 1, false);
716 MemoryAccessRange(thr
, pc
, (uptr
)s2
, len2
+ 1, false);
720 TSAN_INTERCEPTOR(char*, strdup
, const char *str
) {
721 SCOPED_TSAN_INTERCEPTOR(strdup
, str
);
722 // strdup will call malloc, so no instrumentation is required here.
723 return REAL(strdup
)(str
);
726 static bool fix_mmap_addr(void **addr
, long_t sz
, int flags
) {
728 if (!IsAppMem((uptr
)*addr
) || !IsAppMem((uptr
)*addr
+ sz
- 1)) {
729 if (flags
& MAP_FIXED
) {
740 TSAN_INTERCEPTOR(void*, mmap
, void *addr
, long_t sz
, int prot
,
741 int flags
, int fd
, unsigned off
) {
742 SCOPED_TSAN_INTERCEPTOR(mmap
, addr
, sz
, prot
, flags
, fd
, off
);
743 if (!fix_mmap_addr(&addr
, sz
, flags
))
745 void *res
= REAL(mmap
)(addr
, sz
, prot
, flags
, fd
, off
);
746 if (res
!= MAP_FAILED
) {
748 FdAccess(thr
, pc
, fd
);
749 MemoryRangeImitateWrite(thr
, pc
, (uptr
)res
, sz
);
754 TSAN_INTERCEPTOR(void*, mmap64
, void *addr
, long_t sz
, int prot
,
755 int flags
, int fd
, u64 off
) {
756 SCOPED_TSAN_INTERCEPTOR(mmap64
, addr
, sz
, prot
, flags
, fd
, off
);
757 if (!fix_mmap_addr(&addr
, sz
, flags
))
759 void *res
= REAL(mmap64
)(addr
, sz
, prot
, flags
, fd
, off
);
760 if (res
!= MAP_FAILED
) {
762 FdAccess(thr
, pc
, fd
);
763 MemoryRangeImitateWrite(thr
, pc
, (uptr
)res
, sz
);
768 TSAN_INTERCEPTOR(int, munmap
, void *addr
, long_t sz
) {
769 SCOPED_TSAN_INTERCEPTOR(munmap
, addr
, sz
);
770 DontNeedShadowFor((uptr
)addr
, sz
);
771 int res
= REAL(munmap
)(addr
, sz
);
775 TSAN_INTERCEPTOR(void*, memalign
, uptr align
, uptr sz
) {
776 SCOPED_INTERCEPTOR_RAW(memalign
, align
, sz
);
777 return user_alloc(thr
, pc
, sz
, align
);
780 TSAN_INTERCEPTOR(void*, aligned_alloc
, uptr align
, uptr sz
) {
781 SCOPED_INTERCEPTOR_RAW(memalign
, align
, sz
);
782 return user_alloc(thr
, pc
, sz
, align
);
785 TSAN_INTERCEPTOR(void*, valloc
, uptr sz
) {
786 SCOPED_INTERCEPTOR_RAW(valloc
, sz
);
787 return user_alloc(thr
, pc
, sz
, GetPageSizeCached());
790 TSAN_INTERCEPTOR(void*, pvalloc
, uptr sz
) {
791 SCOPED_INTERCEPTOR_RAW(pvalloc
, sz
);
792 sz
= RoundUp(sz
, GetPageSizeCached());
793 return user_alloc(thr
, pc
, sz
, GetPageSizeCached());
796 TSAN_INTERCEPTOR(int, posix_memalign
, void **memptr
, uptr align
, uptr sz
) {
797 SCOPED_INTERCEPTOR_RAW(posix_memalign
, memptr
, align
, sz
);
798 *memptr
= user_alloc(thr
, pc
, sz
, align
);
802 // Used in thread-safe function static initialization.
803 extern "C" int INTERFACE_ATTRIBUTE
__cxa_guard_acquire(atomic_uint32_t
*g
) {
804 SCOPED_INTERCEPTOR_RAW(__cxa_guard_acquire
, g
);
806 u32 cmp
= atomic_load(g
, memory_order_acquire
);
808 if (atomic_compare_exchange_strong(g
, &cmp
, 1<<16, memory_order_relaxed
))
810 } else if (cmp
== 1) {
811 Acquire(thr
, pc
, (uptr
)g
);
814 internal_sched_yield();
819 extern "C" void INTERFACE_ATTRIBUTE
__cxa_guard_release(atomic_uint32_t
*g
) {
820 SCOPED_INTERCEPTOR_RAW(__cxa_guard_release
, g
);
821 Release(thr
, pc
, (uptr
)g
);
822 atomic_store(g
, 1, memory_order_release
);
825 extern "C" void INTERFACE_ATTRIBUTE
__cxa_guard_abort(atomic_uint32_t
*g
) {
826 SCOPED_INTERCEPTOR_RAW(__cxa_guard_abort
, g
);
827 atomic_store(g
, 0, memory_order_relaxed
);
830 static void thread_finalize(void *v
) {
833 if (pthread_setspecific(g_thread_finalize_key
, (void*)(iter
- 1))) {
834 Printf("ThreadSanitizer: failed to set thread key\n");
840 ThreadState
*thr
= cur_thread();
842 SignalContext
*sctx
= thr
->signal_ctx
;
845 UnmapOrDie(sctx
, sizeof(*sctx
));
852 void* (*callback
)(void *arg
);
854 atomic_uintptr_t tid
;
857 extern "C" void *__tsan_thread_start_func(void *arg
) {
858 ThreadParam
*p
= (ThreadParam
*)arg
;
859 void* (*callback
)(void *arg
) = p
->callback
;
860 void *param
= p
->param
;
863 ThreadState
*thr
= cur_thread();
864 // Thread-local state is not initialized yet.
865 ScopedIgnoreInterceptors ignore
;
866 if (pthread_setspecific(g_thread_finalize_key
,
867 (void *)kPthreadDestructorIterations
)) {
868 Printf("ThreadSanitizer: failed to set thread key\n");
871 while ((tid
= atomic_load(&p
->tid
, memory_order_acquire
)) == 0)
873 atomic_store(&p
->tid
, 0, memory_order_release
);
874 ThreadStart(thr
, tid
, GetTid());
876 void *res
= callback(param
);
877 // Prevent the callback from being tail called,
878 // it mixes up stack traces.
879 volatile int foo
= 42;
884 TSAN_INTERCEPTOR(int, pthread_create
,
885 void *th
, void *attr
, void *(*callback
)(void*), void * param
) {
886 SCOPED_INTERCEPTOR_RAW(pthread_create
, th
, attr
, callback
, param
);
887 if (ctx
->after_multithreaded_fork
) {
888 if (flags()->die_after_fork
) {
889 Report("ThreadSanitizer: starting new threads after multi-threaded "
890 "fork is not supported. Dying (set die_after_fork=0 to override)\n");
893 VPrintf(1, "ThreadSanitizer: starting new threads after multi-threaded "
894 "fork is not supported (pid %d). Continuing because of "
895 "die_after_fork=0, but you are on your own\n", internal_getpid());
898 __sanitizer_pthread_attr_t myattr
;
900 pthread_attr_init(&myattr
);
904 REAL(pthread_attr_getdetachstate
)(attr
, &detached
);
905 AdjustStackSize(attr
);
908 p
.callback
= callback
;
910 atomic_store(&p
.tid
, 0, memory_order_relaxed
);
913 // Otherwise we see false positives in pthread stack manipulation.
914 ScopedIgnoreInterceptors ignore
;
915 ThreadIgnoreBegin(thr
, pc
);
916 res
= REAL(pthread_create
)(th
, attr
, __tsan_thread_start_func
, &p
);
917 ThreadIgnoreEnd(thr
, pc
);
920 int tid
= ThreadCreate(thr
, pc
, *(uptr
*)th
, detached
);
922 atomic_store(&p
.tid
, tid
, memory_order_release
);
923 while (atomic_load(&p
.tid
, memory_order_acquire
) != 0)
927 pthread_attr_destroy(&myattr
);
931 TSAN_INTERCEPTOR(int, pthread_join
, void *th
, void **ret
) {
932 SCOPED_INTERCEPTOR_RAW(pthread_join
, th
, ret
);
933 int tid
= ThreadTid(thr
, pc
, (uptr
)th
);
934 ThreadIgnoreBegin(thr
, pc
);
935 int res
= BLOCK_REAL(pthread_join
)(th
, ret
);
936 ThreadIgnoreEnd(thr
, pc
);
938 ThreadJoin(thr
, pc
, tid
);
943 TSAN_INTERCEPTOR(int, pthread_detach
, void *th
) {
944 SCOPED_TSAN_INTERCEPTOR(pthread_detach
, th
);
945 int tid
= ThreadTid(thr
, pc
, (uptr
)th
);
946 int res
= REAL(pthread_detach
)(th
);
948 ThreadDetach(thr
, pc
, tid
);
954 // NPTL implementation of pthread_cond has 2 versions (2.2.5 and 2.3.2).
955 // pthread_cond_t has different size in the different versions.
956 // If call new REAL functions for old pthread_cond_t, they will corrupt memory
957 // after pthread_cond_t (old cond is smaller).
958 // If we call old REAL functions for new pthread_cond_t, we will lose some
959 // functionality (e.g. old functions do not support waiting against
961 // Proper handling would require to have 2 versions of interceptors as well.
962 // But this is messy, in particular requires linker scripts when sanitizer
963 // runtime is linked into a shared library.
964 // Instead we assume we don't have dynamic libraries built against old
965 // pthread (2.2.5 is dated by 2002). And provide legacy_pthread_cond flag
966 // that allows to work with old libraries (but this mode does not support
967 // some features, e.g. pthread_condattr_getpshared).
968 static void *init_cond(void *c
, bool force
= false) {
969 // sizeof(pthread_cond_t) >= sizeof(uptr) in both versions.
970 // So we allocate additional memory on the side large enough to hold
971 // any pthread_cond_t object. Always call new REAL functions, but pass
972 // the aux object to them.
973 // Note: the code assumes that PTHREAD_COND_INITIALIZER initializes
974 // first word of pthread_cond_t to zero.
975 // It's all relevant only for linux.
976 if (!common_flags()->legacy_pthread_cond
)
978 atomic_uintptr_t
*p
= (atomic_uintptr_t
*)c
;
979 uptr cond
= atomic_load(p
, memory_order_acquire
);
980 if (!force
&& cond
!= 0)
982 void *newcond
= WRAP(malloc
)(pthread_cond_t_sz
);
983 internal_memset(newcond
, 0, pthread_cond_t_sz
);
984 if (atomic_compare_exchange_strong(p
, &cond
, (uptr
)newcond
,
985 memory_order_acq_rel
))
991 struct CondMutexUnlockCtx
{
997 static void cond_mutex_unlock(CondMutexUnlockCtx
*arg
) {
998 MutexLock(arg
->thr
, arg
->pc
, (uptr
)arg
->m
);
1001 INTERCEPTOR(int, pthread_cond_init
, void *c
, void *a
) {
1002 void *cond
= init_cond(c
, true);
1003 SCOPED_TSAN_INTERCEPTOR(pthread_cond_init
, cond
, a
);
1004 MemoryAccessRange(thr
, pc
, (uptr
)c
, sizeof(uptr
), true);
1005 return REAL(pthread_cond_init
)(cond
, a
);
1008 INTERCEPTOR(int, pthread_cond_wait
, void *c
, void *m
) {
1009 void *cond
= init_cond(c
);
1010 SCOPED_TSAN_INTERCEPTOR(pthread_cond_wait
, cond
, m
);
1011 MutexUnlock(thr
, pc
, (uptr
)m
);
1012 MemoryAccessRange(thr
, pc
, (uptr
)c
, sizeof(uptr
), false);
1013 CondMutexUnlockCtx arg
= {thr
, pc
, m
};
1014 // This ensures that we handle mutex lock even in case of pthread_cancel.
1015 // See test/tsan/cond_cancel.cc.
1016 int res
= call_pthread_cancel_with_cleanup(
1017 (int(*)(void *c
, void *m
, void *abstime
))REAL(pthread_cond_wait
),
1018 cond
, m
, 0, (void(*)(void *arg
))cond_mutex_unlock
, &arg
);
1019 if (res
== errno_EOWNERDEAD
)
1020 MutexRepair(thr
, pc
, (uptr
)m
);
1021 MutexLock(thr
, pc
, (uptr
)m
);
1025 INTERCEPTOR(int, pthread_cond_timedwait
, void *c
, void *m
, void *abstime
) {
1026 void *cond
= init_cond(c
);
1027 SCOPED_TSAN_INTERCEPTOR(pthread_cond_timedwait
, cond
, m
, abstime
);
1028 MutexUnlock(thr
, pc
, (uptr
)m
);
1029 MemoryAccessRange(thr
, pc
, (uptr
)c
, sizeof(uptr
), false);
1030 CondMutexUnlockCtx arg
= {thr
, pc
, m
};
1031 // This ensures that we handle mutex lock even in case of pthread_cancel.
1032 // See test/tsan/cond_cancel.cc.
1033 int res
= call_pthread_cancel_with_cleanup(
1034 REAL(pthread_cond_timedwait
), cond
, m
, abstime
,
1035 (void(*)(void *arg
))cond_mutex_unlock
, &arg
);
1036 if (res
== errno_EOWNERDEAD
)
1037 MutexRepair(thr
, pc
, (uptr
)m
);
1038 MutexLock(thr
, pc
, (uptr
)m
);
1042 INTERCEPTOR(int, pthread_cond_signal
, void *c
) {
1043 void *cond
= init_cond(c
);
1044 SCOPED_TSAN_INTERCEPTOR(pthread_cond_signal
, cond
);
1045 MemoryAccessRange(thr
, pc
, (uptr
)c
, sizeof(uptr
), false);
1046 return REAL(pthread_cond_signal
)(cond
);
1049 INTERCEPTOR(int, pthread_cond_broadcast
, void *c
) {
1050 void *cond
= init_cond(c
);
1051 SCOPED_TSAN_INTERCEPTOR(pthread_cond_broadcast
, cond
);
1052 MemoryAccessRange(thr
, pc
, (uptr
)c
, sizeof(uptr
), false);
1053 return REAL(pthread_cond_broadcast
)(cond
);
1056 INTERCEPTOR(int, pthread_cond_destroy
, void *c
) {
1057 void *cond
= init_cond(c
);
1058 SCOPED_TSAN_INTERCEPTOR(pthread_cond_destroy
, cond
);
1059 MemoryAccessRange(thr
, pc
, (uptr
)c
, sizeof(uptr
), true);
1060 int res
= REAL(pthread_cond_destroy
)(cond
);
1061 if (common_flags()->legacy_pthread_cond
) {
1062 // Free our aux cond and zero the pointer to not leave dangling pointers.
1064 atomic_store((atomic_uintptr_t
*)c
, 0, memory_order_relaxed
);
1069 TSAN_INTERCEPTOR(int, pthread_mutex_init
, void *m
, void *a
) {
1070 SCOPED_TSAN_INTERCEPTOR(pthread_mutex_init
, m
, a
);
1071 int res
= REAL(pthread_mutex_init
)(m
, a
);
1073 bool recursive
= false;
1076 if (REAL(pthread_mutexattr_gettype
)(a
, &type
) == 0)
1077 recursive
= (type
== PTHREAD_MUTEX_RECURSIVE
1078 || type
== PTHREAD_MUTEX_RECURSIVE_NP
);
1080 MutexCreate(thr
, pc
, (uptr
)m
, false, recursive
, false);
1085 TSAN_INTERCEPTOR(int, pthread_mutex_destroy
, void *m
) {
1086 SCOPED_TSAN_INTERCEPTOR(pthread_mutex_destroy
, m
);
1087 int res
= REAL(pthread_mutex_destroy
)(m
);
1088 if (res
== 0 || res
== EBUSY
) {
1089 MutexDestroy(thr
, pc
, (uptr
)m
);
1094 TSAN_INTERCEPTOR(int, pthread_mutex_trylock
, void *m
) {
1095 SCOPED_TSAN_INTERCEPTOR(pthread_mutex_trylock
, m
);
1096 int res
= REAL(pthread_mutex_trylock
)(m
);
1097 if (res
== EOWNERDEAD
)
1098 MutexRepair(thr
, pc
, (uptr
)m
);
1099 if (res
== 0 || res
== EOWNERDEAD
)
1100 MutexLock(thr
, pc
, (uptr
)m
, /*rec=*/1, /*try_lock=*/true);
1104 TSAN_INTERCEPTOR(int, pthread_mutex_timedlock
, void *m
, void *abstime
) {
1105 SCOPED_TSAN_INTERCEPTOR(pthread_mutex_timedlock
, m
, abstime
);
1106 int res
= REAL(pthread_mutex_timedlock
)(m
, abstime
);
1108 MutexLock(thr
, pc
, (uptr
)m
);
1113 TSAN_INTERCEPTOR(int, pthread_spin_init
, void *m
, int pshared
) {
1114 SCOPED_TSAN_INTERCEPTOR(pthread_spin_init
, m
, pshared
);
1115 int res
= REAL(pthread_spin_init
)(m
, pshared
);
1117 MutexCreate(thr
, pc
, (uptr
)m
, false, false, false);
1122 TSAN_INTERCEPTOR(int, pthread_spin_destroy
, void *m
) {
1123 SCOPED_TSAN_INTERCEPTOR(pthread_spin_destroy
, m
);
1124 int res
= REAL(pthread_spin_destroy
)(m
);
1126 MutexDestroy(thr
, pc
, (uptr
)m
);
1131 TSAN_INTERCEPTOR(int, pthread_spin_lock
, void *m
) {
1132 SCOPED_TSAN_INTERCEPTOR(pthread_spin_lock
, m
);
1133 int res
= REAL(pthread_spin_lock
)(m
);
1135 MutexLock(thr
, pc
, (uptr
)m
);
1140 TSAN_INTERCEPTOR(int, pthread_spin_trylock
, void *m
) {
1141 SCOPED_TSAN_INTERCEPTOR(pthread_spin_trylock
, m
);
1142 int res
= REAL(pthread_spin_trylock
)(m
);
1144 MutexLock(thr
, pc
, (uptr
)m
, /*rec=*/1, /*try_lock=*/true);
1149 TSAN_INTERCEPTOR(int, pthread_spin_unlock
, void *m
) {
1150 SCOPED_TSAN_INTERCEPTOR(pthread_spin_unlock
, m
);
1151 MutexUnlock(thr
, pc
, (uptr
)m
);
1152 int res
= REAL(pthread_spin_unlock
)(m
);
1156 TSAN_INTERCEPTOR(int, pthread_rwlock_init
, void *m
, void *a
) {
1157 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_init
, m
, a
);
1158 int res
= REAL(pthread_rwlock_init
)(m
, a
);
1160 MutexCreate(thr
, pc
, (uptr
)m
, true, false, false);
1165 TSAN_INTERCEPTOR(int, pthread_rwlock_destroy
, void *m
) {
1166 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_destroy
, m
);
1167 int res
= REAL(pthread_rwlock_destroy
)(m
);
1169 MutexDestroy(thr
, pc
, (uptr
)m
);
1174 TSAN_INTERCEPTOR(int, pthread_rwlock_rdlock
, void *m
) {
1175 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_rdlock
, m
);
1176 int res
= REAL(pthread_rwlock_rdlock
)(m
);
1178 MutexReadLock(thr
, pc
, (uptr
)m
);
1183 TSAN_INTERCEPTOR(int, pthread_rwlock_tryrdlock
, void *m
) {
1184 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_tryrdlock
, m
);
1185 int res
= REAL(pthread_rwlock_tryrdlock
)(m
);
1187 MutexReadLock(thr
, pc
, (uptr
)m
, /*try_lock=*/true);
1192 TSAN_INTERCEPTOR(int, pthread_rwlock_timedrdlock
, void *m
, void *abstime
) {
1193 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_timedrdlock
, m
, abstime
);
1194 int res
= REAL(pthread_rwlock_timedrdlock
)(m
, abstime
);
1196 MutexReadLock(thr
, pc
, (uptr
)m
);
1201 TSAN_INTERCEPTOR(int, pthread_rwlock_wrlock
, void *m
) {
1202 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_wrlock
, m
);
1203 int res
= REAL(pthread_rwlock_wrlock
)(m
);
1205 MutexLock(thr
, pc
, (uptr
)m
);
1210 TSAN_INTERCEPTOR(int, pthread_rwlock_trywrlock
, void *m
) {
1211 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_trywrlock
, m
);
1212 int res
= REAL(pthread_rwlock_trywrlock
)(m
);
1214 MutexLock(thr
, pc
, (uptr
)m
, /*rec=*/1, /*try_lock=*/true);
1219 TSAN_INTERCEPTOR(int, pthread_rwlock_timedwrlock
, void *m
, void *abstime
) {
1220 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_timedwrlock
, m
, abstime
);
1221 int res
= REAL(pthread_rwlock_timedwrlock
)(m
, abstime
);
1223 MutexLock(thr
, pc
, (uptr
)m
);
1228 TSAN_INTERCEPTOR(int, pthread_rwlock_unlock
, void *m
) {
1229 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_unlock
, m
);
1230 MutexReadOrWriteUnlock(thr
, pc
, (uptr
)m
);
1231 int res
= REAL(pthread_rwlock_unlock
)(m
);
1235 TSAN_INTERCEPTOR(int, pthread_barrier_init
, void *b
, void *a
, unsigned count
) {
1236 SCOPED_TSAN_INTERCEPTOR(pthread_barrier_init
, b
, a
, count
);
1237 MemoryWrite(thr
, pc
, (uptr
)b
, kSizeLog1
);
1238 int res
= REAL(pthread_barrier_init
)(b
, a
, count
);
1242 TSAN_INTERCEPTOR(int, pthread_barrier_destroy
, void *b
) {
1243 SCOPED_TSAN_INTERCEPTOR(pthread_barrier_destroy
, b
);
1244 MemoryWrite(thr
, pc
, (uptr
)b
, kSizeLog1
);
1245 int res
= REAL(pthread_barrier_destroy
)(b
);
1249 TSAN_INTERCEPTOR(int, pthread_barrier_wait
, void *b
) {
1250 SCOPED_TSAN_INTERCEPTOR(pthread_barrier_wait
, b
);
1251 Release(thr
, pc
, (uptr
)b
);
1252 MemoryRead(thr
, pc
, (uptr
)b
, kSizeLog1
);
1253 int res
= REAL(pthread_barrier_wait
)(b
);
1254 MemoryRead(thr
, pc
, (uptr
)b
, kSizeLog1
);
1255 if (res
== 0 || res
== PTHREAD_BARRIER_SERIAL_THREAD
) {
1256 Acquire(thr
, pc
, (uptr
)b
);
1261 TSAN_INTERCEPTOR(int, pthread_once
, void *o
, void (*f
)()) {
1262 SCOPED_INTERCEPTOR_RAW(pthread_once
, o
, f
);
1263 if (o
== 0 || f
== 0)
1265 atomic_uint32_t
*a
= static_cast<atomic_uint32_t
*>(o
);
1266 u32 v
= atomic_load(a
, memory_order_acquire
);
1267 if (v
== 0 && atomic_compare_exchange_strong(a
, &v
, 1,
1268 memory_order_relaxed
)) {
1270 if (!thr
->in_ignored_lib
)
1271 Release(thr
, pc
, (uptr
)o
);
1272 atomic_store(a
, 2, memory_order_release
);
1276 v
= atomic_load(a
, memory_order_acquire
);
1278 if (!thr
->in_ignored_lib
)
1279 Acquire(thr
, pc
, (uptr
)o
);
1284 TSAN_INTERCEPTOR(int, sem_init
, void *s
, int pshared
, unsigned value
) {
1285 SCOPED_TSAN_INTERCEPTOR(sem_init
, s
, pshared
, value
);
1286 int res
= REAL(sem_init
)(s
, pshared
, value
);
1290 TSAN_INTERCEPTOR(int, sem_destroy
, void *s
) {
1291 SCOPED_TSAN_INTERCEPTOR(sem_destroy
, s
);
1292 int res
= REAL(sem_destroy
)(s
);
1296 TSAN_INTERCEPTOR(int, sem_wait
, void *s
) {
1297 SCOPED_TSAN_INTERCEPTOR(sem_wait
, s
);
1298 int res
= BLOCK_REAL(sem_wait
)(s
);
1300 Acquire(thr
, pc
, (uptr
)s
);
1305 TSAN_INTERCEPTOR(int, sem_trywait
, void *s
) {
1306 SCOPED_TSAN_INTERCEPTOR(sem_trywait
, s
);
1307 int res
= BLOCK_REAL(sem_trywait
)(s
);
1309 Acquire(thr
, pc
, (uptr
)s
);
1314 TSAN_INTERCEPTOR(int, sem_timedwait
, void *s
, void *abstime
) {
1315 SCOPED_TSAN_INTERCEPTOR(sem_timedwait
, s
, abstime
);
1316 int res
= BLOCK_REAL(sem_timedwait
)(s
, abstime
);
1318 Acquire(thr
, pc
, (uptr
)s
);
1323 TSAN_INTERCEPTOR(int, sem_post
, void *s
) {
1324 SCOPED_TSAN_INTERCEPTOR(sem_post
, s
);
1325 Release(thr
, pc
, (uptr
)s
);
1326 int res
= REAL(sem_post
)(s
);
1330 TSAN_INTERCEPTOR(int, sem_getvalue
, void *s
, int *sval
) {
1331 SCOPED_TSAN_INTERCEPTOR(sem_getvalue
, s
, sval
);
1332 int res
= REAL(sem_getvalue
)(s
, sval
);
1334 Acquire(thr
, pc
, (uptr
)s
);
1339 TSAN_INTERCEPTOR(int, __xstat
, int version
, const char *path
, void *buf
) {
1340 SCOPED_TSAN_INTERCEPTOR(__xstat
, version
, path
, buf
);
1341 return REAL(__xstat
)(version
, path
, buf
);
1344 TSAN_INTERCEPTOR(int, stat
, const char *path
, void *buf
) {
1345 SCOPED_TSAN_INTERCEPTOR(__xstat
, 0, path
, buf
);
1346 return REAL(__xstat
)(0, path
, buf
);
1349 TSAN_INTERCEPTOR(int, __xstat64
, int version
, const char *path
, void *buf
) {
1350 SCOPED_TSAN_INTERCEPTOR(__xstat64
, version
, path
, buf
);
1351 return REAL(__xstat64
)(version
, path
, buf
);
1354 TSAN_INTERCEPTOR(int, stat64
, const char *path
, void *buf
) {
1355 SCOPED_TSAN_INTERCEPTOR(__xstat64
, 0, path
, buf
);
1356 return REAL(__xstat64
)(0, path
, buf
);
1359 TSAN_INTERCEPTOR(int, __lxstat
, int version
, const char *path
, void *buf
) {
1360 SCOPED_TSAN_INTERCEPTOR(__lxstat
, version
, path
, buf
);
1361 return REAL(__lxstat
)(version
, path
, buf
);
1364 TSAN_INTERCEPTOR(int, lstat
, const char *path
, void *buf
) {
1365 SCOPED_TSAN_INTERCEPTOR(__lxstat
, 0, path
, buf
);
1366 return REAL(__lxstat
)(0, path
, buf
);
1369 TSAN_INTERCEPTOR(int, __lxstat64
, int version
, const char *path
, void *buf
) {
1370 SCOPED_TSAN_INTERCEPTOR(__lxstat64
, version
, path
, buf
);
1371 return REAL(__lxstat64
)(version
, path
, buf
);
1374 TSAN_INTERCEPTOR(int, lstat64
, const char *path
, void *buf
) {
1375 SCOPED_TSAN_INTERCEPTOR(__lxstat64
, 0, path
, buf
);
1376 return REAL(__lxstat64
)(0, path
, buf
);
1379 TSAN_INTERCEPTOR(int, __fxstat
, int version
, int fd
, void *buf
) {
1380 SCOPED_TSAN_INTERCEPTOR(__fxstat
, version
, fd
, buf
);
1382 FdAccess(thr
, pc
, fd
);
1383 return REAL(__fxstat
)(version
, fd
, buf
);
1386 TSAN_INTERCEPTOR(int, fstat
, int fd
, void *buf
) {
1387 SCOPED_TSAN_INTERCEPTOR(__fxstat
, 0, fd
, buf
);
1389 FdAccess(thr
, pc
, fd
);
1390 return REAL(__fxstat
)(0, fd
, buf
);
1393 TSAN_INTERCEPTOR(int, __fxstat64
, int version
, int fd
, void *buf
) {
1394 SCOPED_TSAN_INTERCEPTOR(__fxstat64
, version
, fd
, buf
);
1396 FdAccess(thr
, pc
, fd
);
1397 return REAL(__fxstat64
)(version
, fd
, buf
);
1400 TSAN_INTERCEPTOR(int, fstat64
, int fd
, void *buf
) {
1401 SCOPED_TSAN_INTERCEPTOR(__fxstat64
, 0, fd
, buf
);
1403 FdAccess(thr
, pc
, fd
);
1404 return REAL(__fxstat64
)(0, fd
, buf
);
1407 TSAN_INTERCEPTOR(int, open
, const char *name
, int flags
, int mode
) {
1408 SCOPED_TSAN_INTERCEPTOR(open
, name
, flags
, mode
);
1409 int fd
= REAL(open
)(name
, flags
, mode
);
1411 FdFileCreate(thr
, pc
, fd
);
1415 TSAN_INTERCEPTOR(int, open64
, const char *name
, int flags
, int mode
) {
1416 SCOPED_TSAN_INTERCEPTOR(open64
, name
, flags
, mode
);
1417 int fd
= REAL(open64
)(name
, flags
, mode
);
1419 FdFileCreate(thr
, pc
, fd
);
1423 TSAN_INTERCEPTOR(int, creat
, const char *name
, int mode
) {
1424 SCOPED_TSAN_INTERCEPTOR(creat
, name
, mode
);
1425 int fd
= REAL(creat
)(name
, mode
);
1427 FdFileCreate(thr
, pc
, fd
);
1431 TSAN_INTERCEPTOR(int, creat64
, const char *name
, int mode
) {
1432 SCOPED_TSAN_INTERCEPTOR(creat64
, name
, mode
);
1433 int fd
= REAL(creat64
)(name
, mode
);
1435 FdFileCreate(thr
, pc
, fd
);
1439 TSAN_INTERCEPTOR(int, dup
, int oldfd
) {
1440 SCOPED_TSAN_INTERCEPTOR(dup
, oldfd
);
1441 int newfd
= REAL(dup
)(oldfd
);
1442 if (oldfd
>= 0 && newfd
>= 0 && newfd
!= oldfd
)
1443 FdDup(thr
, pc
, oldfd
, newfd
);
1447 TSAN_INTERCEPTOR(int, dup2
, int oldfd
, int newfd
) {
1448 SCOPED_TSAN_INTERCEPTOR(dup2
, oldfd
, newfd
);
1449 int newfd2
= REAL(dup2
)(oldfd
, newfd
);
1450 if (oldfd
>= 0 && newfd2
>= 0 && newfd2
!= oldfd
)
1451 FdDup(thr
, pc
, oldfd
, newfd2
);
1455 TSAN_INTERCEPTOR(int, dup3
, int oldfd
, int newfd
, int flags
) {
1456 SCOPED_TSAN_INTERCEPTOR(dup3
, oldfd
, newfd
, flags
);
1457 int newfd2
= REAL(dup3
)(oldfd
, newfd
, flags
);
1458 if (oldfd
>= 0 && newfd2
>= 0 && newfd2
!= oldfd
)
1459 FdDup(thr
, pc
, oldfd
, newfd2
);
1463 TSAN_INTERCEPTOR(int, eventfd
, unsigned initval
, int flags
) {
1464 SCOPED_TSAN_INTERCEPTOR(eventfd
, initval
, flags
);
1465 int fd
= REAL(eventfd
)(initval
, flags
);
1467 FdEventCreate(thr
, pc
, fd
);
1471 TSAN_INTERCEPTOR(int, signalfd
, int fd
, void *mask
, int flags
) {
1472 SCOPED_TSAN_INTERCEPTOR(signalfd
, fd
, mask
, flags
);
1474 FdClose(thr
, pc
, fd
);
1475 fd
= REAL(signalfd
)(fd
, mask
, flags
);
1477 FdSignalCreate(thr
, pc
, fd
);
1481 TSAN_INTERCEPTOR(int, inotify_init
, int fake
) {
1482 SCOPED_TSAN_INTERCEPTOR(inotify_init
, fake
);
1483 int fd
= REAL(inotify_init
)(fake
);
1485 FdInotifyCreate(thr
, pc
, fd
);
1489 TSAN_INTERCEPTOR(int, inotify_init1
, int flags
) {
1490 SCOPED_TSAN_INTERCEPTOR(inotify_init1
, flags
);
1491 int fd
= REAL(inotify_init1
)(flags
);
1493 FdInotifyCreate(thr
, pc
, fd
);
1497 TSAN_INTERCEPTOR(int, socket
, int domain
, int type
, int protocol
) {
1498 SCOPED_TSAN_INTERCEPTOR(socket
, domain
, type
, protocol
);
1499 int fd
= REAL(socket
)(domain
, type
, protocol
);
1501 FdSocketCreate(thr
, pc
, fd
);
1505 TSAN_INTERCEPTOR(int, socketpair
, int domain
, int type
, int protocol
, int *fd
) {
1506 SCOPED_TSAN_INTERCEPTOR(socketpair
, domain
, type
, protocol
, fd
);
1507 int res
= REAL(socketpair
)(domain
, type
, protocol
, fd
);
1508 if (res
== 0 && fd
[0] >= 0 && fd
[1] >= 0)
1509 FdPipeCreate(thr
, pc
, fd
[0], fd
[1]);
1513 TSAN_INTERCEPTOR(int, connect
, int fd
, void *addr
, unsigned addrlen
) {
1514 SCOPED_TSAN_INTERCEPTOR(connect
, fd
, addr
, addrlen
);
1515 FdSocketConnecting(thr
, pc
, fd
);
1516 int res
= REAL(connect
)(fd
, addr
, addrlen
);
1517 if (res
== 0 && fd
>= 0)
1518 FdSocketConnect(thr
, pc
, fd
);
1522 TSAN_INTERCEPTOR(int, bind
, int fd
, void *addr
, unsigned addrlen
) {
1523 SCOPED_TSAN_INTERCEPTOR(bind
, fd
, addr
, addrlen
);
1524 int res
= REAL(bind
)(fd
, addr
, addrlen
);
1525 if (fd
> 0 && res
== 0)
1526 FdAccess(thr
, pc
, fd
);
1530 TSAN_INTERCEPTOR(int, listen
, int fd
, int backlog
) {
1531 SCOPED_TSAN_INTERCEPTOR(listen
, fd
, backlog
);
1532 int res
= REAL(listen
)(fd
, backlog
);
1533 if (fd
> 0 && res
== 0)
1534 FdAccess(thr
, pc
, fd
);
1538 TSAN_INTERCEPTOR(int, epoll_create
, int size
) {
1539 SCOPED_TSAN_INTERCEPTOR(epoll_create
, size
);
1540 int fd
= REAL(epoll_create
)(size
);
1542 FdPollCreate(thr
, pc
, fd
);
1546 TSAN_INTERCEPTOR(int, epoll_create1
, int flags
) {
1547 SCOPED_TSAN_INTERCEPTOR(epoll_create1
, flags
);
1548 int fd
= REAL(epoll_create1
)(flags
);
1550 FdPollCreate(thr
, pc
, fd
);
1554 TSAN_INTERCEPTOR(int, close
, int fd
) {
1555 SCOPED_TSAN_INTERCEPTOR(close
, fd
);
1557 FdClose(thr
, pc
, fd
);
1558 return REAL(close
)(fd
);
1561 TSAN_INTERCEPTOR(int, __close
, int fd
) {
1562 SCOPED_TSAN_INTERCEPTOR(__close
, fd
);
1564 FdClose(thr
, pc
, fd
);
1565 return REAL(__close
)(fd
);
1569 TSAN_INTERCEPTOR(void, __res_iclose
, void *state
, bool free_addr
) {
1570 SCOPED_TSAN_INTERCEPTOR(__res_iclose
, state
, free_addr
);
1572 int cnt
= ExtractResolvFDs(state
, fds
, ARRAY_SIZE(fds
));
1573 for (int i
= 0; i
< cnt
; i
++) {
1575 FdClose(thr
, pc
, fds
[i
]);
1577 REAL(__res_iclose
)(state
, free_addr
);
1580 TSAN_INTERCEPTOR(int, pipe
, int *pipefd
) {
1581 SCOPED_TSAN_INTERCEPTOR(pipe
, pipefd
);
1582 int res
= REAL(pipe
)(pipefd
);
1583 if (res
== 0 && pipefd
[0] >= 0 && pipefd
[1] >= 0)
1584 FdPipeCreate(thr
, pc
, pipefd
[0], pipefd
[1]);
1588 TSAN_INTERCEPTOR(int, pipe2
, int *pipefd
, int flags
) {
1589 SCOPED_TSAN_INTERCEPTOR(pipe2
, pipefd
, flags
);
1590 int res
= REAL(pipe2
)(pipefd
, flags
);
1591 if (res
== 0 && pipefd
[0] >= 0 && pipefd
[1] >= 0)
1592 FdPipeCreate(thr
, pc
, pipefd
[0], pipefd
[1]);
1596 TSAN_INTERCEPTOR(long_t
, send
, int fd
, void *buf
, long_t len
, int flags
) {
1597 SCOPED_TSAN_INTERCEPTOR(send
, fd
, buf
, len
, flags
);
1599 FdAccess(thr
, pc
, fd
);
1600 FdRelease(thr
, pc
, fd
);
1602 int res
= REAL(send
)(fd
, buf
, len
, flags
);
1606 TSAN_INTERCEPTOR(long_t
, sendmsg
, int fd
, void *msg
, int flags
) {
1607 SCOPED_TSAN_INTERCEPTOR(sendmsg
, fd
, msg
, flags
);
1609 FdAccess(thr
, pc
, fd
);
1610 FdRelease(thr
, pc
, fd
);
1612 int res
= REAL(sendmsg
)(fd
, msg
, flags
);
1616 TSAN_INTERCEPTOR(long_t
, recv
, int fd
, void *buf
, long_t len
, int flags
) {
1617 SCOPED_TSAN_INTERCEPTOR(recv
, fd
, buf
, len
, flags
);
1619 FdAccess(thr
, pc
, fd
);
1620 int res
= REAL(recv
)(fd
, buf
, len
, flags
);
1621 if (res
>= 0 && fd
>= 0) {
1622 FdAcquire(thr
, pc
, fd
);
1627 TSAN_INTERCEPTOR(int, unlink
, char *path
) {
1628 SCOPED_TSAN_INTERCEPTOR(unlink
, path
);
1629 Release(thr
, pc
, File2addr(path
));
1630 int res
= REAL(unlink
)(path
);
1634 TSAN_INTERCEPTOR(void*, tmpfile
, int fake
) {
1635 SCOPED_TSAN_INTERCEPTOR(tmpfile
, fake
);
1636 void *res
= REAL(tmpfile
)(fake
);
1638 int fd
= fileno_unlocked(res
);
1640 FdFileCreate(thr
, pc
, fd
);
1645 TSAN_INTERCEPTOR(void*, tmpfile64
, int fake
) {
1646 SCOPED_TSAN_INTERCEPTOR(tmpfile64
, fake
);
1647 void *res
= REAL(tmpfile64
)(fake
);
1649 int fd
= fileno_unlocked(res
);
1651 FdFileCreate(thr
, pc
, fd
);
1656 TSAN_INTERCEPTOR(uptr
, fread
, void *ptr
, uptr size
, uptr nmemb
, void *f
) {
1657 // libc file streams can call user-supplied functions, see fopencookie.
1659 SCOPED_TSAN_INTERCEPTOR(fread
, ptr
, size
, nmemb
, f
);
1660 MemoryAccessRange(thr
, pc
, (uptr
)ptr
, size
* nmemb
, true);
1662 return REAL(fread
)(ptr
, size
, nmemb
, f
);
1665 TSAN_INTERCEPTOR(uptr
, fwrite
, const void *p
, uptr size
, uptr nmemb
, void *f
) {
1666 // libc file streams can call user-supplied functions, see fopencookie.
1668 SCOPED_TSAN_INTERCEPTOR(fwrite
, p
, size
, nmemb
, f
);
1669 MemoryAccessRange(thr
, pc
, (uptr
)p
, size
* nmemb
, false);
1671 return REAL(fwrite
)(p
, size
, nmemb
, f
);
1674 TSAN_INTERCEPTOR(void, abort
, int fake
) {
1675 SCOPED_TSAN_INTERCEPTOR(abort
, fake
);
1680 TSAN_INTERCEPTOR(int, puts
, const char *s
) {
1681 SCOPED_TSAN_INTERCEPTOR(puts
, s
);
1682 MemoryAccessRange(thr
, pc
, (uptr
)s
, internal_strlen(s
), false);
1683 return REAL(puts
)(s
);
1686 TSAN_INTERCEPTOR(int, rmdir
, char *path
) {
1687 SCOPED_TSAN_INTERCEPTOR(rmdir
, path
);
1688 Release(thr
, pc
, Dir2addr(path
));
1689 int res
= REAL(rmdir
)(path
);
1693 TSAN_INTERCEPTOR(void*, opendir
, char *path
) {
1694 SCOPED_TSAN_INTERCEPTOR(opendir
, path
);
1695 void *res
= REAL(opendir
)(path
);
1697 Acquire(thr
, pc
, Dir2addr(path
));
1701 TSAN_INTERCEPTOR(int, epoll_ctl
, int epfd
, int op
, int fd
, void *ev
) {
1702 SCOPED_TSAN_INTERCEPTOR(epoll_ctl
, epfd
, op
, fd
, ev
);
1704 FdAccess(thr
, pc
, epfd
);
1705 if (epfd
>= 0 && fd
>= 0)
1706 FdAccess(thr
, pc
, fd
);
1707 if (op
== EPOLL_CTL_ADD
&& epfd
>= 0)
1708 FdRelease(thr
, pc
, epfd
);
1709 int res
= REAL(epoll_ctl
)(epfd
, op
, fd
, ev
);
1713 TSAN_INTERCEPTOR(int, epoll_wait
, int epfd
, void *ev
, int cnt
, int timeout
) {
1714 SCOPED_TSAN_INTERCEPTOR(epoll_wait
, epfd
, ev
, cnt
, timeout
);
1716 FdAccess(thr
, pc
, epfd
);
1717 int res
= BLOCK_REAL(epoll_wait
)(epfd
, ev
, cnt
, timeout
);
1718 if (res
> 0 && epfd
>= 0)
1719 FdAcquire(thr
, pc
, epfd
);
1725 static void CallUserSignalHandler(ThreadState
*thr
, bool sync
, bool acquire
,
1726 bool sigact
, int sig
, my_siginfo_t
*info
, void *uctx
) {
1728 Acquire(thr
, 0, (uptr
)&sigactions
[sig
]);
1729 // Ensure that the handler does not spoil errno.
1730 const int saved_errno
= errno
;
1732 // Need to remember pc before the call, because the handler can reset it.
1734 (uptr
)sigactions
[sig
].sa_sigaction
:
1735 (uptr
)sigactions
[sig
].sa_handler
;
1736 pc
+= 1; // return address is expected, OutputReport() will undo this
1738 sigactions
[sig
].sa_sigaction(sig
, info
, uctx
);
1740 sigactions
[sig
].sa_handler(sig
);
1741 // We do not detect errno spoiling for SIGTERM,
1742 // because some SIGTERM handlers do spoil errno but reraise SIGTERM,
1743 // tsan reports false positive in such case.
1744 // It's difficult to properly detect this situation (reraise),
1745 // because in async signal processing case (when handler is called directly
1746 // from rtl_generic_sighandler) we have not yet received the reraised
1747 // signal; and it looks too fragile to intercept all ways to reraise a signal.
1748 if (flags()->report_bugs
&& !sync
&& sig
!= SIGTERM
&& errno
!= 99) {
1749 __tsan::StackTrace stack
;
1750 stack
.ObtainCurrent(thr
, pc
);
1751 ThreadRegistryLock
l(ctx
->thread_registry
);
1752 ScopedReport
rep(ReportTypeErrnoInSignal
);
1753 if (!IsFiredSuppression(ctx
, rep
, stack
)) {
1754 rep
.AddStack(&stack
, true);
1755 OutputReport(thr
, rep
);
1758 errno
= saved_errno
;
1761 void ProcessPendingSignals(ThreadState
*thr
) {
1762 SignalContext
*sctx
= SigCtx(thr
);
1764 atomic_load(&sctx
->have_pending_signals
, memory_order_relaxed
) == 0)
1766 atomic_store(&sctx
->have_pending_signals
, 0, memory_order_relaxed
);
1767 atomic_fetch_add(&thr
->in_signal_handler
, 1, memory_order_relaxed
);
1768 // These are too big for stack.
1769 static THREADLOCAL __sanitizer_sigset_t emptyset
, oldset
;
1770 REAL(sigfillset
)(&emptyset
);
1771 pthread_sigmask(SIG_SETMASK
, &emptyset
, &oldset
);
1772 for (int sig
= 0; sig
< kSigCount
; sig
++) {
1773 SignalDesc
*signal
= &sctx
->pending_signals
[sig
];
1774 if (signal
->armed
) {
1775 signal
->armed
= false;
1776 if (sigactions
[sig
].sa_handler
!= SIG_DFL
1777 && sigactions
[sig
].sa_handler
!= SIG_IGN
) {
1778 CallUserSignalHandler(thr
, false, true, signal
->sigaction
,
1779 sig
, &signal
->siginfo
, &signal
->ctx
);
1783 pthread_sigmask(SIG_SETMASK
, &oldset
, 0);
1784 atomic_fetch_add(&thr
->in_signal_handler
, -1, memory_order_relaxed
);
1787 } // namespace __tsan
1789 static bool is_sync_signal(SignalContext
*sctx
, int sig
) {
1790 return sig
== SIGSEGV
|| sig
== SIGBUS
|| sig
== SIGILL
||
1791 sig
== SIGABRT
|| sig
== SIGFPE
|| sig
== SIGPIPE
|| sig
== SIGSYS
||
1792 // If we are sending signal to ourselves, we must process it now.
1793 (sctx
&& sig
== sctx
->int_signal_send
);
1796 void ALWAYS_INLINE
rtl_generic_sighandler(bool sigact
, int sig
,
1797 my_siginfo_t
*info
, void *ctx
) {
1798 ThreadState
*thr
= cur_thread();
1799 SignalContext
*sctx
= SigCtx(thr
);
1800 if (sig
< 0 || sig
>= kSigCount
) {
1801 VPrintf(1, "ThreadSanitizer: ignoring signal %d\n", sig
);
1804 // Don't mess with synchronous signals.
1805 const bool sync
= is_sync_signal(sctx
, sig
);
1807 // If we are in blocking function, we can safely process it now
1808 // (but check if we are in a recursive interceptor,
1809 // i.e. pthread_join()->munmap()).
1810 (sctx
&& atomic_load(&sctx
->in_blocking_func
, memory_order_relaxed
))) {
1811 atomic_fetch_add(&thr
->in_signal_handler
, 1, memory_order_relaxed
);
1812 if (sctx
&& atomic_load(&sctx
->in_blocking_func
, memory_order_relaxed
)) {
1813 // We ignore interceptors in blocking functions,
1814 // temporary enbled them again while we are calling user function.
1815 int const i
= thr
->ignore_interceptors
;
1816 thr
->ignore_interceptors
= 0;
1817 atomic_store(&sctx
->in_blocking_func
, 0, memory_order_relaxed
);
1818 CallUserSignalHandler(thr
, sync
, true, sigact
, sig
, info
, ctx
);
1819 thr
->ignore_interceptors
= i
;
1820 atomic_store(&sctx
->in_blocking_func
, 1, memory_order_relaxed
);
1822 // Be very conservative with when we do acquire in this case.
1823 // It's unsafe to do acquire in async handlers, because ThreadState
1824 // can be in inconsistent state.
1825 // SIGSYS looks relatively safe -- it's synchronous and can actually
1826 // need some global state.
1827 bool acq
= (sig
== SIGSYS
);
1828 CallUserSignalHandler(thr
, sync
, acq
, sigact
, sig
, info
, ctx
);
1830 atomic_fetch_add(&thr
->in_signal_handler
, -1, memory_order_relaxed
);
1836 SignalDesc
*signal
= &sctx
->pending_signals
[sig
];
1837 if (signal
->armed
== false) {
1838 signal
->armed
= true;
1839 signal
->sigaction
= sigact
;
1841 internal_memcpy(&signal
->siginfo
, info
, sizeof(*info
));
1843 internal_memcpy(&signal
->ctx
, ctx
, sizeof(signal
->ctx
));
1844 atomic_store(&sctx
->have_pending_signals
, 1, memory_order_relaxed
);
1848 static void rtl_sighandler(int sig
) {
1849 rtl_generic_sighandler(false, sig
, 0, 0);
1852 static void rtl_sigaction(int sig
, my_siginfo_t
*info
, void *ctx
) {
1853 rtl_generic_sighandler(true, sig
, info
, ctx
);
1856 TSAN_INTERCEPTOR(int, sigaction
, int sig
, sigaction_t
*act
, sigaction_t
*old
) {
1857 SCOPED_TSAN_INTERCEPTOR(sigaction
, sig
, act
, old
);
1859 internal_memcpy(old
, &sigactions
[sig
], sizeof(*old
));
1862 internal_memcpy(&sigactions
[sig
], act
, sizeof(*act
));
1864 internal_memcpy(&newact
, act
, sizeof(newact
));
1865 REAL(sigfillset
)(&newact
.sa_mask
);
1866 if (act
->sa_handler
!= SIG_IGN
&& act
->sa_handler
!= SIG_DFL
) {
1867 if (newact
.sa_flags
& SA_SIGINFO
)
1868 newact
.sa_sigaction
= rtl_sigaction
;
1870 newact
.sa_handler
= rtl_sighandler
;
1872 ReleaseStore(thr
, pc
, (uptr
)&sigactions
[sig
]);
1873 int res
= REAL(sigaction
)(sig
, &newact
, 0);
1877 TSAN_INTERCEPTOR(sighandler_t
, signal
, int sig
, sighandler_t h
) {
1880 REAL(memset
)(&act
.sa_mask
, -1, sizeof(act
.sa_mask
));
1883 int res
= sigaction(sig
, &act
, &old
);
1886 return old
.sa_handler
;
1889 TSAN_INTERCEPTOR(int, sigsuspend
, const __sanitizer_sigset_t
*mask
) {
1890 SCOPED_TSAN_INTERCEPTOR(sigsuspend
, mask
);
1891 return REAL(sigsuspend
)(mask
);
1894 TSAN_INTERCEPTOR(int, raise
, int sig
) {
1895 SCOPED_TSAN_INTERCEPTOR(raise
, sig
);
1896 SignalContext
*sctx
= SigCtx(thr
);
1898 int prev
= sctx
->int_signal_send
;
1899 sctx
->int_signal_send
= sig
;
1900 int res
= REAL(raise
)(sig
);
1901 CHECK_EQ(sctx
->int_signal_send
, sig
);
1902 sctx
->int_signal_send
= prev
;
1906 TSAN_INTERCEPTOR(int, kill
, int pid
, int sig
) {
1907 SCOPED_TSAN_INTERCEPTOR(kill
, pid
, sig
);
1908 SignalContext
*sctx
= SigCtx(thr
);
1910 int prev
= sctx
->int_signal_send
;
1911 if (pid
== (int)internal_getpid()) {
1912 sctx
->int_signal_send
= sig
;
1914 int res
= REAL(kill
)(pid
, sig
);
1915 if (pid
== (int)internal_getpid()) {
1916 CHECK_EQ(sctx
->int_signal_send
, sig
);
1917 sctx
->int_signal_send
= prev
;
1922 TSAN_INTERCEPTOR(int, pthread_kill
, void *tid
, int sig
) {
1923 SCOPED_TSAN_INTERCEPTOR(pthread_kill
, tid
, sig
);
1924 SignalContext
*sctx
= SigCtx(thr
);
1926 int prev
= sctx
->int_signal_send
;
1927 if (tid
== pthread_self()) {
1928 sctx
->int_signal_send
= sig
;
1930 int res
= REAL(pthread_kill
)(tid
, sig
);
1931 if (tid
== pthread_self()) {
1932 CHECK_EQ(sctx
->int_signal_send
, sig
);
1933 sctx
->int_signal_send
= prev
;
1938 TSAN_INTERCEPTOR(int, gettimeofday
, void *tv
, void *tz
) {
1939 SCOPED_TSAN_INTERCEPTOR(gettimeofday
, tv
, tz
);
1940 // It's intercepted merely to process pending signals.
1941 return REAL(gettimeofday
)(tv
, tz
);
1944 TSAN_INTERCEPTOR(int, getaddrinfo
, void *node
, void *service
,
1945 void *hints
, void *rv
) {
1946 SCOPED_TSAN_INTERCEPTOR(getaddrinfo
, node
, service
, hints
, rv
);
1947 // We miss atomic synchronization in getaddrinfo,
1948 // and can report false race between malloc and free
1949 // inside of getaddrinfo. So ignore memory accesses.
1950 ThreadIgnoreBegin(thr
, pc
);
1951 int res
= REAL(getaddrinfo
)(node
, service
, hints
, rv
);
1952 ThreadIgnoreEnd(thr
, pc
);
1956 TSAN_INTERCEPTOR(int, fork
, int fake
) {
1957 if (cur_thread()->in_symbolizer
)
1958 return REAL(fork
)(fake
);
1959 SCOPED_INTERCEPTOR_RAW(fork
, fake
);
1960 ForkBefore(thr
, pc
);
1961 int pid
= REAL(fork
)(fake
);
1964 ForkChildAfter(thr
, pc
);
1966 } else if (pid
> 0) {
1968 ForkParentAfter(thr
, pc
);
1971 ForkParentAfter(thr
, pc
);
1976 TSAN_INTERCEPTOR(int, vfork
, int fake
) {
1977 // Some programs (e.g. openjdk) call close for all file descriptors
1978 // in the child process. Under tsan it leads to false positives, because
1979 // address space is shared, so the parent process also thinks that
1980 // the descriptors are closed (while they are actually not).
1981 // This leads to false positives due to missed synchronization.
1982 // Strictly saying this is undefined behavior, because vfork child is not
1983 // allowed to call any functions other than exec/exit. But this is what
1984 // openjdk does, so we want to handle it.
1985 // We could disable interceptors in the child process. But it's not possible
1986 // to simply intercept and wrap vfork, because vfork child is not allowed
1987 // to return from the function that calls vfork, and that's exactly what
1988 // we would do. So this would require some assembly trickery as well.
1989 // Instead we simply turn vfork into fork.
1990 return WRAP(fork
)(fake
);
1993 static int OnExit(ThreadState
*thr
) {
1994 int status
= Finalize(thr
);
1999 struct TsanInterceptorContext
{
2001 const uptr caller_pc
;
2005 static void HandleRecvmsg(ThreadState
*thr
, uptr pc
,
2006 __sanitizer_msghdr
*msg
) {
2008 int cnt
= ExtractRecvmsgFDs(msg
, fds
, ARRAY_SIZE(fds
));
2009 for (int i
= 0; i
< cnt
; i
++)
2010 FdEventCreate(thr
, pc
, fds
[i
]);
2013 #include "sanitizer_common/sanitizer_platform_interceptors.h"
2014 // Causes interceptor recursion (getaddrinfo() and fopen())
2015 #undef SANITIZER_INTERCEPT_GETADDRINFO
2016 // There interceptors do not seem to be strictly necessary for tsan.
2017 // But we see cases where the interceptors consume 70% of execution time.
2018 // Memory blocks passed to fgetgrent_r are "written to" by tsan several times.
2019 // First, there is some recursion (getgrnam_r calls fgetgrent_r), and each
2020 // function "writes to" the buffer. Then, the same memory is "written to"
2021 // twice, first as buf and then as pwbufp (both of them refer to the same
2023 #undef SANITIZER_INTERCEPT_GETPWENT
2024 #undef SANITIZER_INTERCEPT_GETPWENT_R
2025 #undef SANITIZER_INTERCEPT_FGETPWENT
2026 #undef SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS
2027 #undef SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
2029 #define COMMON_INTERCEPT_FUNCTION(name) INTERCEPT_FUNCTION(name)
2031 #define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
2032 MemoryAccessRange(((TsanInterceptorContext *)ctx)->thr, \
2033 ((TsanInterceptorContext *)ctx)->pc, (uptr)ptr, size, \
2036 #define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \
2037 MemoryAccessRange(((TsanInterceptorContext *) ctx)->thr, \
2038 ((TsanInterceptorContext *) ctx)->pc, (uptr) ptr, size, \
2041 #define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \
2042 SCOPED_TSAN_INTERCEPTOR(func, __VA_ARGS__); \
2043 TsanInterceptorContext _ctx = {thr, caller_pc, pc}; \
2044 ctx = (void *)&_ctx; \
2047 #define COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, func, ...) \
2048 SCOPED_INTERCEPTOR_RAW(func, __VA_ARGS__); \
2049 TsanInterceptorContext _ctx = {thr, caller_pc, pc}; \
2050 ctx = (void *)&_ctx; \
2053 #define COMMON_INTERCEPTOR_FILE_OPEN(ctx, file, path) \
2054 Acquire(thr, pc, File2addr(path)); \
2056 int fd = fileno_unlocked(file); \
2057 if (fd >= 0) FdFileCreate(thr, pc, fd); \
2060 #define COMMON_INTERCEPTOR_FILE_CLOSE(ctx, file) \
2062 int fd = fileno_unlocked(file); \
2063 if (fd >= 0) FdClose(thr, pc, fd); \
2066 #define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, res) \
2067 libignore()->OnLibraryLoaded(filename)
2069 #define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() \
2070 libignore()->OnLibraryUnloaded()
2072 #define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \
2073 FdAcquire(((TsanInterceptorContext *) ctx)->thr, pc, fd)
2075 #define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \
2076 FdRelease(((TsanInterceptorContext *) ctx)->thr, pc, fd)
2078 #define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) \
2079 FdAccess(((TsanInterceptorContext *) ctx)->thr, pc, fd)
2081 #define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \
2082 FdSocketAccept(((TsanInterceptorContext *) ctx)->thr, pc, fd, newfd)
2084 #define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) \
2085 ThreadSetName(((TsanInterceptorContext *) ctx)->thr, name)
2087 #define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name) \
2088 __tsan::ctx->thread_registry->SetThreadNameByUserId(thread, name)
2090 #define COMMON_INTERCEPTOR_BLOCK_REAL(name) BLOCK_REAL(name)
2092 #define COMMON_INTERCEPTOR_ON_EXIT(ctx) \
2093 OnExit(((TsanInterceptorContext *) ctx)->thr)
2095 #define COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m) \
2096 MutexLock(((TsanInterceptorContext *)ctx)->thr, \
2097 ((TsanInterceptorContext *)ctx)->pc, (uptr)m)
2099 #define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) \
2100 MutexUnlock(((TsanInterceptorContext *)ctx)->thr, \
2101 ((TsanInterceptorContext *)ctx)->pc, (uptr)m)
2103 #define COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m) \
2104 MutexRepair(((TsanInterceptorContext *)ctx)->thr, \
2105 ((TsanInterceptorContext *)ctx)->pc, (uptr)m)
2107 #define COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg) \
2108 HandleRecvmsg(((TsanInterceptorContext *)ctx)->thr, \
2109 ((TsanInterceptorContext *)ctx)->pc, msg)
2111 #include "sanitizer_common/sanitizer_common_interceptors.inc"
2113 #define TSAN_SYSCALL() \
2114 ThreadState *thr = cur_thread(); \
2115 if (thr->ignore_interceptors) \
2117 ScopedSyscall scoped_syscall(thr) \
2120 struct ScopedSyscall
{
2123 explicit ScopedSyscall(ThreadState
*thr
)
2129 ProcessPendingSignals(thr
);
2133 static void syscall_access_range(uptr pc
, uptr p
, uptr s
, bool write
) {
2135 MemoryAccessRange(thr
, pc
, p
, s
, write
);
2138 static void syscall_acquire(uptr pc
, uptr addr
) {
2140 Acquire(thr
, pc
, addr
);
2141 DPrintf("syscall_acquire(%p)\n", addr
);
2144 static void syscall_release(uptr pc
, uptr addr
) {
2146 DPrintf("syscall_release(%p)\n", addr
);
2147 Release(thr
, pc
, addr
);
2150 static void syscall_fd_close(uptr pc
, int fd
) {
2152 FdClose(thr
, pc
, fd
);
2155 static USED
void syscall_fd_acquire(uptr pc
, int fd
) {
2157 FdAcquire(thr
, pc
, fd
);
2158 DPrintf("syscall_fd_acquire(%p)\n", fd
);
2161 static USED
void syscall_fd_release(uptr pc
, int fd
) {
2163 DPrintf("syscall_fd_release(%p)\n", fd
);
2164 FdRelease(thr
, pc
, fd
);
2167 static void syscall_pre_fork(uptr pc
) {
2169 ForkBefore(thr
, pc
);
2172 static void syscall_post_fork(uptr pc
, int pid
) {
2176 ForkChildAfter(thr
, pc
);
2178 } else if (pid
> 0) {
2180 ForkParentAfter(thr
, pc
);
2183 ForkParentAfter(thr
, pc
);
2187 #define COMMON_SYSCALL_PRE_READ_RANGE(p, s) \
2188 syscall_access_range(GET_CALLER_PC(), (uptr)(p), (uptr)(s), false)
2190 #define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) \
2191 syscall_access_range(GET_CALLER_PC(), (uptr)(p), (uptr)(s), true)
2193 #define COMMON_SYSCALL_POST_READ_RANGE(p, s) \
2199 #define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) \
2205 #define COMMON_SYSCALL_ACQUIRE(addr) \
2206 syscall_acquire(GET_CALLER_PC(), (uptr)(addr))
2208 #define COMMON_SYSCALL_RELEASE(addr) \
2209 syscall_release(GET_CALLER_PC(), (uptr)(addr))
2211 #define COMMON_SYSCALL_FD_CLOSE(fd) syscall_fd_close(GET_CALLER_PC(), fd)
2213 #define COMMON_SYSCALL_FD_ACQUIRE(fd) syscall_fd_acquire(GET_CALLER_PC(), fd)
2215 #define COMMON_SYSCALL_FD_RELEASE(fd) syscall_fd_release(GET_CALLER_PC(), fd)
2217 #define COMMON_SYSCALL_PRE_FORK() \
2218 syscall_pre_fork(GET_CALLER_PC())
2220 #define COMMON_SYSCALL_POST_FORK(res) \
2221 syscall_post_fork(GET_CALLER_PC(), res)
2223 #include "sanitizer_common/sanitizer_common_syscalls.inc"
2227 static void finalize(void *arg
) {
2228 ThreadState
*thr
= cur_thread();
2230 atexit_ctx
->exit(thr
, pc
);
2231 int status
= Finalize(thr
);
2232 // Make sure the output is not lost.
2233 // Flushing all the streams here may freeze the process if a child thread is
2234 // performing file stream operations at the same time.
2235 REAL(fflush
)(stdout
);
2236 REAL(fflush
)(stderr
);
2238 REAL(_exit
)(status
);
2241 static void unreachable() {
2242 Report("FATAL: ThreadSanitizer: unreachable called\n");
2246 void InitializeInterceptors() {
2247 // We need to setup it early, because functions like dlsym() can call it.
2248 REAL(memset
) = internal_memset
;
2249 REAL(memcpy
) = internal_memcpy
;
2250 REAL(memcmp
) = internal_memcmp
;
2252 // Instruct libc malloc to consume less memory.
2253 mallopt(1, 0); // M_MXFAST
2254 mallopt(-3, 32*1024); // M_MMAP_THRESHOLD
2256 InitializeCommonInterceptors();
2258 // We can not use TSAN_INTERCEPT to get setjmp addr,
2259 // because it does &setjmp and setjmp is not present in some versions of libc.
2260 using __interception::GetRealFunctionAddress
;
2261 GetRealFunctionAddress("setjmp", (uptr
*)&REAL(setjmp
), 0, 0);
2262 GetRealFunctionAddress("_setjmp", (uptr
*)&REAL(_setjmp
), 0, 0);
2263 GetRealFunctionAddress("sigsetjmp", (uptr
*)&REAL(sigsetjmp
), 0, 0);
2264 GetRealFunctionAddress("__sigsetjmp", (uptr
*)&REAL(__sigsetjmp
), 0, 0);
2266 TSAN_INTERCEPT(longjmp
);
2267 TSAN_INTERCEPT(siglongjmp
);
2269 TSAN_INTERCEPT(malloc
);
2270 TSAN_INTERCEPT(__libc_memalign
);
2271 TSAN_INTERCEPT(calloc
);
2272 TSAN_INTERCEPT(realloc
);
2273 TSAN_INTERCEPT(free
);
2274 TSAN_INTERCEPT(cfree
);
2275 TSAN_INTERCEPT(mmap
);
2276 TSAN_INTERCEPT(mmap64
);
2277 TSAN_INTERCEPT(munmap
);
2278 TSAN_INTERCEPT(memalign
);
2279 TSAN_INTERCEPT(valloc
);
2280 TSAN_INTERCEPT(pvalloc
);
2281 TSAN_INTERCEPT(posix_memalign
);
2283 TSAN_INTERCEPT(strlen
);
2284 TSAN_INTERCEPT(memset
);
2285 TSAN_INTERCEPT(memcpy
);
2286 TSAN_INTERCEPT(memmove
);
2287 TSAN_INTERCEPT(memcmp
);
2288 TSAN_INTERCEPT(strchr
);
2289 TSAN_INTERCEPT(strchrnul
);
2290 TSAN_INTERCEPT(strrchr
);
2291 TSAN_INTERCEPT(strcpy
); // NOLINT
2292 TSAN_INTERCEPT(strncpy
);
2293 TSAN_INTERCEPT(strstr
);
2294 TSAN_INTERCEPT(strdup
);
2296 TSAN_INTERCEPT(pthread_create
);
2297 TSAN_INTERCEPT(pthread_join
);
2298 TSAN_INTERCEPT(pthread_detach
);
2300 TSAN_INTERCEPT_VER(pthread_cond_init
, "GLIBC_2.3.2");
2301 TSAN_INTERCEPT_VER(pthread_cond_signal
, "GLIBC_2.3.2");
2302 TSAN_INTERCEPT_VER(pthread_cond_broadcast
, "GLIBC_2.3.2");
2303 TSAN_INTERCEPT_VER(pthread_cond_wait
, "GLIBC_2.3.2");
2304 TSAN_INTERCEPT_VER(pthread_cond_timedwait
, "GLIBC_2.3.2");
2305 TSAN_INTERCEPT_VER(pthread_cond_destroy
, "GLIBC_2.3.2");
2307 TSAN_INTERCEPT(pthread_mutex_init
);
2308 TSAN_INTERCEPT(pthread_mutex_destroy
);
2309 TSAN_INTERCEPT(pthread_mutex_trylock
);
2310 TSAN_INTERCEPT(pthread_mutex_timedlock
);
2312 TSAN_INTERCEPT(pthread_spin_init
);
2313 TSAN_INTERCEPT(pthread_spin_destroy
);
2314 TSAN_INTERCEPT(pthread_spin_lock
);
2315 TSAN_INTERCEPT(pthread_spin_trylock
);
2316 TSAN_INTERCEPT(pthread_spin_unlock
);
2318 TSAN_INTERCEPT(pthread_rwlock_init
);
2319 TSAN_INTERCEPT(pthread_rwlock_destroy
);
2320 TSAN_INTERCEPT(pthread_rwlock_rdlock
);
2321 TSAN_INTERCEPT(pthread_rwlock_tryrdlock
);
2322 TSAN_INTERCEPT(pthread_rwlock_timedrdlock
);
2323 TSAN_INTERCEPT(pthread_rwlock_wrlock
);
2324 TSAN_INTERCEPT(pthread_rwlock_trywrlock
);
2325 TSAN_INTERCEPT(pthread_rwlock_timedwrlock
);
2326 TSAN_INTERCEPT(pthread_rwlock_unlock
);
2328 TSAN_INTERCEPT(pthread_barrier_init
);
2329 TSAN_INTERCEPT(pthread_barrier_destroy
);
2330 TSAN_INTERCEPT(pthread_barrier_wait
);
2332 TSAN_INTERCEPT(pthread_once
);
2334 TSAN_INTERCEPT(sem_init
);
2335 TSAN_INTERCEPT(sem_destroy
);
2336 TSAN_INTERCEPT(sem_wait
);
2337 TSAN_INTERCEPT(sem_trywait
);
2338 TSAN_INTERCEPT(sem_timedwait
);
2339 TSAN_INTERCEPT(sem_post
);
2340 TSAN_INTERCEPT(sem_getvalue
);
2342 TSAN_INTERCEPT(stat
);
2343 TSAN_INTERCEPT(__xstat
);
2344 TSAN_INTERCEPT(stat64
);
2345 TSAN_INTERCEPT(__xstat64
);
2346 TSAN_INTERCEPT(lstat
);
2347 TSAN_INTERCEPT(__lxstat
);
2348 TSAN_INTERCEPT(lstat64
);
2349 TSAN_INTERCEPT(__lxstat64
);
2350 TSAN_INTERCEPT(fstat
);
2351 TSAN_INTERCEPT(__fxstat
);
2352 TSAN_INTERCEPT(fstat64
);
2353 TSAN_INTERCEPT(__fxstat64
);
2354 TSAN_INTERCEPT(open
);
2355 TSAN_INTERCEPT(open64
);
2356 TSAN_INTERCEPT(creat
);
2357 TSAN_INTERCEPT(creat64
);
2358 TSAN_INTERCEPT(dup
);
2359 TSAN_INTERCEPT(dup2
);
2360 TSAN_INTERCEPT(dup3
);
2361 TSAN_INTERCEPT(eventfd
);
2362 TSAN_INTERCEPT(signalfd
);
2363 TSAN_INTERCEPT(inotify_init
);
2364 TSAN_INTERCEPT(inotify_init1
);
2365 TSAN_INTERCEPT(socket
);
2366 TSAN_INTERCEPT(socketpair
);
2367 TSAN_INTERCEPT(connect
);
2368 TSAN_INTERCEPT(bind
);
2369 TSAN_INTERCEPT(listen
);
2370 TSAN_INTERCEPT(epoll_create
);
2371 TSAN_INTERCEPT(epoll_create1
);
2372 TSAN_INTERCEPT(close
);
2373 TSAN_INTERCEPT(__close
);
2374 TSAN_INTERCEPT(__res_iclose
);
2375 TSAN_INTERCEPT(pipe
);
2376 TSAN_INTERCEPT(pipe2
);
2378 TSAN_INTERCEPT(send
);
2379 TSAN_INTERCEPT(sendmsg
);
2380 TSAN_INTERCEPT(recv
);
2382 TSAN_INTERCEPT(unlink
);
2383 TSAN_INTERCEPT(tmpfile
);
2384 TSAN_INTERCEPT(tmpfile64
);
2385 TSAN_INTERCEPT(fread
);
2386 TSAN_INTERCEPT(fwrite
);
2387 TSAN_INTERCEPT(abort
);
2388 TSAN_INTERCEPT(puts
);
2389 TSAN_INTERCEPT(rmdir
);
2390 TSAN_INTERCEPT(opendir
);
2392 TSAN_INTERCEPT(epoll_ctl
);
2393 TSAN_INTERCEPT(epoll_wait
);
2395 TSAN_INTERCEPT(sigaction
);
2396 TSAN_INTERCEPT(signal
);
2397 TSAN_INTERCEPT(sigsuspend
);
2398 TSAN_INTERCEPT(raise
);
2399 TSAN_INTERCEPT(kill
);
2400 TSAN_INTERCEPT(pthread_kill
);
2401 TSAN_INTERCEPT(sleep
);
2402 TSAN_INTERCEPT(usleep
);
2403 TSAN_INTERCEPT(nanosleep
);
2404 TSAN_INTERCEPT(gettimeofday
);
2405 TSAN_INTERCEPT(getaddrinfo
);
2407 TSAN_INTERCEPT(fork
);
2408 TSAN_INTERCEPT(vfork
);
2409 TSAN_INTERCEPT(on_exit
);
2410 TSAN_INTERCEPT(__cxa_atexit
);
2411 TSAN_INTERCEPT(_exit
);
2413 // Need to setup it, because interceptors check that the function is resolved.
2414 // But atexit is emitted directly into the module, so can't be resolved.
2415 REAL(atexit
) = (int(*)(void(*)()))unreachable
;
2416 atexit_ctx
= new(internal_alloc(MBlockAtExit
, sizeof(AtExitContext
)))
2419 if (REAL(__cxa_atexit
)(&finalize
, 0, 0)) {
2420 Printf("ThreadSanitizer: failed to setup atexit callback\n");
2424 if (pthread_key_create(&g_thread_finalize_key
, &thread_finalize
)) {
2425 Printf("ThreadSanitizer: failed to create thread key\n");
2431 // Remember list of loaded libraries for atexit interceptors.
2432 modules
= (LoadedModule
*)MmapOrDie(sizeof(*modules
)*kMaxModules
,
2434 nmodules
= GetListOfModules(modules
, kMaxModules
, 0);
2437 void *internal_start_thread(void(*func
)(void *arg
), void *arg
) {
2438 // Start the thread with signals blocked, otherwise it can steal user signals.
2439 __sanitizer_sigset_t set
, old
;
2440 internal_sigfillset(&set
);
2441 internal_sigprocmask(SIG_SETMASK
, &set
, &old
);
2443 REAL(pthread_create
)(&th
, 0, (void*(*)(void *arg
))func
, arg
);
2444 internal_sigprocmask(SIG_SETMASK
, &old
, 0);
2448 void internal_join_thread(void *th
) {
2449 REAL(pthread_join
)(th
, 0);
2452 } // namespace __tsan