1 //===-- tsan_interceptors.cc ----------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file is a part of ThreadSanitizer (TSan), a race detector.
12 // FIXME: move as many interceptors as possible into
13 // sanitizer_common/sanitizer_common_interceptors.h
14 //===----------------------------------------------------------------------===//
16 #include "sanitizer_common/sanitizer_atomic.h"
17 #include "sanitizer_common/sanitizer_libc.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"
24 #include "tsan_mman.h"
27 using namespace __tsan
; // NOLINT
29 const int kSigCount
= 128;
36 u64 val
[1024 / 8 / sizeof(u64
)];
43 extern "C" int pthread_attr_init(void *attr
);
44 extern "C" int pthread_attr_destroy(void *attr
);
45 extern "C" int pthread_attr_getdetachstate(void *attr
, int *v
);
46 extern "C" int pthread_attr_setstacksize(void *attr
, uptr stacksize
);
47 extern "C" int pthread_attr_getstacksize(void *attr
, uptr
*stacksize
);
48 extern "C" int pthread_key_create(unsigned *key
, void (*destructor
)(void* v
));
49 extern "C" int pthread_setspecific(unsigned key
, const void *v
);
50 extern "C" int pthread_mutexattr_gettype(void *a
, int *type
);
51 extern "C" int pthread_yield();
52 extern "C" int pthread_sigmask(int how
, const sigset_t
*set
, sigset_t
*oldset
);
53 extern "C" int sigfillset(sigset_t
*set
);
54 extern "C" void *pthread_self();
55 extern "C" void _exit(int status
);
56 extern "C" int *__errno_location();
57 extern "C" int fileno_unlocked(void *stream
);
58 extern "C" void *__libc_malloc(uptr size
);
59 extern "C" void *__libc_calloc(uptr size
, uptr n
);
60 extern "C" void *__libc_realloc(void *ptr
, uptr size
);
61 extern "C" void __libc_free(void *ptr
);
62 const int PTHREAD_MUTEX_RECURSIVE
= 1;
63 const int PTHREAD_MUTEX_RECURSIVE_NP
= 1;
64 const int kPthreadAttrSize
= 56;
65 const int EINVAL
= 22;
67 const int EPOLL_CTL_ADD
= 1;
69 const int SIGABRT
= 6;
71 const int SIGSEGV
= 11;
72 const int SIGPIPE
= 13;
74 void *const MAP_FAILED
= (void*)-1;
75 const int PTHREAD_BARRIER_SERIAL_THREAD
= -1;
76 const int MAP_FIXED
= 0x10;
77 typedef long long_t
; // NOLINT
79 // From /usr/include/unistd.h
80 # define F_ULOCK 0 /* Unlock a previously locked region. */
81 # define F_LOCK 1 /* Lock a region for exclusive use. */
82 # define F_TLOCK 2 /* Test and lock a region for exclusive use. */
83 # define F_TEST 3 /* Test a region for other processes locks. */
85 typedef void (*sighandler_t
)(int sig
);
87 #define errno (*__errno_location())
89 union pthread_attr_t
{
90 char size
[kPthreadAttrSize
];
96 sighandler_t sa_handler
;
97 void (*sa_sigaction
)(int sig
, my_siginfo_t
*siginfo
, void *uctx
);
101 void (*sa_restorer
)();
104 const sighandler_t SIG_DFL
= (sighandler_t
)0;
105 const sighandler_t SIG_IGN
= (sighandler_t
)1;
106 const sighandler_t SIG_ERR
= (sighandler_t
)-1;
107 const int SA_SIGINFO
= 4;
108 const int SIG_SETMASK
= 2;
114 static sigaction_t sigactions
[kSigCount
];
120 my_siginfo_t siginfo
;
124 struct SignalContext
{
125 int in_blocking_func
;
127 int pending_signal_count
;
128 SignalDesc pending_signals
[kSigCount
];
130 } // namespace __tsan
132 static SignalContext
*SigCtx(ThreadState
*thr
) {
133 SignalContext
*ctx
= (SignalContext
*)thr
->signal_ctx
;
134 if (ctx
== 0 && thr
->is_alive
) {
136 ctx
= (SignalContext
*)MmapOrDie(sizeof(*ctx
), "SignalContext");
137 MemoryResetRange(thr
, (uptr
)&SigCtx
, (uptr
)ctx
, sizeof(*ctx
));
138 thr
->signal_ctx
= ctx
;
143 static unsigned g_thread_finalize_key
;
145 class ScopedInterceptor
{
147 ScopedInterceptor(ThreadState
*thr
, const char *fname
, uptr pc
);
148 ~ScopedInterceptor();
150 ThreadState
*const thr_
;
154 ScopedInterceptor::ScopedInterceptor(ThreadState
*thr
, const char *fname
,
157 , in_rtl_(thr
->in_rtl
) {
158 if (thr_
->in_rtl
== 0) {
162 DPrintf("#%d: intercept %s()\n", thr_
->tid
, fname
);
168 ScopedInterceptor::~ScopedInterceptor() {
170 if (thr_
->in_rtl
== 0) {
172 ProcessPendingSignals(thr_
);
174 CHECK_EQ(in_rtl_
, thr_
->in_rtl
);
177 #define SCOPED_INTERCEPTOR_RAW(func, ...) \
178 ThreadState *thr = cur_thread(); \
179 StatInc(thr, StatInterceptor); \
180 StatInc(thr, StatInt_##func); \
181 const uptr caller_pc = GET_CALLER_PC(); \
182 ScopedInterceptor si(thr, #func, caller_pc); \
183 const uptr pc = __sanitizer::StackTrace::GetPreviousInstructionPc( \
184 __sanitizer::StackTrace::GetCurrentPc()); \
188 #define SCOPED_TSAN_INTERCEPTOR(func, ...) \
189 SCOPED_INTERCEPTOR_RAW(func, __VA_ARGS__); \
190 if (REAL(func) == 0) { \
191 Printf("FATAL: ThreadSanitizer: failed to intercept %s\n", #func); \
194 if (thr->in_rtl > 1) \
195 return REAL(func)(__VA_ARGS__); \
198 #define TSAN_INTERCEPTOR(ret, func, ...) INTERCEPTOR(ret, func, __VA_ARGS__)
199 #define TSAN_INTERCEPT(func) INTERCEPT_FUNCTION(func)
201 #define BLOCK_REAL(name) (BlockingCall(thr), REAL(name))
203 struct BlockingCall
{
204 explicit BlockingCall(ThreadState
*thr
)
206 ctx
->in_blocking_func
++;
210 ctx
->in_blocking_func
--;
216 TSAN_INTERCEPTOR(unsigned, sleep
, unsigned sec
) {
217 SCOPED_TSAN_INTERCEPTOR(sleep
, sec
);
218 unsigned res
= BLOCK_REAL(sleep
)(sec
);
223 TSAN_INTERCEPTOR(int, usleep
, long_t usec
) {
224 SCOPED_TSAN_INTERCEPTOR(usleep
, usec
);
225 int res
= BLOCK_REAL(usleep
)(usec
);
230 TSAN_INTERCEPTOR(int, nanosleep
, void *req
, void *rem
) {
231 SCOPED_TSAN_INTERCEPTOR(nanosleep
, req
, rem
);
232 int res
= BLOCK_REAL(nanosleep
)(req
, rem
);
237 class AtExitContext
{
240 : mtx_(MutexTypeAtExit
, StatMtxAtExit
)
244 typedef void(*atexit_t
)();
246 int atexit(ThreadState
*thr
, uptr pc
, bool is_on_exit
,
247 atexit_t f
, void *arg
) {
249 if (pos_
== kMaxAtExit
)
251 Release(thr
, pc
, (uptr
)this);
254 is_on_exits_
[pos_
] = is_on_exit
;
259 void exit(ThreadState
*thr
, uptr pc
) {
260 CHECK_EQ(thr
->in_rtl
, 0);
264 bool is_on_exit
= false;
271 is_on_exit
= is_on_exits_
[pos_
];
273 Acquire(thr
, pc
, (uptr
)this);
278 DPrintf("#%d: executing atexit func %p\n", thr
->tid
, f
);
279 CHECK_EQ(thr
->in_rtl
, 0);
281 ((void(*)(int status
, void *arg
))f
)(0, arg
);
283 ((void(*)(void *arg
, void *dso
))f
)(arg
, 0);
288 static const int kMaxAtExit
= 128;
290 atexit_t stack_
[kMaxAtExit
];
291 void *args_
[kMaxAtExit
];
292 bool is_on_exits_
[kMaxAtExit
];
296 static AtExitContext
*atexit_ctx
;
298 static void finalize(void *arg
) {
299 ThreadState
* thr
= cur_thread();
301 atexit_ctx
->exit(thr
, pc
);
302 int status
= Finalize(cur_thread());
307 TSAN_INTERCEPTOR(int, atexit
, void (*f
)()) {
308 if (cur_thread()->in_symbolizer
)
310 SCOPED_TSAN_INTERCEPTOR(atexit
, f
);
311 return atexit_ctx
->atexit(thr
, pc
, false, (void(*)())f
, 0);
314 TSAN_INTERCEPTOR(int, on_exit
, void(*f
)(int, void*), void *arg
) {
315 if (cur_thread()->in_symbolizer
)
317 SCOPED_TSAN_INTERCEPTOR(on_exit
, f
, arg
);
318 return atexit_ctx
->atexit(thr
, pc
, true, (void(*)())f
, arg
);
321 TSAN_INTERCEPTOR(int, __cxa_atexit
, void (*f
)(void *a
), void *arg
, void *dso
) {
322 if (cur_thread()->in_symbolizer
)
324 SCOPED_TSAN_INTERCEPTOR(__cxa_atexit
, f
, arg
, dso
);
326 return REAL(__cxa_atexit
)(f
, arg
, dso
);
327 return atexit_ctx
->atexit(thr
, pc
, false, (void(*)())f
, arg
);
330 TSAN_INTERCEPTOR(void, longjmp
, void *env
, int val
) {
331 SCOPED_TSAN_INTERCEPTOR(longjmp
, env
, val
);
332 Printf("ThreadSanitizer: longjmp() is not supported\n");
336 TSAN_INTERCEPTOR(void, siglongjmp
, void *env
, int val
) {
337 SCOPED_TSAN_INTERCEPTOR(siglongjmp
, env
, val
);
338 Printf("ThreadSanitizer: siglongjmp() is not supported\n");
342 TSAN_INTERCEPTOR(void*, malloc
, uptr size
) {
343 if (cur_thread()->in_symbolizer
)
344 return __libc_malloc(size
);
347 SCOPED_INTERCEPTOR_RAW(malloc
, size
);
348 p
= user_alloc(thr
, pc
, size
);
350 invoke_malloc_hook(p
, size
);
354 TSAN_INTERCEPTOR(void*, __libc_memalign
, uptr align
, uptr sz
) {
355 SCOPED_TSAN_INTERCEPTOR(__libc_memalign
, align
, sz
);
356 return user_alloc(thr
, pc
, sz
, align
);
359 TSAN_INTERCEPTOR(void*, calloc
, uptr size
, uptr n
) {
360 if (cur_thread()->in_symbolizer
)
361 return __libc_calloc(size
, n
);
362 if (__sanitizer::CallocShouldReturnNullDueToOverflow(size
, n
)) return 0;
365 SCOPED_INTERCEPTOR_RAW(calloc
, size
, n
);
366 p
= user_alloc(thr
, pc
, n
* size
);
367 if (p
) internal_memset(p
, 0, n
* size
);
369 invoke_malloc_hook(p
, n
* size
);
373 TSAN_INTERCEPTOR(void*, realloc
, void *p
, uptr size
) {
374 if (cur_thread()->in_symbolizer
)
375 return __libc_realloc(p
, size
);
379 SCOPED_INTERCEPTOR_RAW(realloc
, p
, size
);
380 p
= user_realloc(thr
, pc
, p
, size
);
382 invoke_malloc_hook(p
, size
);
386 TSAN_INTERCEPTOR(void, free
, void *p
) {
389 if (cur_thread()->in_symbolizer
)
390 return __libc_free(p
);
392 SCOPED_INTERCEPTOR_RAW(free
, p
);
393 user_free(thr
, pc
, p
);
396 TSAN_INTERCEPTOR(void, cfree
, void *p
) {
399 if (cur_thread()->in_symbolizer
)
400 return __libc_free(p
);
402 SCOPED_INTERCEPTOR_RAW(cfree
, p
);
403 user_free(thr
, pc
, p
);
406 #define OPERATOR_NEW_BODY(mangled_name) \
407 if (cur_thread()->in_symbolizer) \
408 return __libc_malloc(size); \
411 SCOPED_INTERCEPTOR_RAW(mangled_name, size); \
412 p = user_alloc(thr, pc, size); \
414 invoke_malloc_hook(p, size); \
417 void *operator new(__sanitizer::uptr size
) {
418 OPERATOR_NEW_BODY(_Znwm
);
420 void *operator new[](__sanitizer::uptr size
) {
421 OPERATOR_NEW_BODY(_Znam
);
423 void *operator new(__sanitizer::uptr size
, std::nothrow_t
const&) {
424 OPERATOR_NEW_BODY(_ZnwmRKSt9nothrow_t
);
426 void *operator new[](__sanitizer::uptr size
, std::nothrow_t
const&) {
427 OPERATOR_NEW_BODY(_ZnamRKSt9nothrow_t
);
430 #define OPERATOR_DELETE_BODY(mangled_name) \
431 if (ptr == 0) return; \
432 if (cur_thread()->in_symbolizer) \
433 return __libc_free(ptr); \
434 invoke_free_hook(ptr); \
435 SCOPED_INTERCEPTOR_RAW(mangled_name, ptr); \
436 user_free(thr, pc, ptr);
438 void operator delete(void *ptr
) {
439 OPERATOR_DELETE_BODY(_ZdlPv
);
441 void operator delete[](void *ptr
) {
442 OPERATOR_DELETE_BODY(_ZdlPvRKSt9nothrow_t
);
444 void operator delete(void *ptr
, std::nothrow_t
const&) {
445 OPERATOR_DELETE_BODY(_ZdaPv
);
447 void operator delete[](void *ptr
, std::nothrow_t
const&) {
448 OPERATOR_DELETE_BODY(_ZdaPvRKSt9nothrow_t
);
451 TSAN_INTERCEPTOR(uptr
, strlen
, const char *s
) {
452 SCOPED_TSAN_INTERCEPTOR(strlen
, s
);
453 uptr len
= internal_strlen(s
);
454 MemoryAccessRange(thr
, pc
, (uptr
)s
, len
+ 1, false);
458 TSAN_INTERCEPTOR(void*, memset
, void *dst
, int v
, uptr size
) {
459 SCOPED_TSAN_INTERCEPTOR(memset
, dst
, v
, size
);
460 MemoryAccessRange(thr
, pc
, (uptr
)dst
, size
, true);
461 return internal_memset(dst
, v
, size
);
464 TSAN_INTERCEPTOR(void*, memcpy
, void *dst
, const void *src
, uptr size
) {
465 SCOPED_TSAN_INTERCEPTOR(memcpy
, dst
, src
, size
);
466 MemoryAccessRange(thr
, pc
, (uptr
)dst
, size
, true);
467 MemoryAccessRange(thr
, pc
, (uptr
)src
, size
, false);
468 return internal_memcpy(dst
, src
, size
);
471 TSAN_INTERCEPTOR(int, memcmp
, const void *s1
, const void *s2
, uptr n
) {
472 SCOPED_TSAN_INTERCEPTOR(memcmp
, s1
, s2
, n
);
475 for (; len
< n
; len
++) {
476 if ((res
= ((unsigned char*)s1
)[len
] - ((unsigned char*)s2
)[len
]))
479 MemoryAccessRange(thr
, pc
, (uptr
)s1
, len
< n
? len
+ 1 : n
, false);
480 MemoryAccessRange(thr
, pc
, (uptr
)s2
, len
< n
? len
+ 1 : n
, false);
484 TSAN_INTERCEPTOR(int, strcmp
, const char *s1
, const char *s2
) {
485 SCOPED_TSAN_INTERCEPTOR(strcmp
, s1
, s2
);
487 for (; s1
[len
] && s2
[len
]; len
++) {
488 if (s1
[len
] != s2
[len
])
491 MemoryAccessRange(thr
, pc
, (uptr
)s1
, len
+ 1, false);
492 MemoryAccessRange(thr
, pc
, (uptr
)s2
, len
+ 1, false);
493 return s1
[len
] - s2
[len
];
496 TSAN_INTERCEPTOR(int, strncmp
, const char *s1
, const char *s2
, uptr n
) {
497 SCOPED_TSAN_INTERCEPTOR(strncmp
, s1
, s2
, n
);
499 for (; len
< n
&& s1
[len
] && s2
[len
]; len
++) {
500 if (s1
[len
] != s2
[len
])
503 MemoryAccessRange(thr
, pc
, (uptr
)s1
, len
< n
? len
+ 1 : n
, false);
504 MemoryAccessRange(thr
, pc
, (uptr
)s2
, len
< n
? len
+ 1 : n
, false);
505 return len
== n
? 0 : s1
[len
] - s2
[len
];
508 TSAN_INTERCEPTOR(void*, memchr
, void *s
, int c
, uptr n
) {
509 SCOPED_TSAN_INTERCEPTOR(memchr
, s
, c
, n
);
510 void *res
= REAL(memchr
)(s
, c
, n
);
511 uptr len
= res
? (char*)res
- (char*)s
+ 1 : n
;
512 MemoryAccessRange(thr
, pc
, (uptr
)s
, len
, false);
516 TSAN_INTERCEPTOR(void*, memrchr
, char *s
, int c
, uptr n
) {
517 SCOPED_TSAN_INTERCEPTOR(memrchr
, s
, c
, n
);
518 MemoryAccessRange(thr
, pc
, (uptr
)s
, n
, false);
519 return REAL(memrchr
)(s
, c
, n
);
522 TSAN_INTERCEPTOR(void*, memmove
, void *dst
, void *src
, uptr n
) {
523 SCOPED_TSAN_INTERCEPTOR(memmove
, dst
, src
, n
);
524 MemoryAccessRange(thr
, pc
, (uptr
)dst
, n
, true);
525 MemoryAccessRange(thr
, pc
, (uptr
)src
, n
, false);
526 return REAL(memmove
)(dst
, src
, n
);
529 TSAN_INTERCEPTOR(char*, strchr
, char *s
, int c
) {
530 SCOPED_TSAN_INTERCEPTOR(strchr
, s
, c
);
531 char *res
= REAL(strchr
)(s
, c
);
532 uptr len
= res
? (char*)res
- (char*)s
+ 1 : internal_strlen(s
) + 1;
533 MemoryAccessRange(thr
, pc
, (uptr
)s
, len
, false);
537 TSAN_INTERCEPTOR(char*, strchrnul
, char *s
, int c
) {
538 SCOPED_TSAN_INTERCEPTOR(strchrnul
, s
, c
);
539 char *res
= REAL(strchrnul
)(s
, c
);
540 uptr len
= (char*)res
- (char*)s
+ 1;
541 MemoryAccessRange(thr
, pc
, (uptr
)s
, len
, false);
545 TSAN_INTERCEPTOR(char*, strrchr
, char *s
, int c
) {
546 SCOPED_TSAN_INTERCEPTOR(strrchr
, s
, c
);
547 MemoryAccessRange(thr
, pc
, (uptr
)s
, internal_strlen(s
) + 1, false);
548 return REAL(strrchr
)(s
, c
);
551 TSAN_INTERCEPTOR(char*, strcpy
, char *dst
, const char *src
) { // NOLINT
552 SCOPED_TSAN_INTERCEPTOR(strcpy
, dst
, src
); // NOLINT
553 uptr srclen
= internal_strlen(src
);
554 MemoryAccessRange(thr
, pc
, (uptr
)dst
, srclen
+ 1, true);
555 MemoryAccessRange(thr
, pc
, (uptr
)src
, srclen
+ 1, false);
556 return REAL(strcpy
)(dst
, src
); // NOLINT
559 TSAN_INTERCEPTOR(char*, strncpy
, char *dst
, char *src
, uptr n
) {
560 SCOPED_TSAN_INTERCEPTOR(strncpy
, dst
, src
, n
);
561 uptr srclen
= internal_strnlen(src
, n
);
562 MemoryAccessRange(thr
, pc
, (uptr
)dst
, n
, true);
563 MemoryAccessRange(thr
, pc
, (uptr
)src
, min(srclen
+ 1, n
), false);
564 return REAL(strncpy
)(dst
, src
, n
);
567 TSAN_INTERCEPTOR(const char*, strstr
, const char *s1
, const char *s2
) {
568 SCOPED_TSAN_INTERCEPTOR(strstr
, s1
, s2
);
569 const char *res
= REAL(strstr
)(s1
, s2
);
570 uptr len1
= internal_strlen(s1
);
571 uptr len2
= internal_strlen(s2
);
572 MemoryAccessRange(thr
, pc
, (uptr
)s1
, len1
+ 1, false);
573 MemoryAccessRange(thr
, pc
, (uptr
)s2
, len2
+ 1, false);
577 static bool fix_mmap_addr(void **addr
, long_t sz
, int flags
) {
579 if (!IsAppMem((uptr
)*addr
) || !IsAppMem((uptr
)*addr
+ sz
- 1)) {
580 if (flags
& MAP_FIXED
) {
591 TSAN_INTERCEPTOR(void*, mmap
, void *addr
, long_t sz
, int prot
,
592 int flags
, int fd
, unsigned off
) {
593 SCOPED_TSAN_INTERCEPTOR(mmap
, addr
, sz
, prot
, flags
, fd
, off
);
594 if (!fix_mmap_addr(&addr
, sz
, flags
))
596 void *res
= REAL(mmap
)(addr
, sz
, prot
, flags
, fd
, off
);
597 if (res
!= MAP_FAILED
) {
598 MemoryResetRange(thr
, pc
, (uptr
)res
, sz
);
603 TSAN_INTERCEPTOR(void*, mmap64
, void *addr
, long_t sz
, int prot
,
604 int flags
, int fd
, u64 off
) {
605 SCOPED_TSAN_INTERCEPTOR(mmap64
, addr
, sz
, prot
, flags
, fd
, off
);
606 if (!fix_mmap_addr(&addr
, sz
, flags
))
608 void *res
= REAL(mmap64
)(addr
, sz
, prot
, flags
, fd
, off
);
609 if (res
!= MAP_FAILED
) {
610 MemoryResetRange(thr
, pc
, (uptr
)res
, sz
);
615 TSAN_INTERCEPTOR(int, munmap
, void *addr
, long_t sz
) {
616 SCOPED_TSAN_INTERCEPTOR(munmap
, addr
, sz
);
617 int res
= REAL(munmap
)(addr
, sz
);
621 TSAN_INTERCEPTOR(void*, memalign
, uptr align
, uptr sz
) {
622 SCOPED_TSAN_INTERCEPTOR(memalign
, align
, sz
);
623 return user_alloc(thr
, pc
, sz
, align
);
626 TSAN_INTERCEPTOR(void*, valloc
, uptr sz
) {
627 SCOPED_TSAN_INTERCEPTOR(valloc
, sz
);
628 return user_alloc(thr
, pc
, sz
, GetPageSizeCached());
631 TSAN_INTERCEPTOR(void*, pvalloc
, uptr sz
) {
632 SCOPED_TSAN_INTERCEPTOR(pvalloc
, sz
);
633 sz
= RoundUp(sz
, GetPageSizeCached());
634 return user_alloc(thr
, pc
, sz
, GetPageSizeCached());
637 TSAN_INTERCEPTOR(int, posix_memalign
, void **memptr
, uptr align
, uptr sz
) {
638 SCOPED_TSAN_INTERCEPTOR(posix_memalign
, memptr
, align
, sz
);
639 *memptr
= user_alloc(thr
, pc
, sz
, align
);
643 // Used in thread-safe function static initialization.
644 extern "C" int INTERFACE_ATTRIBUTE
__cxa_guard_acquire(atomic_uint32_t
*g
) {
645 SCOPED_INTERCEPTOR_RAW(__cxa_guard_acquire
, g
);
647 u32 cmp
= atomic_load(g
, memory_order_acquire
);
649 if (atomic_compare_exchange_strong(g
, &cmp
, 1<<16, memory_order_relaxed
))
651 } else if (cmp
== 1) {
652 Acquire(thr
, pc
, (uptr
)g
);
655 internal_sched_yield();
660 extern "C" void INTERFACE_ATTRIBUTE
__cxa_guard_release(atomic_uint32_t
*g
) {
661 SCOPED_INTERCEPTOR_RAW(__cxa_guard_release
, g
);
662 Release(thr
, pc
, (uptr
)g
);
663 atomic_store(g
, 1, memory_order_release
);
666 extern "C" void INTERFACE_ATTRIBUTE
__cxa_guard_abort(atomic_uint32_t
*g
) {
667 SCOPED_INTERCEPTOR_RAW(__cxa_guard_abort
, g
);
668 atomic_store(g
, 0, memory_order_relaxed
);
671 static void thread_finalize(void *v
) {
674 if (pthread_setspecific(g_thread_finalize_key
, (void*)(iter
- 1))) {
675 Printf("ThreadSanitizer: failed to set thread key\n");
682 ThreadState
*thr
= cur_thread();
684 SignalContext
*sctx
= thr
->signal_ctx
;
687 UnmapOrDie(sctx
, sizeof(*sctx
));
694 void* (*callback
)(void *arg
);
696 atomic_uintptr_t tid
;
699 extern "C" void *__tsan_thread_start_func(void *arg
) {
700 ThreadParam
*p
= (ThreadParam
*)arg
;
701 void* (*callback
)(void *arg
) = p
->callback
;
702 void *param
= p
->param
;
705 ThreadState
*thr
= cur_thread();
707 if (pthread_setspecific(g_thread_finalize_key
, (void*)4)) {
708 Printf("ThreadSanitizer: failed to set thread key\n");
711 while ((tid
= atomic_load(&p
->tid
, memory_order_acquire
)) == 0)
713 atomic_store(&p
->tid
, 0, memory_order_release
);
714 ThreadStart(thr
, tid
, GetTid());
715 CHECK_EQ(thr
->in_rtl
, 1);
717 void *res
= callback(param
);
718 // Prevent the callback from being tail called,
719 // it mixes up stack traces.
720 volatile int foo
= 42;
725 TSAN_INTERCEPTOR(int, pthread_create
,
726 void *th
, void *attr
, void *(*callback
)(void*), void * param
) {
727 SCOPED_TSAN_INTERCEPTOR(pthread_create
, th
, attr
, callback
, param
);
728 pthread_attr_t myattr
;
730 pthread_attr_init(&myattr
);
734 pthread_attr_getdetachstate(attr
, &detached
);
736 pthread_attr_getstacksize(attr
, &stacksize
);
737 // We place the huge ThreadState object into TLS, account for that.
738 const uptr minstacksize
= GetTlsSize() + 128*1024;
739 if (stacksize
< minstacksize
) {
740 DPrintf("ThreadSanitizer: stacksize %zu->%zu\n", stacksize
, minstacksize
);
741 pthread_attr_setstacksize(attr
, minstacksize
);
744 p
.callback
= callback
;
746 atomic_store(&p
.tid
, 0, memory_order_relaxed
);
747 int res
= REAL(pthread_create
)(th
, attr
, __tsan_thread_start_func
, &p
);
749 int tid
= ThreadCreate(thr
, pc
, *(uptr
*)th
, detached
);
751 atomic_store(&p
.tid
, tid
, memory_order_release
);
752 while (atomic_load(&p
.tid
, memory_order_acquire
) != 0)
756 pthread_attr_destroy(&myattr
);
760 TSAN_INTERCEPTOR(int, pthread_join
, void *th
, void **ret
) {
761 SCOPED_TSAN_INTERCEPTOR(pthread_join
, th
, ret
);
762 int tid
= ThreadTid(thr
, pc
, (uptr
)th
);
763 int res
= BLOCK_REAL(pthread_join
)(th
, ret
);
765 ThreadJoin(thr
, pc
, tid
);
770 TSAN_INTERCEPTOR(int, pthread_detach
, void *th
) {
771 SCOPED_TSAN_INTERCEPTOR(pthread_detach
, th
);
772 int tid
= ThreadTid(thr
, pc
, (uptr
)th
);
773 int res
= REAL(pthread_detach
)(th
);
775 ThreadDetach(thr
, pc
, tid
);
780 TSAN_INTERCEPTOR(int, pthread_mutex_init
, void *m
, void *a
) {
781 SCOPED_TSAN_INTERCEPTOR(pthread_mutex_init
, m
, a
);
782 int res
= REAL(pthread_mutex_init
)(m
, a
);
784 bool recursive
= false;
787 if (pthread_mutexattr_gettype(a
, &type
) == 0)
788 recursive
= (type
== PTHREAD_MUTEX_RECURSIVE
789 || type
== PTHREAD_MUTEX_RECURSIVE_NP
);
791 MutexCreate(thr
, pc
, (uptr
)m
, false, recursive
, false);
796 TSAN_INTERCEPTOR(int, pthread_mutex_destroy
, void *m
) {
797 SCOPED_TSAN_INTERCEPTOR(pthread_mutex_destroy
, m
);
798 int res
= REAL(pthread_mutex_destroy
)(m
);
799 if (res
== 0 || res
== EBUSY
) {
800 MutexDestroy(thr
, pc
, (uptr
)m
);
805 TSAN_INTERCEPTOR(int, pthread_mutex_lock
, void *m
) {
806 SCOPED_TSAN_INTERCEPTOR(pthread_mutex_lock
, m
);
807 int res
= REAL(pthread_mutex_lock
)(m
);
809 MutexLock(thr
, pc
, (uptr
)m
);
814 TSAN_INTERCEPTOR(int, pthread_mutex_trylock
, void *m
) {
815 SCOPED_TSAN_INTERCEPTOR(pthread_mutex_trylock
, m
);
816 int res
= REAL(pthread_mutex_trylock
)(m
);
818 MutexLock(thr
, pc
, (uptr
)m
);
823 TSAN_INTERCEPTOR(int, pthread_mutex_timedlock
, void *m
, void *abstime
) {
824 SCOPED_TSAN_INTERCEPTOR(pthread_mutex_timedlock
, m
, abstime
);
825 int res
= REAL(pthread_mutex_timedlock
)(m
, abstime
);
827 MutexLock(thr
, pc
, (uptr
)m
);
832 TSAN_INTERCEPTOR(int, pthread_mutex_unlock
, void *m
) {
833 SCOPED_TSAN_INTERCEPTOR(pthread_mutex_unlock
, m
);
834 MutexUnlock(thr
, pc
, (uptr
)m
);
835 int res
= REAL(pthread_mutex_unlock
)(m
);
839 TSAN_INTERCEPTOR(int, pthread_spin_init
, void *m
, int pshared
) {
840 SCOPED_TSAN_INTERCEPTOR(pthread_spin_init
, m
, pshared
);
841 int res
= REAL(pthread_spin_init
)(m
, pshared
);
843 MutexCreate(thr
, pc
, (uptr
)m
, false, false, false);
848 TSAN_INTERCEPTOR(int, pthread_spin_destroy
, void *m
) {
849 SCOPED_TSAN_INTERCEPTOR(pthread_spin_destroy
, m
);
850 int res
= REAL(pthread_spin_destroy
)(m
);
852 MutexDestroy(thr
, pc
, (uptr
)m
);
857 TSAN_INTERCEPTOR(int, pthread_spin_lock
, void *m
) {
858 SCOPED_TSAN_INTERCEPTOR(pthread_spin_lock
, m
);
859 int res
= REAL(pthread_spin_lock
)(m
);
861 MutexLock(thr
, pc
, (uptr
)m
);
866 TSAN_INTERCEPTOR(int, pthread_spin_trylock
, void *m
) {
867 SCOPED_TSAN_INTERCEPTOR(pthread_spin_trylock
, m
);
868 int res
= REAL(pthread_spin_trylock
)(m
);
870 MutexLock(thr
, pc
, (uptr
)m
);
875 TSAN_INTERCEPTOR(int, pthread_spin_unlock
, void *m
) {
876 SCOPED_TSAN_INTERCEPTOR(pthread_spin_unlock
, m
);
877 MutexUnlock(thr
, pc
, (uptr
)m
);
878 int res
= REAL(pthread_spin_unlock
)(m
);
882 TSAN_INTERCEPTOR(int, pthread_rwlock_init
, void *m
, void *a
) {
883 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_init
, m
, a
);
884 int res
= REAL(pthread_rwlock_init
)(m
, a
);
886 MutexCreate(thr
, pc
, (uptr
)m
, true, false, false);
891 TSAN_INTERCEPTOR(int, pthread_rwlock_destroy
, void *m
) {
892 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_destroy
, m
);
893 int res
= REAL(pthread_rwlock_destroy
)(m
);
895 MutexDestroy(thr
, pc
, (uptr
)m
);
900 TSAN_INTERCEPTOR(int, pthread_rwlock_rdlock
, void *m
) {
901 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_rdlock
, m
);
902 int res
= REAL(pthread_rwlock_rdlock
)(m
);
904 MutexReadLock(thr
, pc
, (uptr
)m
);
909 TSAN_INTERCEPTOR(int, pthread_rwlock_tryrdlock
, void *m
) {
910 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_tryrdlock
, m
);
911 int res
= REAL(pthread_rwlock_tryrdlock
)(m
);
913 MutexReadLock(thr
, pc
, (uptr
)m
);
918 TSAN_INTERCEPTOR(int, pthread_rwlock_timedrdlock
, void *m
, void *abstime
) {
919 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_timedrdlock
, m
, abstime
);
920 int res
= REAL(pthread_rwlock_timedrdlock
)(m
, abstime
);
922 MutexReadLock(thr
, pc
, (uptr
)m
);
927 TSAN_INTERCEPTOR(int, pthread_rwlock_wrlock
, void *m
) {
928 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_wrlock
, m
);
929 int res
= REAL(pthread_rwlock_wrlock
)(m
);
931 MutexLock(thr
, pc
, (uptr
)m
);
936 TSAN_INTERCEPTOR(int, pthread_rwlock_trywrlock
, void *m
) {
937 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_trywrlock
, m
);
938 int res
= REAL(pthread_rwlock_trywrlock
)(m
);
940 MutexLock(thr
, pc
, (uptr
)m
);
945 TSAN_INTERCEPTOR(int, pthread_rwlock_timedwrlock
, void *m
, void *abstime
) {
946 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_timedwrlock
, m
, abstime
);
947 int res
= REAL(pthread_rwlock_timedwrlock
)(m
, abstime
);
949 MutexLock(thr
, pc
, (uptr
)m
);
954 TSAN_INTERCEPTOR(int, pthread_rwlock_unlock
, void *m
) {
955 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_unlock
, m
);
956 MutexReadOrWriteUnlock(thr
, pc
, (uptr
)m
);
957 int res
= REAL(pthread_rwlock_unlock
)(m
);
961 // libpthread.so contains several versions of pthread_cond_init symbol.
962 // When we just dlsym() it, we get the wrong (old) version.
964 TSAN_INTERCEPTOR(int, pthread_cond_init, void *c, void *a) {
965 SCOPED_TSAN_INTERCEPTOR(pthread_cond_init, c, a);
966 int res = REAL(pthread_cond_init)(c, a);
971 TSAN_INTERCEPTOR(int, pthread_cond_destroy
, void *c
) {
972 SCOPED_TSAN_INTERCEPTOR(pthread_cond_destroy
, c
);
973 int res
= REAL(pthread_cond_destroy
)(c
);
977 TSAN_INTERCEPTOR(int, pthread_cond_signal
, void *c
) {
978 SCOPED_TSAN_INTERCEPTOR(pthread_cond_signal
, c
);
979 int res
= REAL(pthread_cond_signal
)(c
);
983 TSAN_INTERCEPTOR(int, pthread_cond_broadcast
, void *c
) {
984 SCOPED_TSAN_INTERCEPTOR(pthread_cond_broadcast
, c
);
985 int res
= REAL(pthread_cond_broadcast
)(c
);
989 TSAN_INTERCEPTOR(int, pthread_cond_wait
, void *c
, void *m
) {
990 SCOPED_TSAN_INTERCEPTOR(pthread_cond_wait
, c
, m
);
991 MutexUnlock(thr
, pc
, (uptr
)m
);
992 int res
= REAL(pthread_cond_wait
)(c
, m
);
993 MutexLock(thr
, pc
, (uptr
)m
);
997 TSAN_INTERCEPTOR(int, pthread_cond_timedwait
, void *c
, void *m
, void *abstime
) {
998 SCOPED_TSAN_INTERCEPTOR(pthread_cond_timedwait
, c
, m
, abstime
);
999 MutexUnlock(thr
, pc
, (uptr
)m
);
1000 int res
= REAL(pthread_cond_timedwait
)(c
, m
, abstime
);
1001 MutexLock(thr
, pc
, (uptr
)m
);
1005 TSAN_INTERCEPTOR(int, pthread_barrier_init
, void *b
, void *a
, unsigned count
) {
1006 SCOPED_TSAN_INTERCEPTOR(pthread_barrier_init
, b
, a
, count
);
1007 MemoryWrite(thr
, pc
, (uptr
)b
, kSizeLog1
);
1008 int res
= REAL(pthread_barrier_init
)(b
, a
, count
);
1012 TSAN_INTERCEPTOR(int, pthread_barrier_destroy
, void *b
) {
1013 SCOPED_TSAN_INTERCEPTOR(pthread_barrier_destroy
, b
);
1014 MemoryWrite(thr
, pc
, (uptr
)b
, kSizeLog1
);
1015 int res
= REAL(pthread_barrier_destroy
)(b
);
1019 TSAN_INTERCEPTOR(int, pthread_barrier_wait
, void *b
) {
1020 SCOPED_TSAN_INTERCEPTOR(pthread_barrier_wait
, b
);
1021 Release(thr
, pc
, (uptr
)b
);
1022 MemoryRead(thr
, pc
, (uptr
)b
, kSizeLog1
);
1023 int res
= REAL(pthread_barrier_wait
)(b
);
1024 MemoryRead(thr
, pc
, (uptr
)b
, kSizeLog1
);
1025 if (res
== 0 || res
== PTHREAD_BARRIER_SERIAL_THREAD
) {
1026 Acquire(thr
, pc
, (uptr
)b
);
1031 TSAN_INTERCEPTOR(int, pthread_once
, void *o
, void (*f
)()) {
1032 SCOPED_TSAN_INTERCEPTOR(pthread_once
, o
, f
);
1033 if (o
== 0 || f
== 0)
1035 atomic_uint32_t
*a
= static_cast<atomic_uint32_t
*>(o
);
1036 u32 v
= atomic_load(a
, memory_order_acquire
);
1037 if (v
== 0 && atomic_compare_exchange_strong(a
, &v
, 1,
1038 memory_order_relaxed
)) {
1039 const int old_in_rtl
= thr
->in_rtl
;
1042 CHECK_EQ(thr
->in_rtl
, 0);
1043 thr
->in_rtl
= old_in_rtl
;
1044 Release(thr
, pc
, (uptr
)o
);
1045 atomic_store(a
, 2, memory_order_release
);
1049 v
= atomic_load(a
, memory_order_acquire
);
1051 Acquire(thr
, pc
, (uptr
)o
);
1056 TSAN_INTERCEPTOR(int, sem_init
, void *s
, int pshared
, unsigned value
) {
1057 SCOPED_TSAN_INTERCEPTOR(sem_init
, s
, pshared
, value
);
1058 int res
= REAL(sem_init
)(s
, pshared
, value
);
1062 TSAN_INTERCEPTOR(int, sem_destroy
, void *s
) {
1063 SCOPED_TSAN_INTERCEPTOR(sem_destroy
, s
);
1064 int res
= REAL(sem_destroy
)(s
);
1068 TSAN_INTERCEPTOR(int, sem_wait
, void *s
) {
1069 SCOPED_TSAN_INTERCEPTOR(sem_wait
, s
);
1070 int res
= BLOCK_REAL(sem_wait
)(s
);
1072 Acquire(thr
, pc
, (uptr
)s
);
1077 TSAN_INTERCEPTOR(int, sem_trywait
, void *s
) {
1078 SCOPED_TSAN_INTERCEPTOR(sem_trywait
, s
);
1079 int res
= BLOCK_REAL(sem_trywait
)(s
);
1081 Acquire(thr
, pc
, (uptr
)s
);
1086 TSAN_INTERCEPTOR(int, sem_timedwait
, void *s
, void *abstime
) {
1087 SCOPED_TSAN_INTERCEPTOR(sem_timedwait
, s
, abstime
);
1088 int res
= BLOCK_REAL(sem_timedwait
)(s
, abstime
);
1090 Acquire(thr
, pc
, (uptr
)s
);
1095 TSAN_INTERCEPTOR(int, sem_post
, void *s
) {
1096 SCOPED_TSAN_INTERCEPTOR(sem_post
, s
);
1097 Release(thr
, pc
, (uptr
)s
);
1098 int res
= REAL(sem_post
)(s
);
1102 TSAN_INTERCEPTOR(int, sem_getvalue
, void *s
, int *sval
) {
1103 SCOPED_TSAN_INTERCEPTOR(sem_getvalue
, s
, sval
);
1104 int res
= REAL(sem_getvalue
)(s
, sval
);
1106 Acquire(thr
, pc
, (uptr
)s
);
1111 TSAN_INTERCEPTOR(int, __xstat
, int version
, const char *path
, void *buf
) {
1112 SCOPED_TSAN_INTERCEPTOR(__xstat
, version
, path
, buf
);
1113 return REAL(__xstat
)(version
, path
, buf
);
1116 TSAN_INTERCEPTOR(int, stat
, const char *path
, void *buf
) {
1117 SCOPED_TSAN_INTERCEPTOR(__xstat
, 0, path
, buf
);
1118 return REAL(__xstat
)(0, path
, buf
);
1121 TSAN_INTERCEPTOR(int, __xstat64
, int version
, const char *path
, void *buf
) {
1122 SCOPED_TSAN_INTERCEPTOR(__xstat64
, version
, path
, buf
);
1123 return REAL(__xstat64
)(version
, path
, buf
);
1126 TSAN_INTERCEPTOR(int, stat64
, const char *path
, void *buf
) {
1127 SCOPED_TSAN_INTERCEPTOR(__xstat64
, 0, path
, buf
);
1128 return REAL(__xstat64
)(0, path
, buf
);
1131 TSAN_INTERCEPTOR(int, __lxstat
, int version
, const char *path
, void *buf
) {
1132 SCOPED_TSAN_INTERCEPTOR(__lxstat
, version
, path
, buf
);
1133 return REAL(__lxstat
)(version
, path
, buf
);
1136 TSAN_INTERCEPTOR(int, lstat
, const char *path
, void *buf
) {
1137 SCOPED_TSAN_INTERCEPTOR(__lxstat
, 0, path
, buf
);
1138 return REAL(__lxstat
)(0, path
, buf
);
1141 TSAN_INTERCEPTOR(int, __lxstat64
, int version
, const char *path
, void *buf
) {
1142 SCOPED_TSAN_INTERCEPTOR(__lxstat64
, version
, path
, buf
);
1143 return REAL(__lxstat64
)(version
, path
, buf
);
1146 TSAN_INTERCEPTOR(int, lstat64
, const char *path
, void *buf
) {
1147 SCOPED_TSAN_INTERCEPTOR(__lxstat64
, 0, path
, buf
);
1148 return REAL(__lxstat64
)(0, path
, buf
);
1151 TSAN_INTERCEPTOR(int, __fxstat
, int version
, int fd
, void *buf
) {
1152 SCOPED_TSAN_INTERCEPTOR(__fxstat
, version
, fd
, buf
);
1153 return REAL(__fxstat
)(version
, fd
, buf
);
1156 TSAN_INTERCEPTOR(int, fstat
, int fd
, void *buf
) {
1157 SCOPED_TSAN_INTERCEPTOR(__fxstat
, 0, fd
, buf
);
1158 return REAL(__fxstat
)(0, fd
, buf
);
1161 TSAN_INTERCEPTOR(int, __fxstat64
, int version
, int fd
, void *buf
) {
1162 SCOPED_TSAN_INTERCEPTOR(__fxstat64
, version
, fd
, buf
);
1163 return REAL(__fxstat64
)(version
, fd
, buf
);
1166 TSAN_INTERCEPTOR(int, fstat64
, int fd
, void *buf
) {
1167 SCOPED_TSAN_INTERCEPTOR(__fxstat64
, 0, fd
, buf
);
1168 return REAL(__fxstat64
)(0, fd
, buf
);
1171 TSAN_INTERCEPTOR(int, open
, const char *name
, int flags
, int mode
) {
1172 SCOPED_TSAN_INTERCEPTOR(open
, name
, flags
, mode
);
1173 int fd
= REAL(open
)(name
, flags
, mode
);
1175 FdFileCreate(thr
, pc
, fd
);
1179 TSAN_INTERCEPTOR(int, open64
, const char *name
, int flags
, int mode
) {
1180 SCOPED_TSAN_INTERCEPTOR(open64
, name
, flags
, mode
);
1181 int fd
= REAL(open64
)(name
, flags
, mode
);
1183 FdFileCreate(thr
, pc
, fd
);
1187 TSAN_INTERCEPTOR(int, creat
, const char *name
, int mode
) {
1188 SCOPED_TSAN_INTERCEPTOR(creat
, name
, mode
);
1189 int fd
= REAL(creat
)(name
, mode
);
1191 FdFileCreate(thr
, pc
, fd
);
1195 TSAN_INTERCEPTOR(int, creat64
, const char *name
, int mode
) {
1196 SCOPED_TSAN_INTERCEPTOR(creat64
, name
, mode
);
1197 int fd
= REAL(creat64
)(name
, mode
);
1199 FdFileCreate(thr
, pc
, fd
);
1203 TSAN_INTERCEPTOR(int, dup
, int oldfd
) {
1204 SCOPED_TSAN_INTERCEPTOR(dup
, oldfd
);
1205 int newfd
= REAL(dup
)(oldfd
);
1206 if (oldfd
>= 0 && newfd
>= 0 && newfd
!= oldfd
)
1207 FdDup(thr
, pc
, oldfd
, newfd
);
1211 TSAN_INTERCEPTOR(int, dup2
, int oldfd
, int newfd
) {
1212 SCOPED_TSAN_INTERCEPTOR(dup2
, oldfd
, newfd
);
1213 int newfd2
= REAL(dup2
)(oldfd
, newfd
);
1214 if (oldfd
>= 0 && newfd2
>= 0 && newfd2
!= oldfd
)
1215 FdDup(thr
, pc
, oldfd
, newfd2
);
1219 TSAN_INTERCEPTOR(int, dup3
, int oldfd
, int newfd
, int flags
) {
1220 SCOPED_TSAN_INTERCEPTOR(dup3
, oldfd
, newfd
, flags
);
1221 int newfd2
= REAL(dup3
)(oldfd
, newfd
, flags
);
1222 if (oldfd
>= 0 && newfd2
>= 0 && newfd2
!= oldfd
)
1223 FdDup(thr
, pc
, oldfd
, newfd2
);
1227 TSAN_INTERCEPTOR(int, eventfd
, unsigned initval
, int flags
) {
1228 SCOPED_TSAN_INTERCEPTOR(eventfd
, initval
, flags
);
1229 int fd
= REAL(eventfd
)(initval
, flags
);
1231 FdEventCreate(thr
, pc
, fd
);
1235 TSAN_INTERCEPTOR(int, signalfd
, int fd
, void *mask
, int flags
) {
1236 SCOPED_TSAN_INTERCEPTOR(signalfd
, fd
, mask
, flags
);
1238 FdClose(thr
, pc
, fd
);
1239 fd
= REAL(signalfd
)(fd
, mask
, flags
);
1241 FdSignalCreate(thr
, pc
, fd
);
1245 TSAN_INTERCEPTOR(int, inotify_init
, int fake
) {
1246 SCOPED_TSAN_INTERCEPTOR(inotify_init
, fake
);
1247 int fd
= REAL(inotify_init
)(fake
);
1249 FdInotifyCreate(thr
, pc
, fd
);
1253 TSAN_INTERCEPTOR(int, inotify_init1
, int flags
) {
1254 SCOPED_TSAN_INTERCEPTOR(inotify_init1
, flags
);
1255 int fd
= REAL(inotify_init1
)(flags
);
1257 FdInotifyCreate(thr
, pc
, fd
);
1261 TSAN_INTERCEPTOR(int, socket
, int domain
, int type
, int protocol
) {
1262 SCOPED_TSAN_INTERCEPTOR(socket
, domain
, type
, protocol
);
1263 int fd
= REAL(socket
)(domain
, type
, protocol
);
1265 FdSocketCreate(thr
, pc
, fd
);
1269 TSAN_INTERCEPTOR(int, socketpair
, int domain
, int type
, int protocol
, int *fd
) {
1270 SCOPED_TSAN_INTERCEPTOR(socketpair
, domain
, type
, protocol
, fd
);
1271 int res
= REAL(socketpair
)(domain
, type
, protocol
, fd
);
1272 if (res
== 0 && fd
[0] >= 0 && fd
[1] >= 0)
1273 FdPipeCreate(thr
, pc
, fd
[0], fd
[1]);
1277 TSAN_INTERCEPTOR(int, connect
, int fd
, void *addr
, unsigned addrlen
) {
1278 SCOPED_TSAN_INTERCEPTOR(connect
, fd
, addr
, addrlen
);
1279 FdSocketConnecting(thr
, pc
, fd
);
1280 int res
= REAL(connect
)(fd
, addr
, addrlen
);
1281 if (res
== 0 && fd
>= 0)
1282 FdSocketConnect(thr
, pc
, fd
);
1286 TSAN_INTERCEPTOR(int, accept
, int fd
, void *addr
, unsigned *addrlen
) {
1287 SCOPED_TSAN_INTERCEPTOR(accept
, fd
, addr
, addrlen
);
1288 int fd2
= REAL(accept
)(fd
, addr
, addrlen
);
1289 if (fd
>= 0 && fd2
>= 0)
1290 FdSocketAccept(thr
, pc
, fd
, fd2
);
1294 TSAN_INTERCEPTOR(int, accept4
, int fd
, void *addr
, unsigned *addrlen
, int f
) {
1295 SCOPED_TSAN_INTERCEPTOR(accept4
, fd
, addr
, addrlen
, f
);
1296 int fd2
= REAL(accept4
)(fd
, addr
, addrlen
, f
);
1297 if (fd
>= 0 && fd2
>= 0)
1298 FdSocketAccept(thr
, pc
, fd
, fd2
);
1302 TSAN_INTERCEPTOR(int, epoll_create
, int size
) {
1303 SCOPED_TSAN_INTERCEPTOR(epoll_create
, size
);
1304 int fd
= REAL(epoll_create
)(size
);
1306 FdPollCreate(thr
, pc
, fd
);
1310 TSAN_INTERCEPTOR(int, epoll_create1
, int flags
) {
1311 SCOPED_TSAN_INTERCEPTOR(epoll_create1
, flags
);
1312 int fd
= REAL(epoll_create1
)(flags
);
1314 FdPollCreate(thr
, pc
, fd
);
1318 TSAN_INTERCEPTOR(int, close
, int fd
) {
1319 SCOPED_TSAN_INTERCEPTOR(close
, fd
);
1321 FdClose(thr
, pc
, fd
);
1322 return REAL(close
)(fd
);
1325 TSAN_INTERCEPTOR(int, __close
, int fd
) {
1326 SCOPED_TSAN_INTERCEPTOR(__close
, fd
);
1328 FdClose(thr
, pc
, fd
);
1329 return REAL(__close
)(fd
);
1332 TSAN_INTERCEPTOR(int, pipe
, int *pipefd
) {
1333 SCOPED_TSAN_INTERCEPTOR(pipe
, pipefd
);
1334 int res
= REAL(pipe
)(pipefd
);
1335 if (res
== 0 && pipefd
[0] >= 0 && pipefd
[1] >= 0)
1336 FdPipeCreate(thr
, pc
, pipefd
[0], pipefd
[1]);
1340 TSAN_INTERCEPTOR(int, pipe2
, int *pipefd
, int flags
) {
1341 SCOPED_TSAN_INTERCEPTOR(pipe2
, pipefd
, flags
);
1342 int res
= REAL(pipe2
)(pipefd
, flags
);
1343 if (res
== 0 && pipefd
[0] >= 0 && pipefd
[1] >= 0)
1344 FdPipeCreate(thr
, pc
, pipefd
[0], pipefd
[1]);
1348 TSAN_INTERCEPTOR(long_t
, readv
, int fd
, void *vec
, int cnt
) {
1349 SCOPED_TSAN_INTERCEPTOR(readv
, fd
, vec
, cnt
);
1350 int res
= REAL(readv
)(fd
, vec
, cnt
);
1351 if (res
>= 0 && fd
>= 0) {
1352 FdAcquire(thr
, pc
, fd
);
1357 TSAN_INTERCEPTOR(long_t
, preadv64
, int fd
, void *vec
, int cnt
, u64 off
) {
1358 SCOPED_TSAN_INTERCEPTOR(preadv64
, fd
, vec
, cnt
, off
);
1359 int res
= REAL(preadv64
)(fd
, vec
, cnt
, off
);
1360 if (res
>= 0 && fd
>= 0) {
1361 FdAcquire(thr
, pc
, fd
);
1366 TSAN_INTERCEPTOR(long_t
, writev
, int fd
, void *vec
, int cnt
) {
1367 SCOPED_TSAN_INTERCEPTOR(writev
, fd
, vec
, cnt
);
1369 FdRelease(thr
, pc
, fd
);
1370 int res
= REAL(writev
)(fd
, vec
, cnt
);
1374 TSAN_INTERCEPTOR(long_t
, pwritev64
, int fd
, void *vec
, int cnt
, u64 off
) {
1375 SCOPED_TSAN_INTERCEPTOR(pwritev64
, fd
, vec
, cnt
, off
);
1377 FdRelease(thr
, pc
, fd
);
1378 int res
= REAL(pwritev64
)(fd
, vec
, cnt
, off
);
1382 TSAN_INTERCEPTOR(long_t
, send
, int fd
, void *buf
, long_t len
, int flags
) {
1383 SCOPED_TSAN_INTERCEPTOR(send
, fd
, buf
, len
, flags
);
1385 FdRelease(thr
, pc
, fd
);
1386 int res
= REAL(send
)(fd
, buf
, len
, flags
);
1390 TSAN_INTERCEPTOR(long_t
, sendmsg
, int fd
, void *msg
, int flags
) {
1391 SCOPED_TSAN_INTERCEPTOR(sendmsg
, fd
, msg
, flags
);
1393 FdRelease(thr
, pc
, fd
);
1394 int res
= REAL(sendmsg
)(fd
, msg
, flags
);
1398 TSAN_INTERCEPTOR(long_t
, recv
, int fd
, void *buf
, long_t len
, int flags
) {
1399 SCOPED_TSAN_INTERCEPTOR(recv
, fd
, buf
, len
, flags
);
1400 int res
= REAL(recv
)(fd
, buf
, len
, flags
);
1401 if (res
>= 0 && fd
>= 0) {
1402 FdAcquire(thr
, pc
, fd
);
1407 TSAN_INTERCEPTOR(long_t
, recvmsg
, int fd
, void *msg
, int flags
) {
1408 SCOPED_TSAN_INTERCEPTOR(recvmsg
, fd
, msg
, flags
);
1409 int res
= REAL(recvmsg
)(fd
, msg
, flags
);
1410 if (res
>= 0 && fd
>= 0) {
1411 FdAcquire(thr
, pc
, fd
);
1416 TSAN_INTERCEPTOR(int, unlink
, char *path
) {
1417 SCOPED_TSAN_INTERCEPTOR(unlink
, path
);
1418 Release(thr
, pc
, File2addr(path
));
1419 int res
= REAL(unlink
)(path
);
1423 TSAN_INTERCEPTOR(void*, fopen
, char *path
, char *mode
) {
1424 SCOPED_TSAN_INTERCEPTOR(fopen
, path
, mode
);
1425 void *res
= REAL(fopen
)(path
, mode
);
1426 Acquire(thr
, pc
, File2addr(path
));
1428 int fd
= fileno_unlocked(res
);
1430 FdFileCreate(thr
, pc
, fd
);
1435 TSAN_INTERCEPTOR(void*, freopen
, char *path
, char *mode
, void *stream
) {
1436 SCOPED_TSAN_INTERCEPTOR(freopen
, path
, mode
, stream
);
1438 int fd
= fileno_unlocked(stream
);
1440 FdClose(thr
, pc
, fd
);
1442 void *res
= REAL(freopen
)(path
, mode
, stream
);
1443 Acquire(thr
, pc
, File2addr(path
));
1445 int fd
= fileno_unlocked(res
);
1447 FdFileCreate(thr
, pc
, fd
);
1452 TSAN_INTERCEPTOR(int, fclose
, void *stream
) {
1454 SCOPED_TSAN_INTERCEPTOR(fclose
, stream
);
1456 int fd
= fileno_unlocked(stream
);
1458 FdClose(thr
, pc
, fd
);
1461 return REAL(fclose
)(stream
);
1464 TSAN_INTERCEPTOR(uptr
, fread
, void *ptr
, uptr size
, uptr nmemb
, void *f
) {
1466 SCOPED_TSAN_INTERCEPTOR(fread
, ptr
, size
, nmemb
, f
);
1467 MemoryAccessRange(thr
, pc
, (uptr
)ptr
, size
* nmemb
, true);
1469 return REAL(fread
)(ptr
, size
, nmemb
, f
);
1472 TSAN_INTERCEPTOR(uptr
, fwrite
, const void *p
, uptr size
, uptr nmemb
, void *f
) {
1474 SCOPED_TSAN_INTERCEPTOR(fwrite
, p
, size
, nmemb
, f
);
1475 MemoryAccessRange(thr
, pc
, (uptr
)p
, size
* nmemb
, false);
1477 return REAL(fwrite
)(p
, size
, nmemb
, f
);
1480 TSAN_INTERCEPTOR(int, puts
, const char *s
) {
1481 SCOPED_TSAN_INTERCEPTOR(puts
, s
);
1482 MemoryAccessRange(thr
, pc
, (uptr
)s
, internal_strlen(s
), false);
1483 return REAL(puts
)(s
);
1486 TSAN_INTERCEPTOR(int, rmdir
, char *path
) {
1487 SCOPED_TSAN_INTERCEPTOR(rmdir
, path
);
1488 Release(thr
, pc
, Dir2addr(path
));
1489 int res
= REAL(rmdir
)(path
);
1493 TSAN_INTERCEPTOR(void*, opendir
, char *path
) {
1494 SCOPED_TSAN_INTERCEPTOR(opendir
, path
);
1495 void *res
= REAL(opendir
)(path
);
1497 Acquire(thr
, pc
, Dir2addr(path
));
1501 TSAN_INTERCEPTOR(int, epoll_ctl
, int epfd
, int op
, int fd
, void *ev
) {
1502 SCOPED_TSAN_INTERCEPTOR(epoll_ctl
, epfd
, op
, fd
, ev
);
1503 if (op
== EPOLL_CTL_ADD
&& epfd
>= 0) {
1504 FdRelease(thr
, pc
, epfd
);
1506 int res
= REAL(epoll_ctl
)(epfd
, op
, fd
, ev
);
1508 FdAccess(thr
, pc
, fd
);
1512 TSAN_INTERCEPTOR(int, epoll_wait
, int epfd
, void *ev
, int cnt
, int timeout
) {
1513 SCOPED_TSAN_INTERCEPTOR(epoll_wait
, epfd
, ev
, cnt
, timeout
);
1514 int res
= BLOCK_REAL(epoll_wait
)(epfd
, ev
, cnt
, timeout
);
1515 if (res
> 0 && epfd
>= 0) {
1516 FdAcquire(thr
, pc
, epfd
);
1521 TSAN_INTERCEPTOR(int, poll
, void *fds
, long_t nfds
, int timeout
) {
1522 SCOPED_TSAN_INTERCEPTOR(poll
, fds
, nfds
, timeout
);
1523 int res
= BLOCK_REAL(poll
)(fds
, nfds
, timeout
);
1527 static void ALWAYS_INLINE
rtl_generic_sighandler(bool sigact
, int sig
,
1528 my_siginfo_t
*info
, void *ctx
) {
1529 ThreadState
*thr
= cur_thread();
1530 SignalContext
*sctx
= SigCtx(thr
);
1531 // Don't mess with synchronous signals.
1532 if (sig
== SIGSEGV
|| sig
== SIGBUS
|| sig
== SIGILL
||
1533 sig
== SIGABRT
|| sig
== SIGFPE
|| sig
== SIGPIPE
||
1534 // If we are sending signal to ourselves, we must process it now.
1535 (sctx
&& sig
== sctx
->int_signal_send
) ||
1536 // If we are in blocking function, we can safely process it now
1537 // (but check if we are in a recursive interceptor,
1538 // i.e. pthread_join()->munmap()).
1539 (sctx
&& sctx
->in_blocking_func
== 1 && thr
->in_rtl
== 1)) {
1540 CHECK(thr
->in_rtl
== 0 || thr
->in_rtl
== 1);
1541 int in_rtl
= thr
->in_rtl
;
1543 CHECK_EQ(thr
->in_signal_handler
, false);
1544 thr
->in_signal_handler
= true;
1546 sigactions
[sig
].sa_sigaction(sig
, info
, ctx
);
1548 sigactions
[sig
].sa_handler(sig
);
1549 CHECK_EQ(thr
->in_signal_handler
, true);
1550 thr
->in_signal_handler
= false;
1551 thr
->in_rtl
= in_rtl
;
1557 SignalDesc
*signal
= &sctx
->pending_signals
[sig
];
1558 if (signal
->armed
== false) {
1559 signal
->armed
= true;
1560 signal
->sigaction
= sigact
;
1562 internal_memcpy(&signal
->siginfo
, info
, sizeof(*info
));
1564 internal_memcpy(&signal
->ctx
, ctx
, sizeof(signal
->ctx
));
1565 sctx
->pending_signal_count
++;
1569 static void rtl_sighandler(int sig
) {
1570 rtl_generic_sighandler(false, sig
, 0, 0);
1573 static void rtl_sigaction(int sig
, my_siginfo_t
*info
, void *ctx
) {
1574 rtl_generic_sighandler(true, sig
, info
, ctx
);
1577 TSAN_INTERCEPTOR(int, sigaction
, int sig
, sigaction_t
*act
, sigaction_t
*old
) {
1578 SCOPED_TSAN_INTERCEPTOR(sigaction
, sig
, act
, old
);
1580 internal_memcpy(old
, &sigactions
[sig
], sizeof(*old
));
1583 internal_memcpy(&sigactions
[sig
], act
, sizeof(*act
));
1585 internal_memcpy(&newact
, act
, sizeof(newact
));
1586 sigfillset(&newact
.sa_mask
);
1587 if (act
->sa_handler
!= SIG_IGN
&& act
->sa_handler
!= SIG_DFL
) {
1588 if (newact
.sa_flags
& SA_SIGINFO
)
1589 newact
.sa_sigaction
= rtl_sigaction
;
1591 newact
.sa_handler
= rtl_sighandler
;
1593 int res
= REAL(sigaction
)(sig
, &newact
, 0);
1597 TSAN_INTERCEPTOR(sighandler_t
, signal
, int sig
, sighandler_t h
) {
1600 REAL(memset
)(&act
.sa_mask
, -1, sizeof(act
.sa_mask
));
1603 int res
= sigaction(sig
, &act
, &old
);
1606 return old
.sa_handler
;
1609 TSAN_INTERCEPTOR(int, raise
, int sig
) {
1610 SCOPED_TSAN_INTERCEPTOR(raise
, sig
);
1611 SignalContext
*sctx
= SigCtx(thr
);
1613 int prev
= sctx
->int_signal_send
;
1614 sctx
->int_signal_send
= sig
;
1615 int res
= REAL(raise
)(sig
);
1616 CHECK_EQ(sctx
->int_signal_send
, sig
);
1617 sctx
->int_signal_send
= prev
;
1621 TSAN_INTERCEPTOR(int, kill
, int pid
, int sig
) {
1622 SCOPED_TSAN_INTERCEPTOR(kill
, pid
, sig
);
1623 SignalContext
*sctx
= SigCtx(thr
);
1625 int prev
= sctx
->int_signal_send
;
1626 if (pid
== GetPid()) {
1627 sctx
->int_signal_send
= sig
;
1629 int res
= REAL(kill
)(pid
, sig
);
1630 if (pid
== GetPid()) {
1631 CHECK_EQ(sctx
->int_signal_send
, sig
);
1632 sctx
->int_signal_send
= prev
;
1637 TSAN_INTERCEPTOR(int, pthread_kill
, void *tid
, int sig
) {
1638 SCOPED_TSAN_INTERCEPTOR(pthread_kill
, tid
, sig
);
1639 SignalContext
*sctx
= SigCtx(thr
);
1641 int prev
= sctx
->int_signal_send
;
1642 if (tid
== pthread_self()) {
1643 sctx
->int_signal_send
= sig
;
1645 int res
= REAL(pthread_kill
)(tid
, sig
);
1646 if (tid
== pthread_self()) {
1647 CHECK_EQ(sctx
->int_signal_send
, sig
);
1648 sctx
->int_signal_send
= prev
;
1653 TSAN_INTERCEPTOR(int, gettimeofday
, void *tv
, void *tz
) {
1654 SCOPED_TSAN_INTERCEPTOR(gettimeofday
, tv
, tz
);
1655 // It's intercepted merely to process pending signals.
1656 return REAL(gettimeofday
)(tv
, tz
);
1659 // Linux kernel has a bug that leads to kernel deadlock if a process
1660 // maps TBs of memory and then calls mlock().
1661 static void MlockIsUnsupported() {
1662 static atomic_uint8_t printed
;
1663 if (atomic_exchange(&printed
, 1, memory_order_relaxed
))
1665 Printf("INFO: ThreadSanitizer ignores mlock/mlockall/munlock/munlockall\n");
1668 TSAN_INTERCEPTOR(int, mlock
, const void *addr
, uptr len
) {
1669 MlockIsUnsupported();
1673 TSAN_INTERCEPTOR(int, munlock
, const void *addr
, uptr len
) {
1674 MlockIsUnsupported();
1678 TSAN_INTERCEPTOR(int, mlockall
, int flags
) {
1679 MlockIsUnsupported();
1683 TSAN_INTERCEPTOR(int, munlockall
, void) {
1684 MlockIsUnsupported();
1688 TSAN_INTERCEPTOR(int, fork
, int fake
) {
1689 SCOPED_TSAN_INTERCEPTOR(fork
, fake
);
1690 // It's intercepted merely to process pending signals.
1691 int pid
= REAL(fork
)(fake
);
1695 } else if (pid
> 0) {
1701 struct TsanInterceptorContext
{
1703 const uptr caller_pc
;
1707 #define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
1708 MemoryAccessRange(((TsanInterceptorContext*)ctx)->thr, \
1709 ((TsanInterceptorContext*)ctx)->pc, \
1710 (uptr)ptr, size, true)
1711 #define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \
1712 MemoryAccessRange(((TsanInterceptorContext*)ctx)->thr, \
1713 ((TsanInterceptorContext*)ctx)->pc, \
1714 (uptr)ptr, size, false)
1715 #define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \
1716 SCOPED_TSAN_INTERCEPTOR(func, __VA_ARGS__) \
1717 TsanInterceptorContext _ctx = {thr, caller_pc, pc}; \
1718 ctx = (void*)&_ctx; \
1720 #define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \
1721 FdAcquire(((TsanInterceptorContext*)ctx)->thr, pc, fd)
1722 #define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \
1723 FdRelease(((TsanInterceptorContext*)ctx)->thr, pc, fd)
1724 #define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) \
1725 ThreadSetName(((TsanInterceptorContext*)ctx)->thr, name)
1726 #include "sanitizer_common/sanitizer_common_interceptors.inc"
1730 void ProcessPendingSignals(ThreadState
*thr
) {
1731 CHECK_EQ(thr
->in_rtl
, 0);
1732 SignalContext
*sctx
= SigCtx(thr
);
1733 if (sctx
== 0 || sctx
->pending_signal_count
== 0 || thr
->in_signal_handler
)
1735 Context
*ctx
= CTX();
1736 thr
->in_signal_handler
= true;
1737 sctx
->pending_signal_count
= 0;
1738 // These are too big for stack.
1739 static THREADLOCAL sigset_t emptyset
, oldset
;
1740 sigfillset(&emptyset
);
1741 pthread_sigmask(SIG_SETMASK
, &emptyset
, &oldset
);
1742 for (int sig
= 0; sig
< kSigCount
; sig
++) {
1743 SignalDesc
*signal
= &sctx
->pending_signals
[sig
];
1744 if (signal
->armed
) {
1745 signal
->armed
= false;
1746 if (sigactions
[sig
].sa_handler
!= SIG_DFL
1747 && sigactions
[sig
].sa_handler
!= SIG_IGN
) {
1748 // Insure that the handler does not spoil errno.
1749 const int saved_errno
= errno
;
1751 if (signal
->sigaction
)
1752 sigactions
[sig
].sa_sigaction(sig
, &signal
->siginfo
, &signal
->ctx
);
1754 sigactions
[sig
].sa_handler(sig
);
1755 if (flags()->report_bugs
&& errno
!= 0) {
1757 __tsan::StackTrace stack
;
1758 uptr pc
= signal
->sigaction
?
1759 (uptr
)sigactions
[sig
].sa_sigaction
:
1760 (uptr
)sigactions
[sig
].sa_handler
;
1762 Lock
l(&ctx
->thread_mtx
);
1763 ScopedReport
rep(ReportTypeErrnoInSignal
);
1764 if (!IsFiredSuppression(ctx
, rep
, stack
)) {
1765 rep
.AddStack(&stack
);
1766 OutputReport(ctx
, rep
, rep
.GetReport()->stacks
[0]);
1769 errno
= saved_errno
;
1773 pthread_sigmask(SIG_SETMASK
, &oldset
, 0);
1774 CHECK_EQ(thr
->in_signal_handler
, true);
1775 thr
->in_signal_handler
= false;
1778 static void unreachable() {
1779 Printf("FATAL: ThreadSanitizer: unreachable called\n");
1783 void InitializeInterceptors() {
1784 CHECK_GT(cur_thread()->in_rtl
, 0);
1786 // We need to setup it early, because functions like dlsym() can call it.
1787 REAL(memset
) = internal_memset
;
1788 REAL(memcpy
) = internal_memcpy
;
1789 REAL(memcmp
) = internal_memcmp
;
1791 SANITIZER_COMMON_INTERCEPTORS_INIT
;
1793 TSAN_INTERCEPT(longjmp
);
1794 TSAN_INTERCEPT(siglongjmp
);
1796 TSAN_INTERCEPT(malloc
);
1797 TSAN_INTERCEPT(__libc_memalign
);
1798 TSAN_INTERCEPT(calloc
);
1799 TSAN_INTERCEPT(realloc
);
1800 TSAN_INTERCEPT(free
);
1801 TSAN_INTERCEPT(cfree
);
1802 TSAN_INTERCEPT(mmap
);
1803 TSAN_INTERCEPT(mmap64
);
1804 TSAN_INTERCEPT(munmap
);
1805 TSAN_INTERCEPT(memalign
);
1806 TSAN_INTERCEPT(valloc
);
1807 TSAN_INTERCEPT(pvalloc
);
1808 TSAN_INTERCEPT(posix_memalign
);
1810 TSAN_INTERCEPT(strlen
);
1811 TSAN_INTERCEPT(memset
);
1812 TSAN_INTERCEPT(memcpy
);
1813 TSAN_INTERCEPT(strcmp
);
1814 TSAN_INTERCEPT(memchr
);
1815 TSAN_INTERCEPT(memrchr
);
1816 TSAN_INTERCEPT(memmove
);
1817 TSAN_INTERCEPT(memcmp
);
1818 TSAN_INTERCEPT(strchr
);
1819 TSAN_INTERCEPT(strchrnul
);
1820 TSAN_INTERCEPT(strrchr
);
1821 TSAN_INTERCEPT(strncmp
);
1822 TSAN_INTERCEPT(strcpy
); // NOLINT
1823 TSAN_INTERCEPT(strncpy
);
1824 TSAN_INTERCEPT(strstr
);
1826 TSAN_INTERCEPT(pthread_create
);
1827 TSAN_INTERCEPT(pthread_join
);
1828 TSAN_INTERCEPT(pthread_detach
);
1830 TSAN_INTERCEPT(pthread_mutex_init
);
1831 TSAN_INTERCEPT(pthread_mutex_destroy
);
1832 TSAN_INTERCEPT(pthread_mutex_lock
);
1833 TSAN_INTERCEPT(pthread_mutex_trylock
);
1834 TSAN_INTERCEPT(pthread_mutex_timedlock
);
1835 TSAN_INTERCEPT(pthread_mutex_unlock
);
1837 TSAN_INTERCEPT(pthread_spin_init
);
1838 TSAN_INTERCEPT(pthread_spin_destroy
);
1839 TSAN_INTERCEPT(pthread_spin_lock
);
1840 TSAN_INTERCEPT(pthread_spin_trylock
);
1841 TSAN_INTERCEPT(pthread_spin_unlock
);
1843 TSAN_INTERCEPT(pthread_rwlock_init
);
1844 TSAN_INTERCEPT(pthread_rwlock_destroy
);
1845 TSAN_INTERCEPT(pthread_rwlock_rdlock
);
1846 TSAN_INTERCEPT(pthread_rwlock_tryrdlock
);
1847 TSAN_INTERCEPT(pthread_rwlock_timedrdlock
);
1848 TSAN_INTERCEPT(pthread_rwlock_wrlock
);
1849 TSAN_INTERCEPT(pthread_rwlock_trywrlock
);
1850 TSAN_INTERCEPT(pthread_rwlock_timedwrlock
);
1851 TSAN_INTERCEPT(pthread_rwlock_unlock
);
1853 // TSAN_INTERCEPT(pthread_cond_init);
1854 TSAN_INTERCEPT(pthread_cond_destroy
);
1855 TSAN_INTERCEPT(pthread_cond_signal
);
1856 TSAN_INTERCEPT(pthread_cond_broadcast
);
1857 TSAN_INTERCEPT(pthread_cond_wait
);
1858 TSAN_INTERCEPT(pthread_cond_timedwait
);
1860 TSAN_INTERCEPT(pthread_barrier_init
);
1861 TSAN_INTERCEPT(pthread_barrier_destroy
);
1862 TSAN_INTERCEPT(pthread_barrier_wait
);
1864 TSAN_INTERCEPT(pthread_once
);
1866 TSAN_INTERCEPT(sem_init
);
1867 TSAN_INTERCEPT(sem_destroy
);
1868 TSAN_INTERCEPT(sem_wait
);
1869 TSAN_INTERCEPT(sem_trywait
);
1870 TSAN_INTERCEPT(sem_timedwait
);
1871 TSAN_INTERCEPT(sem_post
);
1872 TSAN_INTERCEPT(sem_getvalue
);
1874 TSAN_INTERCEPT(stat
);
1875 TSAN_INTERCEPT(__xstat
);
1876 TSAN_INTERCEPT(stat64
);
1877 TSAN_INTERCEPT(__xstat64
);
1878 TSAN_INTERCEPT(lstat
);
1879 TSAN_INTERCEPT(__lxstat
);
1880 TSAN_INTERCEPT(lstat64
);
1881 TSAN_INTERCEPT(__lxstat64
);
1882 TSAN_INTERCEPT(fstat
);
1883 TSAN_INTERCEPT(__fxstat
);
1884 TSAN_INTERCEPT(fstat64
);
1885 TSAN_INTERCEPT(__fxstat64
);
1886 TSAN_INTERCEPT(open
);
1887 TSAN_INTERCEPT(open64
);
1888 TSAN_INTERCEPT(creat
);
1889 TSAN_INTERCEPT(creat64
);
1890 TSAN_INTERCEPT(dup
);
1891 TSAN_INTERCEPT(dup2
);
1892 TSAN_INTERCEPT(dup3
);
1893 TSAN_INTERCEPT(eventfd
);
1894 TSAN_INTERCEPT(signalfd
);
1895 TSAN_INTERCEPT(inotify_init
);
1896 TSAN_INTERCEPT(inotify_init1
);
1897 TSAN_INTERCEPT(socket
);
1898 TSAN_INTERCEPT(socketpair
);
1899 TSAN_INTERCEPT(connect
);
1900 TSAN_INTERCEPT(accept
);
1901 TSAN_INTERCEPT(accept4
);
1902 TSAN_INTERCEPT(epoll_create
);
1903 TSAN_INTERCEPT(epoll_create1
);
1904 TSAN_INTERCEPT(close
);
1905 TSAN_INTERCEPT(pipe
);
1906 TSAN_INTERCEPT(pipe2
);
1908 TSAN_INTERCEPT(readv
);
1909 TSAN_INTERCEPT(preadv64
);
1910 TSAN_INTERCEPT(writev
);
1911 TSAN_INTERCEPT(pwritev64
);
1912 TSAN_INTERCEPT(send
);
1913 TSAN_INTERCEPT(sendmsg
);
1914 TSAN_INTERCEPT(recv
);
1915 TSAN_INTERCEPT(recvmsg
);
1917 TSAN_INTERCEPT(unlink
);
1918 TSAN_INTERCEPT(fopen
);
1919 TSAN_INTERCEPT(freopen
);
1920 TSAN_INTERCEPT(fclose
);
1921 TSAN_INTERCEPT(fread
);
1922 TSAN_INTERCEPT(fwrite
);
1923 TSAN_INTERCEPT(puts
);
1924 TSAN_INTERCEPT(rmdir
);
1925 TSAN_INTERCEPT(opendir
);
1927 TSAN_INTERCEPT(epoll_ctl
);
1928 TSAN_INTERCEPT(epoll_wait
);
1929 TSAN_INTERCEPT(poll
);
1931 TSAN_INTERCEPT(sigaction
);
1932 TSAN_INTERCEPT(signal
);
1933 TSAN_INTERCEPT(raise
);
1934 TSAN_INTERCEPT(kill
);
1935 TSAN_INTERCEPT(pthread_kill
);
1936 TSAN_INTERCEPT(sleep
);
1937 TSAN_INTERCEPT(usleep
);
1938 TSAN_INTERCEPT(nanosleep
);
1939 TSAN_INTERCEPT(gettimeofday
);
1941 TSAN_INTERCEPT(mlock
);
1942 TSAN_INTERCEPT(munlock
);
1943 TSAN_INTERCEPT(mlockall
);
1944 TSAN_INTERCEPT(munlockall
);
1946 TSAN_INTERCEPT(fork
);
1947 TSAN_INTERCEPT(on_exit
);
1948 TSAN_INTERCEPT(__cxa_atexit
);
1950 // Need to setup it, because interceptors check that the function is resolved.
1951 // But atexit is emitted directly into the module, so can't be resolved.
1952 REAL(atexit
) = (int(*)(void(*)()))unreachable
;
1953 atexit_ctx
= new(internal_alloc(MBlockAtExit
, sizeof(AtExitContext
)))
1956 if (REAL(__cxa_atexit
)(&finalize
, 0, 0)) {
1957 Printf("ThreadSanitizer: failed to setup atexit callback\n");
1961 if (pthread_key_create(&g_thread_finalize_key
, &thread_finalize
)) {
1962 Printf("ThreadSanitizer: failed to create thread key\n");
1969 void internal_start_thread(void(*func
)(void *arg
), void *arg
) {
1971 REAL(pthread_create
)(&th
, 0, (void*(*)(void *arg
))func
, arg
);
1972 REAL(pthread_detach
)(th
);
1975 } // namespace __tsan