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.h
12 //===----------------------------------------------------------------------===//
14 #include "sanitizer_common/sanitizer_atomic.h"
15 #include "sanitizer_common/sanitizer_libc.h"
16 #include "sanitizer_common/sanitizer_placement_new.h"
17 #include "sanitizer_common/sanitizer_stacktrace.h"
18 #include "interception/interception.h"
19 #include "tsan_interface.h"
20 #include "tsan_platform.h"
22 #include "tsan_mman.h"
25 using namespace __tsan
; // NOLINT
27 const int kSigCount
= 128;
34 u64 val
[1024 / 8 / sizeof(u64
)];
41 extern "C" int pthread_attr_init(void *attr
);
42 extern "C" int pthread_attr_destroy(void *attr
);
43 extern "C" int pthread_attr_getdetachstate(void *attr
, int *v
);
44 extern "C" int pthread_attr_setstacksize(void *attr
, uptr stacksize
);
45 extern "C" int pthread_attr_getstacksize(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 extern "C" int pthread_mutexattr_gettype(void *a
, int *type
);
49 extern "C" int pthread_yield();
50 extern "C" int pthread_sigmask(int how
, const sigset_t
*set
, sigset_t
*oldset
);
51 extern "C" int sigfillset(sigset_t
*set
);
52 extern "C" void *pthread_self();
53 extern "C" void _exit(int status
);
54 extern "C" int *__errno_location();
55 extern "C" int fileno_unlocked(void *stream
);
56 extern "C" void *__libc_malloc(uptr size
);
57 extern "C" void *__libc_calloc(uptr size
, uptr n
);
58 extern "C" void *__libc_realloc(void *ptr
, uptr size
);
59 extern "C" void __libc_free(void *ptr
);
60 const int PTHREAD_MUTEX_RECURSIVE
= 1;
61 const int PTHREAD_MUTEX_RECURSIVE_NP
= 1;
62 const int kPthreadAttrSize
= 56;
63 const int EINVAL
= 22;
65 const int EPOLL_CTL_ADD
= 1;
67 const int SIGABRT
= 6;
69 const int SIGSEGV
= 11;
70 const int SIGPIPE
= 13;
72 void *const MAP_FAILED
= (void*)-1;
73 const int PTHREAD_BARRIER_SERIAL_THREAD
= -1;
74 const int MAP_FIXED
= 0x10;
75 typedef long long_t
; // NOLINT
77 // From /usr/include/unistd.h
78 # define F_ULOCK 0 /* Unlock a previously locked region. */
79 # define F_LOCK 1 /* Lock a region for exclusive use. */
80 # define F_TLOCK 2 /* Test and lock a region for exclusive use. */
81 # define F_TEST 3 /* Test a region for other processes locks. */
83 typedef void (*sighandler_t
)(int sig
);
85 #define errno (*__errno_location())
87 union pthread_attr_t
{
88 char size
[kPthreadAttrSize
];
94 sighandler_t sa_handler
;
95 void (*sa_sigaction
)(int sig
, my_siginfo_t
*siginfo
, void *uctx
);
99 void (*sa_restorer
)();
102 const sighandler_t SIG_DFL
= (sighandler_t
)0;
103 const sighandler_t SIG_IGN
= (sighandler_t
)1;
104 const sighandler_t SIG_ERR
= (sighandler_t
)-1;
105 const int SA_SIGINFO
= 4;
106 const int SIG_SETMASK
= 2;
112 static sigaction_t sigactions
[kSigCount
];
118 my_siginfo_t siginfo
;
122 struct SignalContext
{
123 int in_blocking_func
;
125 int pending_signal_count
;
126 SignalDesc pending_signals
[kSigCount
];
128 } // namespace __tsan
130 static SignalContext
*SigCtx(ThreadState
*thr
) {
131 SignalContext
*ctx
= (SignalContext
*)thr
->signal_ctx
;
132 if (ctx
== 0 && thr
->is_alive
) {
134 ctx
= (SignalContext
*)MmapOrDie(sizeof(*ctx
), "SignalContext");
135 MemoryResetRange(thr
, (uptr
)&SigCtx
, (uptr
)ctx
, sizeof(*ctx
));
136 thr
->signal_ctx
= ctx
;
141 static unsigned g_thread_finalize_key
;
143 class ScopedInterceptor
{
145 ScopedInterceptor(ThreadState
*thr
, const char *fname
, uptr pc
);
146 ~ScopedInterceptor();
148 ThreadState
*const thr_
;
152 ScopedInterceptor::ScopedInterceptor(ThreadState
*thr
, const char *fname
,
155 , in_rtl_(thr
->in_rtl
) {
156 if (thr_
->in_rtl
== 0) {
160 DPrintf("#%d: intercept %s()\n", thr_
->tid
, fname
);
166 ScopedInterceptor::~ScopedInterceptor() {
168 if (thr_
->in_rtl
== 0) {
170 ProcessPendingSignals(thr_
);
172 CHECK_EQ(in_rtl_
, thr_
->in_rtl
);
175 #define SCOPED_INTERCEPTOR_RAW(func, ...) \
176 ThreadState *thr = cur_thread(); \
177 StatInc(thr, StatInterceptor); \
178 StatInc(thr, StatInt_##func); \
179 const uptr caller_pc = GET_CALLER_PC(); \
180 ScopedInterceptor si(thr, #func, caller_pc); \
181 const uptr pc = __sanitizer::StackTrace::GetPreviousInstructionPc( \
182 __sanitizer::StackTrace::GetCurrentPc()); \
186 #define SCOPED_TSAN_INTERCEPTOR(func, ...) \
187 SCOPED_INTERCEPTOR_RAW(func, __VA_ARGS__); \
188 if (REAL(func) == 0) { \
189 Printf("FATAL: ThreadSanitizer: failed to intercept %s\n", #func); \
192 if (thr->in_rtl > 1) \
193 return REAL(func)(__VA_ARGS__); \
196 #define TSAN_INTERCEPTOR(ret, func, ...) INTERCEPTOR(ret, func, __VA_ARGS__)
197 #define TSAN_INTERCEPT(func) INTERCEPT_FUNCTION(func)
199 #define BLOCK_REAL(name) (BlockingCall(thr), REAL(name))
201 struct BlockingCall
{
202 explicit BlockingCall(ThreadState
*thr
)
204 ctx
->in_blocking_func
++;
208 ctx
->in_blocking_func
--;
214 TSAN_INTERCEPTOR(unsigned, sleep
, unsigned sec
) {
215 SCOPED_TSAN_INTERCEPTOR(sleep
, sec
);
216 unsigned res
= BLOCK_REAL(sleep
)(sec
);
221 TSAN_INTERCEPTOR(int, usleep
, long_t usec
) {
222 SCOPED_TSAN_INTERCEPTOR(usleep
, usec
);
223 int res
= BLOCK_REAL(usleep
)(usec
);
228 TSAN_INTERCEPTOR(int, nanosleep
, void *req
, void *rem
) {
229 SCOPED_TSAN_INTERCEPTOR(nanosleep
, req
, rem
);
230 int res
= BLOCK_REAL(nanosleep
)(req
, rem
);
235 class AtExitContext
{
238 : mtx_(MutexTypeAtExit
, StatMtxAtExit
)
242 typedef void(*atexit_t
)();
244 int atexit(ThreadState
*thr
, uptr pc
, bool is_on_exit
,
245 atexit_t f
, void *arg
) {
247 if (pos_
== kMaxAtExit
)
249 Release(thr
, pc
, (uptr
)this);
252 is_on_exits_
[pos_
] = is_on_exit
;
257 void exit(ThreadState
*thr
, uptr pc
) {
258 CHECK_EQ(thr
->in_rtl
, 0);
262 bool is_on_exit
= false;
269 is_on_exit
= is_on_exits_
[pos_
];
271 Acquire(thr
, pc
, (uptr
)this);
276 DPrintf("#%d: executing atexit func %p\n", thr
->tid
, f
);
277 CHECK_EQ(thr
->in_rtl
, 0);
279 ((void(*)(int status
, void *arg
))f
)(0, arg
);
281 ((void(*)(void *arg
, void *dso
))f
)(arg
, 0);
286 static const int kMaxAtExit
= 128;
288 atexit_t stack_
[kMaxAtExit
];
289 void *args_
[kMaxAtExit
];
290 bool is_on_exits_
[kMaxAtExit
];
294 static AtExitContext
*atexit_ctx
;
296 static void finalize(void *arg
) {
297 ThreadState
* thr
= cur_thread();
299 atexit_ctx
->exit(thr
, pc
);
300 int status
= Finalize(cur_thread());
305 TSAN_INTERCEPTOR(int, atexit
, void (*f
)()) {
306 if (cur_thread()->in_symbolizer
)
308 SCOPED_TSAN_INTERCEPTOR(atexit
, f
);
309 return atexit_ctx
->atexit(thr
, pc
, false, (void(*)())f
, 0);
312 TSAN_INTERCEPTOR(int, on_exit
, void(*f
)(int, void*), void *arg
) {
313 if (cur_thread()->in_symbolizer
)
315 SCOPED_TSAN_INTERCEPTOR(on_exit
, f
, arg
);
316 return atexit_ctx
->atexit(thr
, pc
, true, (void(*)())f
, arg
);
319 TSAN_INTERCEPTOR(int, __cxa_atexit
, void (*f
)(void *a
), void *arg
, void *dso
) {
320 if (cur_thread()->in_symbolizer
)
322 SCOPED_TSAN_INTERCEPTOR(__cxa_atexit
, f
, arg
, dso
);
324 return REAL(__cxa_atexit
)(f
, arg
, dso
);
325 return atexit_ctx
->atexit(thr
, pc
, false, (void(*)())f
, arg
);
328 TSAN_INTERCEPTOR(void, longjmp
, void *env
, int val
) {
329 SCOPED_TSAN_INTERCEPTOR(longjmp
, env
, val
);
330 Printf("ThreadSanitizer: longjmp() is not supported\n");
334 TSAN_INTERCEPTOR(void, siglongjmp
, void *env
, int val
) {
335 SCOPED_TSAN_INTERCEPTOR(siglongjmp
, env
, val
);
336 Printf("ThreadSanitizer: siglongjmp() is not supported\n");
340 TSAN_INTERCEPTOR(void*, malloc
, uptr size
) {
341 if (cur_thread()->in_symbolizer
)
342 return __libc_malloc(size
);
345 SCOPED_INTERCEPTOR_RAW(malloc
, size
);
346 p
= user_alloc(thr
, pc
, size
);
348 invoke_malloc_hook(p
, size
);
352 TSAN_INTERCEPTOR(void*, __libc_memalign
, uptr align
, uptr sz
) {
353 SCOPED_TSAN_INTERCEPTOR(__libc_memalign
, align
, sz
);
354 return user_alloc(thr
, pc
, sz
, align
);
357 TSAN_INTERCEPTOR(void*, calloc
, uptr size
, uptr n
) {
358 if (cur_thread()->in_symbolizer
)
359 return __libc_calloc(size
, n
);
360 if (__sanitizer::CallocShouldReturnNullDueToOverflow(size
, n
)) return 0;
363 SCOPED_INTERCEPTOR_RAW(calloc
, size
, n
);
364 p
= user_alloc(thr
, pc
, n
* size
);
365 if (p
) internal_memset(p
, 0, n
* size
);
367 invoke_malloc_hook(p
, n
* size
);
371 TSAN_INTERCEPTOR(void*, realloc
, void *p
, uptr size
) {
372 if (cur_thread()->in_symbolizer
)
373 return __libc_realloc(p
, size
);
377 SCOPED_INTERCEPTOR_RAW(realloc
, p
, size
);
378 p
= user_realloc(thr
, pc
, p
, size
);
380 invoke_malloc_hook(p
, size
);
384 TSAN_INTERCEPTOR(void, free
, void *p
) {
387 if (cur_thread()->in_symbolizer
)
388 return __libc_free(p
);
390 SCOPED_INTERCEPTOR_RAW(free
, p
);
391 user_free(thr
, pc
, p
);
394 TSAN_INTERCEPTOR(void, cfree
, void *p
) {
397 if (cur_thread()->in_symbolizer
)
398 return __libc_free(p
);
400 SCOPED_INTERCEPTOR_RAW(cfree
, p
);
401 user_free(thr
, pc
, p
);
404 #define OPERATOR_NEW_BODY(mangled_name) \
405 if (cur_thread()->in_symbolizer) \
406 return __libc_malloc(size); \
409 SCOPED_INTERCEPTOR_RAW(mangled_name, size); \
410 p = user_alloc(thr, pc, size); \
412 invoke_malloc_hook(p, size); \
415 void *operator new(__sanitizer::uptr size
) {
416 OPERATOR_NEW_BODY(_Znwm
);
418 void *operator new[](__sanitizer::uptr size
) {
419 OPERATOR_NEW_BODY(_Znam
);
421 void *operator new(__sanitizer::uptr size
, std::nothrow_t
const&) {
422 OPERATOR_NEW_BODY(_ZnwmRKSt9nothrow_t
);
424 void *operator new[](__sanitizer::uptr size
, std::nothrow_t
const&) {
425 OPERATOR_NEW_BODY(_ZnamRKSt9nothrow_t
);
428 #define OPERATOR_DELETE_BODY(mangled_name) \
429 if (ptr == 0) return; \
430 if (cur_thread()->in_symbolizer) \
431 return __libc_free(ptr); \
432 invoke_free_hook(ptr); \
433 SCOPED_INTERCEPTOR_RAW(mangled_name, ptr); \
434 user_free(thr, pc, ptr);
436 void operator delete(void *ptr
) {
437 OPERATOR_DELETE_BODY(_ZdlPv
);
439 void operator delete[](void *ptr
) {
440 OPERATOR_DELETE_BODY(_ZdlPvRKSt9nothrow_t
);
442 void operator delete(void *ptr
, std::nothrow_t
const&) {
443 OPERATOR_DELETE_BODY(_ZdaPv
);
445 void operator delete[](void *ptr
, std::nothrow_t
const&) {
446 OPERATOR_DELETE_BODY(_ZdaPvRKSt9nothrow_t
);
449 TSAN_INTERCEPTOR(uptr
, strlen
, const char *s
) {
450 SCOPED_TSAN_INTERCEPTOR(strlen
, s
);
451 uptr len
= internal_strlen(s
);
452 MemoryAccessRange(thr
, pc
, (uptr
)s
, len
+ 1, false);
456 TSAN_INTERCEPTOR(void*, memset
, void *dst
, int v
, uptr size
) {
457 SCOPED_TSAN_INTERCEPTOR(memset
, dst
, v
, size
);
458 MemoryAccessRange(thr
, pc
, (uptr
)dst
, size
, true);
459 return internal_memset(dst
, v
, size
);
462 TSAN_INTERCEPTOR(void*, memcpy
, void *dst
, const void *src
, uptr size
) {
463 SCOPED_TSAN_INTERCEPTOR(memcpy
, dst
, src
, size
);
464 MemoryAccessRange(thr
, pc
, (uptr
)dst
, size
, true);
465 MemoryAccessRange(thr
, pc
, (uptr
)src
, size
, false);
466 return internal_memcpy(dst
, src
, size
);
469 TSAN_INTERCEPTOR(int, memcmp
, const void *s1
, const void *s2
, uptr n
) {
470 SCOPED_TSAN_INTERCEPTOR(memcmp
, s1
, s2
, n
);
473 for (; len
< n
; len
++) {
474 if ((res
= ((unsigned char*)s1
)[len
] - ((unsigned char*)s2
)[len
]))
477 MemoryAccessRange(thr
, pc
, (uptr
)s1
, len
< n
? len
+ 1 : n
, false);
478 MemoryAccessRange(thr
, pc
, (uptr
)s2
, len
< n
? len
+ 1 : n
, false);
482 TSAN_INTERCEPTOR(int, strcmp
, const char *s1
, const char *s2
) {
483 SCOPED_TSAN_INTERCEPTOR(strcmp
, s1
, s2
);
485 for (; s1
[len
] && s2
[len
]; len
++) {
486 if (s1
[len
] != s2
[len
])
489 MemoryAccessRange(thr
, pc
, (uptr
)s1
, len
+ 1, false);
490 MemoryAccessRange(thr
, pc
, (uptr
)s2
, len
+ 1, false);
491 return s1
[len
] - s2
[len
];
494 TSAN_INTERCEPTOR(int, strncmp
, const char *s1
, const char *s2
, uptr n
) {
495 SCOPED_TSAN_INTERCEPTOR(strncmp
, s1
, s2
, n
);
497 for (; len
< n
&& s1
[len
] && s2
[len
]; len
++) {
498 if (s1
[len
] != s2
[len
])
501 MemoryAccessRange(thr
, pc
, (uptr
)s1
, len
< n
? len
+ 1 : n
, false);
502 MemoryAccessRange(thr
, pc
, (uptr
)s2
, len
< n
? len
+ 1 : n
, false);
503 return len
== n
? 0 : s1
[len
] - s2
[len
];
506 TSAN_INTERCEPTOR(void*, memchr
, void *s
, int c
, uptr n
) {
507 SCOPED_TSAN_INTERCEPTOR(memchr
, s
, c
, n
);
508 void *res
= REAL(memchr
)(s
, c
, n
);
509 uptr len
= res
? (char*)res
- (char*)s
+ 1 : n
;
510 MemoryAccessRange(thr
, pc
, (uptr
)s
, len
, false);
514 TSAN_INTERCEPTOR(void*, memrchr
, char *s
, int c
, uptr n
) {
515 SCOPED_TSAN_INTERCEPTOR(memrchr
, s
, c
, n
);
516 MemoryAccessRange(thr
, pc
, (uptr
)s
, n
, false);
517 return REAL(memrchr
)(s
, c
, n
);
520 TSAN_INTERCEPTOR(void*, memmove
, void *dst
, void *src
, uptr n
) {
521 SCOPED_TSAN_INTERCEPTOR(memmove
, dst
, src
, n
);
522 MemoryAccessRange(thr
, pc
, (uptr
)dst
, n
, true);
523 MemoryAccessRange(thr
, pc
, (uptr
)src
, n
, false);
524 return REAL(memmove
)(dst
, src
, n
);
527 TSAN_INTERCEPTOR(char*, strchr
, char *s
, int c
) {
528 SCOPED_TSAN_INTERCEPTOR(strchr
, s
, c
);
529 char *res
= REAL(strchr
)(s
, c
);
530 uptr len
= res
? (char*)res
- (char*)s
+ 1 : internal_strlen(s
) + 1;
531 MemoryAccessRange(thr
, pc
, (uptr
)s
, len
, false);
535 TSAN_INTERCEPTOR(char*, strchrnul
, char *s
, int c
) {
536 SCOPED_TSAN_INTERCEPTOR(strchrnul
, s
, c
);
537 char *res
= REAL(strchrnul
)(s
, c
);
538 uptr len
= (char*)res
- (char*)s
+ 1;
539 MemoryAccessRange(thr
, pc
, (uptr
)s
, len
, false);
543 TSAN_INTERCEPTOR(char*, strrchr
, char *s
, int c
) {
544 SCOPED_TSAN_INTERCEPTOR(strrchr
, s
, c
);
545 MemoryAccessRange(thr
, pc
, (uptr
)s
, internal_strlen(s
) + 1, false);
546 return REAL(strrchr
)(s
, c
);
549 TSAN_INTERCEPTOR(char*, strcpy
, char *dst
, const char *src
) { // NOLINT
550 SCOPED_TSAN_INTERCEPTOR(strcpy
, dst
, src
); // NOLINT
551 uptr srclen
= internal_strlen(src
);
552 MemoryAccessRange(thr
, pc
, (uptr
)dst
, srclen
+ 1, true);
553 MemoryAccessRange(thr
, pc
, (uptr
)src
, srclen
+ 1, false);
554 return REAL(strcpy
)(dst
, src
); // NOLINT
557 TSAN_INTERCEPTOR(char*, strncpy
, char *dst
, char *src
, uptr n
) {
558 SCOPED_TSAN_INTERCEPTOR(strncpy
, dst
, src
, n
);
559 uptr srclen
= internal_strnlen(src
, n
);
560 MemoryAccessRange(thr
, pc
, (uptr
)dst
, n
, true);
561 MemoryAccessRange(thr
, pc
, (uptr
)src
, min(srclen
+ 1, n
), false);
562 return REAL(strncpy
)(dst
, src
, n
);
565 TSAN_INTERCEPTOR(const char*, strstr
, const char *s1
, const char *s2
) {
566 SCOPED_TSAN_INTERCEPTOR(strstr
, s1
, s2
);
567 const char *res
= REAL(strstr
)(s1
, s2
);
568 uptr len1
= internal_strlen(s1
);
569 uptr len2
= internal_strlen(s2
);
570 MemoryAccessRange(thr
, pc
, (uptr
)s1
, len1
+ 1, false);
571 MemoryAccessRange(thr
, pc
, (uptr
)s2
, len2
+ 1, false);
575 static bool fix_mmap_addr(void **addr
, long_t sz
, int flags
) {
577 if (!IsAppMem((uptr
)*addr
) || !IsAppMem((uptr
)*addr
+ sz
- 1)) {
578 if (flags
& MAP_FIXED
) {
589 TSAN_INTERCEPTOR(void*, mmap
, void *addr
, long_t sz
, int prot
,
590 int flags
, int fd
, unsigned off
) {
591 SCOPED_TSAN_INTERCEPTOR(mmap
, addr
, sz
, prot
, flags
, fd
, off
);
592 if (!fix_mmap_addr(&addr
, sz
, flags
))
594 void *res
= REAL(mmap
)(addr
, sz
, prot
, flags
, fd
, off
);
595 if (res
!= MAP_FAILED
) {
597 FdAccess(thr
, pc
, fd
);
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
) {
611 FdAccess(thr
, pc
, fd
);
612 MemoryResetRange(thr
, pc
, (uptr
)res
, sz
);
617 TSAN_INTERCEPTOR(int, munmap
, void *addr
, long_t sz
) {
618 SCOPED_TSAN_INTERCEPTOR(munmap
, addr
, sz
);
619 int res
= REAL(munmap
)(addr
, sz
);
623 TSAN_INTERCEPTOR(void*, memalign
, uptr align
, uptr sz
) {
624 SCOPED_TSAN_INTERCEPTOR(memalign
, align
, sz
);
625 return user_alloc(thr
, pc
, sz
, align
);
628 TSAN_INTERCEPTOR(void*, valloc
, uptr sz
) {
629 SCOPED_TSAN_INTERCEPTOR(valloc
, sz
);
630 return user_alloc(thr
, pc
, sz
, GetPageSizeCached());
633 TSAN_INTERCEPTOR(void*, pvalloc
, uptr sz
) {
634 SCOPED_TSAN_INTERCEPTOR(pvalloc
, sz
);
635 sz
= RoundUp(sz
, GetPageSizeCached());
636 return user_alloc(thr
, pc
, sz
, GetPageSizeCached());
639 TSAN_INTERCEPTOR(int, posix_memalign
, void **memptr
, uptr align
, uptr sz
) {
640 SCOPED_TSAN_INTERCEPTOR(posix_memalign
, memptr
, align
, sz
);
641 *memptr
= user_alloc(thr
, pc
, sz
, align
);
645 // Used in thread-safe function static initialization.
646 extern "C" int INTERFACE_ATTRIBUTE
__cxa_guard_acquire(atomic_uint32_t
*g
) {
647 SCOPED_INTERCEPTOR_RAW(__cxa_guard_acquire
, g
);
649 u32 cmp
= atomic_load(g
, memory_order_acquire
);
651 if (atomic_compare_exchange_strong(g
, &cmp
, 1<<16, memory_order_relaxed
))
653 } else if (cmp
== 1) {
654 Acquire(thr
, pc
, (uptr
)g
);
657 internal_sched_yield();
662 extern "C" void INTERFACE_ATTRIBUTE
__cxa_guard_release(atomic_uint32_t
*g
) {
663 SCOPED_INTERCEPTOR_RAW(__cxa_guard_release
, g
);
664 Release(thr
, pc
, (uptr
)g
);
665 atomic_store(g
, 1, memory_order_release
);
668 extern "C" void INTERFACE_ATTRIBUTE
__cxa_guard_abort(atomic_uint32_t
*g
) {
669 SCOPED_INTERCEPTOR_RAW(__cxa_guard_abort
, g
);
670 atomic_store(g
, 0, memory_order_relaxed
);
673 static void thread_finalize(void *v
) {
676 if (pthread_setspecific(g_thread_finalize_key
, (void*)(iter
- 1))) {
677 Printf("ThreadSanitizer: failed to set thread key\n");
684 ThreadState
*thr
= cur_thread();
686 SignalContext
*sctx
= thr
->signal_ctx
;
689 UnmapOrDie(sctx
, sizeof(*sctx
));
696 void* (*callback
)(void *arg
);
698 atomic_uintptr_t tid
;
701 extern "C" void *__tsan_thread_start_func(void *arg
) {
702 ThreadParam
*p
= (ThreadParam
*)arg
;
703 void* (*callback
)(void *arg
) = p
->callback
;
704 void *param
= p
->param
;
707 ThreadState
*thr
= cur_thread();
709 if (pthread_setspecific(g_thread_finalize_key
, (void*)4)) {
710 Printf("ThreadSanitizer: failed to set thread key\n");
713 while ((tid
= atomic_load(&p
->tid
, memory_order_acquire
)) == 0)
715 atomic_store(&p
->tid
, 0, memory_order_release
);
716 ThreadStart(thr
, tid
, GetTid());
717 CHECK_EQ(thr
->in_rtl
, 1);
719 void *res
= callback(param
);
720 // Prevent the callback from being tail called,
721 // it mixes up stack traces.
722 volatile int foo
= 42;
727 TSAN_INTERCEPTOR(int, pthread_create
,
728 void *th
, void *attr
, void *(*callback
)(void*), void * param
) {
729 SCOPED_TSAN_INTERCEPTOR(pthread_create
, th
, attr
, callback
, param
);
730 pthread_attr_t myattr
;
732 pthread_attr_init(&myattr
);
736 pthread_attr_getdetachstate(attr
, &detached
);
738 pthread_attr_getstacksize(attr
, &stacksize
);
739 // We place the huge ThreadState object into TLS, account for that.
740 const uptr minstacksize
= GetTlsSize() + 128*1024;
741 if (stacksize
< minstacksize
) {
742 DPrintf("ThreadSanitizer: stacksize %zu->%zu\n", stacksize
, minstacksize
);
743 pthread_attr_setstacksize(attr
, minstacksize
);
746 p
.callback
= callback
;
748 atomic_store(&p
.tid
, 0, memory_order_relaxed
);
749 int res
= REAL(pthread_create
)(th
, attr
, __tsan_thread_start_func
, &p
);
751 int tid
= ThreadCreate(thr
, pc
, *(uptr
*)th
, detached
);
753 atomic_store(&p
.tid
, tid
, memory_order_release
);
754 while (atomic_load(&p
.tid
, memory_order_acquire
) != 0)
758 pthread_attr_destroy(&myattr
);
762 TSAN_INTERCEPTOR(int, pthread_join
, void *th
, void **ret
) {
763 SCOPED_TSAN_INTERCEPTOR(pthread_join
, th
, ret
);
764 int tid
= ThreadTid(thr
, pc
, (uptr
)th
);
765 int res
= BLOCK_REAL(pthread_join
)(th
, ret
);
767 ThreadJoin(thr
, pc
, tid
);
772 TSAN_INTERCEPTOR(int, pthread_detach
, void *th
) {
773 SCOPED_TSAN_INTERCEPTOR(pthread_detach
, th
);
774 int tid
= ThreadTid(thr
, pc
, (uptr
)th
);
775 int res
= REAL(pthread_detach
)(th
);
777 ThreadDetach(thr
, pc
, tid
);
782 TSAN_INTERCEPTOR(int, pthread_mutex_init
, void *m
, void *a
) {
783 SCOPED_TSAN_INTERCEPTOR(pthread_mutex_init
, m
, a
);
784 int res
= REAL(pthread_mutex_init
)(m
, a
);
786 bool recursive
= false;
789 if (pthread_mutexattr_gettype(a
, &type
) == 0)
790 recursive
= (type
== PTHREAD_MUTEX_RECURSIVE
791 || type
== PTHREAD_MUTEX_RECURSIVE_NP
);
793 MutexCreate(thr
, pc
, (uptr
)m
, false, recursive
, false);
798 TSAN_INTERCEPTOR(int, pthread_mutex_destroy
, void *m
) {
799 SCOPED_TSAN_INTERCEPTOR(pthread_mutex_destroy
, m
);
800 int res
= REAL(pthread_mutex_destroy
)(m
);
801 if (res
== 0 || res
== EBUSY
) {
802 MutexDestroy(thr
, pc
, (uptr
)m
);
807 TSAN_INTERCEPTOR(int, pthread_mutex_lock
, void *m
) {
808 SCOPED_TSAN_INTERCEPTOR(pthread_mutex_lock
, m
);
809 int res
= REAL(pthread_mutex_lock
)(m
);
811 MutexLock(thr
, pc
, (uptr
)m
);
816 TSAN_INTERCEPTOR(int, pthread_mutex_trylock
, void *m
) {
817 SCOPED_TSAN_INTERCEPTOR(pthread_mutex_trylock
, m
);
818 int res
= REAL(pthread_mutex_trylock
)(m
);
820 MutexLock(thr
, pc
, (uptr
)m
);
825 TSAN_INTERCEPTOR(int, pthread_mutex_timedlock
, void *m
, void *abstime
) {
826 SCOPED_TSAN_INTERCEPTOR(pthread_mutex_timedlock
, m
, abstime
);
827 int res
= REAL(pthread_mutex_timedlock
)(m
, abstime
);
829 MutexLock(thr
, pc
, (uptr
)m
);
834 TSAN_INTERCEPTOR(int, pthread_mutex_unlock
, void *m
) {
835 SCOPED_TSAN_INTERCEPTOR(pthread_mutex_unlock
, m
);
836 MutexUnlock(thr
, pc
, (uptr
)m
);
837 int res
= REAL(pthread_mutex_unlock
)(m
);
841 TSAN_INTERCEPTOR(int, pthread_spin_init
, void *m
, int pshared
) {
842 SCOPED_TSAN_INTERCEPTOR(pthread_spin_init
, m
, pshared
);
843 int res
= REAL(pthread_spin_init
)(m
, pshared
);
845 MutexCreate(thr
, pc
, (uptr
)m
, false, false, false);
850 TSAN_INTERCEPTOR(int, pthread_spin_destroy
, void *m
) {
851 SCOPED_TSAN_INTERCEPTOR(pthread_spin_destroy
, m
);
852 int res
= REAL(pthread_spin_destroy
)(m
);
854 MutexDestroy(thr
, pc
, (uptr
)m
);
859 TSAN_INTERCEPTOR(int, pthread_spin_lock
, void *m
) {
860 SCOPED_TSAN_INTERCEPTOR(pthread_spin_lock
, m
);
861 int res
= REAL(pthread_spin_lock
)(m
);
863 MutexLock(thr
, pc
, (uptr
)m
);
868 TSAN_INTERCEPTOR(int, pthread_spin_trylock
, void *m
) {
869 SCOPED_TSAN_INTERCEPTOR(pthread_spin_trylock
, m
);
870 int res
= REAL(pthread_spin_trylock
)(m
);
872 MutexLock(thr
, pc
, (uptr
)m
);
877 TSAN_INTERCEPTOR(int, pthread_spin_unlock
, void *m
) {
878 SCOPED_TSAN_INTERCEPTOR(pthread_spin_unlock
, m
);
879 MutexUnlock(thr
, pc
, (uptr
)m
);
880 int res
= REAL(pthread_spin_unlock
)(m
);
884 TSAN_INTERCEPTOR(int, pthread_rwlock_init
, void *m
, void *a
) {
885 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_init
, m
, a
);
886 int res
= REAL(pthread_rwlock_init
)(m
, a
);
888 MutexCreate(thr
, pc
, (uptr
)m
, true, false, false);
893 TSAN_INTERCEPTOR(int, pthread_rwlock_destroy
, void *m
) {
894 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_destroy
, m
);
895 int res
= REAL(pthread_rwlock_destroy
)(m
);
897 MutexDestroy(thr
, pc
, (uptr
)m
);
902 TSAN_INTERCEPTOR(int, pthread_rwlock_rdlock
, void *m
) {
903 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_rdlock
, m
);
904 int res
= REAL(pthread_rwlock_rdlock
)(m
);
906 MutexReadLock(thr
, pc
, (uptr
)m
);
911 TSAN_INTERCEPTOR(int, pthread_rwlock_tryrdlock
, void *m
) {
912 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_tryrdlock
, m
);
913 int res
= REAL(pthread_rwlock_tryrdlock
)(m
);
915 MutexReadLock(thr
, pc
, (uptr
)m
);
920 TSAN_INTERCEPTOR(int, pthread_rwlock_timedrdlock
, void *m
, void *abstime
) {
921 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_timedrdlock
, m
, abstime
);
922 int res
= REAL(pthread_rwlock_timedrdlock
)(m
, abstime
);
924 MutexReadLock(thr
, pc
, (uptr
)m
);
929 TSAN_INTERCEPTOR(int, pthread_rwlock_wrlock
, void *m
) {
930 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_wrlock
, m
);
931 int res
= REAL(pthread_rwlock_wrlock
)(m
);
933 MutexLock(thr
, pc
, (uptr
)m
);
938 TSAN_INTERCEPTOR(int, pthread_rwlock_trywrlock
, void *m
) {
939 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_trywrlock
, m
);
940 int res
= REAL(pthread_rwlock_trywrlock
)(m
);
942 MutexLock(thr
, pc
, (uptr
)m
);
947 TSAN_INTERCEPTOR(int, pthread_rwlock_timedwrlock
, void *m
, void *abstime
) {
948 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_timedwrlock
, m
, abstime
);
949 int res
= REAL(pthread_rwlock_timedwrlock
)(m
, abstime
);
951 MutexLock(thr
, pc
, (uptr
)m
);
956 TSAN_INTERCEPTOR(int, pthread_rwlock_unlock
, void *m
) {
957 SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_unlock
, m
);
958 MutexReadOrWriteUnlock(thr
, pc
, (uptr
)m
);
959 int res
= REAL(pthread_rwlock_unlock
)(m
);
963 // libpthread.so contains several versions of pthread_cond_init symbol.
964 // When we just dlsym() it, we get the wrong (old) version.
966 TSAN_INTERCEPTOR(int, pthread_cond_init, void *c, void *a) {
967 SCOPED_TSAN_INTERCEPTOR(pthread_cond_init, c, a);
968 int res = REAL(pthread_cond_init)(c, a);
973 TSAN_INTERCEPTOR(int, pthread_cond_destroy
, void *c
) {
974 SCOPED_TSAN_INTERCEPTOR(pthread_cond_destroy
, c
);
975 int res
= REAL(pthread_cond_destroy
)(c
);
979 TSAN_INTERCEPTOR(int, pthread_cond_signal
, void *c
) {
980 SCOPED_TSAN_INTERCEPTOR(pthread_cond_signal
, c
);
981 int res
= REAL(pthread_cond_signal
)(c
);
985 TSAN_INTERCEPTOR(int, pthread_cond_broadcast
, void *c
) {
986 SCOPED_TSAN_INTERCEPTOR(pthread_cond_broadcast
, c
);
987 int res
= REAL(pthread_cond_broadcast
)(c
);
991 TSAN_INTERCEPTOR(int, pthread_cond_wait
, void *c
, void *m
) {
992 SCOPED_TSAN_INTERCEPTOR(pthread_cond_wait
, c
, m
);
993 MutexUnlock(thr
, pc
, (uptr
)m
);
994 int res
= REAL(pthread_cond_wait
)(c
, m
);
995 MutexLock(thr
, pc
, (uptr
)m
);
999 TSAN_INTERCEPTOR(int, pthread_cond_timedwait
, void *c
, void *m
, void *abstime
) {
1000 SCOPED_TSAN_INTERCEPTOR(pthread_cond_timedwait
, c
, m
, abstime
);
1001 MutexUnlock(thr
, pc
, (uptr
)m
);
1002 int res
= REAL(pthread_cond_timedwait
)(c
, m
, abstime
);
1003 MutexLock(thr
, pc
, (uptr
)m
);
1007 TSAN_INTERCEPTOR(int, pthread_barrier_init
, void *b
, void *a
, unsigned count
) {
1008 SCOPED_TSAN_INTERCEPTOR(pthread_barrier_init
, b
, a
, count
);
1009 MemoryWrite(thr
, pc
, (uptr
)b
, kSizeLog1
);
1010 int res
= REAL(pthread_barrier_init
)(b
, a
, count
);
1014 TSAN_INTERCEPTOR(int, pthread_barrier_destroy
, void *b
) {
1015 SCOPED_TSAN_INTERCEPTOR(pthread_barrier_destroy
, b
);
1016 MemoryWrite(thr
, pc
, (uptr
)b
, kSizeLog1
);
1017 int res
= REAL(pthread_barrier_destroy
)(b
);
1021 TSAN_INTERCEPTOR(int, pthread_barrier_wait
, void *b
) {
1022 SCOPED_TSAN_INTERCEPTOR(pthread_barrier_wait
, b
);
1023 Release(thr
, pc
, (uptr
)b
);
1024 MemoryRead(thr
, pc
, (uptr
)b
, kSizeLog1
);
1025 int res
= REAL(pthread_barrier_wait
)(b
);
1026 MemoryRead(thr
, pc
, (uptr
)b
, kSizeLog1
);
1027 if (res
== 0 || res
== PTHREAD_BARRIER_SERIAL_THREAD
) {
1028 Acquire(thr
, pc
, (uptr
)b
);
1033 TSAN_INTERCEPTOR(int, pthread_once
, void *o
, void (*f
)()) {
1034 SCOPED_TSAN_INTERCEPTOR(pthread_once
, o
, f
);
1035 if (o
== 0 || f
== 0)
1037 atomic_uint32_t
*a
= static_cast<atomic_uint32_t
*>(o
);
1038 u32 v
= atomic_load(a
, memory_order_acquire
);
1039 if (v
== 0 && atomic_compare_exchange_strong(a
, &v
, 1,
1040 memory_order_relaxed
)) {
1041 const int old_in_rtl
= thr
->in_rtl
;
1044 CHECK_EQ(thr
->in_rtl
, 0);
1045 thr
->in_rtl
= old_in_rtl
;
1046 Release(thr
, pc
, (uptr
)o
);
1047 atomic_store(a
, 2, memory_order_release
);
1051 v
= atomic_load(a
, memory_order_acquire
);
1053 Acquire(thr
, pc
, (uptr
)o
);
1058 TSAN_INTERCEPTOR(int, sem_init
, void *s
, int pshared
, unsigned value
) {
1059 SCOPED_TSAN_INTERCEPTOR(sem_init
, s
, pshared
, value
);
1060 int res
= REAL(sem_init
)(s
, pshared
, value
);
1064 TSAN_INTERCEPTOR(int, sem_destroy
, void *s
) {
1065 SCOPED_TSAN_INTERCEPTOR(sem_destroy
, s
);
1066 int res
= REAL(sem_destroy
)(s
);
1070 TSAN_INTERCEPTOR(int, sem_wait
, void *s
) {
1071 SCOPED_TSAN_INTERCEPTOR(sem_wait
, s
);
1072 int res
= BLOCK_REAL(sem_wait
)(s
);
1074 Acquire(thr
, pc
, (uptr
)s
);
1079 TSAN_INTERCEPTOR(int, sem_trywait
, void *s
) {
1080 SCOPED_TSAN_INTERCEPTOR(sem_trywait
, s
);
1081 int res
= BLOCK_REAL(sem_trywait
)(s
);
1083 Acquire(thr
, pc
, (uptr
)s
);
1088 TSAN_INTERCEPTOR(int, sem_timedwait
, void *s
, void *abstime
) {
1089 SCOPED_TSAN_INTERCEPTOR(sem_timedwait
, s
, abstime
);
1090 int res
= BLOCK_REAL(sem_timedwait
)(s
, abstime
);
1092 Acquire(thr
, pc
, (uptr
)s
);
1097 TSAN_INTERCEPTOR(int, sem_post
, void *s
) {
1098 SCOPED_TSAN_INTERCEPTOR(sem_post
, s
);
1099 Release(thr
, pc
, (uptr
)s
);
1100 int res
= REAL(sem_post
)(s
);
1104 TSAN_INTERCEPTOR(int, sem_getvalue
, void *s
, int *sval
) {
1105 SCOPED_TSAN_INTERCEPTOR(sem_getvalue
, s
, sval
);
1106 int res
= REAL(sem_getvalue
)(s
, sval
);
1108 Acquire(thr
, pc
, (uptr
)s
);
1113 TSAN_INTERCEPTOR(int, __xstat
, int version
, const char *path
, void *buf
) {
1114 SCOPED_TSAN_INTERCEPTOR(__xstat
, version
, path
, buf
);
1115 return REAL(__xstat
)(version
, path
, buf
);
1118 TSAN_INTERCEPTOR(int, stat
, const char *path
, void *buf
) {
1119 SCOPED_TSAN_INTERCEPTOR(__xstat
, 0, path
, buf
);
1120 return REAL(__xstat
)(0, path
, buf
);
1123 TSAN_INTERCEPTOR(int, __xstat64
, int version
, const char *path
, void *buf
) {
1124 SCOPED_TSAN_INTERCEPTOR(__xstat64
, version
, path
, buf
);
1125 return REAL(__xstat64
)(version
, path
, buf
);
1128 TSAN_INTERCEPTOR(int, stat64
, const char *path
, void *buf
) {
1129 SCOPED_TSAN_INTERCEPTOR(__xstat64
, 0, path
, buf
);
1130 return REAL(__xstat64
)(0, path
, buf
);
1133 TSAN_INTERCEPTOR(int, __lxstat
, int version
, const char *path
, void *buf
) {
1134 SCOPED_TSAN_INTERCEPTOR(__lxstat
, version
, path
, buf
);
1135 return REAL(__lxstat
)(version
, path
, buf
);
1138 TSAN_INTERCEPTOR(int, lstat
, const char *path
, void *buf
) {
1139 SCOPED_TSAN_INTERCEPTOR(__lxstat
, 0, path
, buf
);
1140 return REAL(__lxstat
)(0, path
, buf
);
1143 TSAN_INTERCEPTOR(int, __lxstat64
, int version
, const char *path
, void *buf
) {
1144 SCOPED_TSAN_INTERCEPTOR(__lxstat64
, version
, path
, buf
);
1145 return REAL(__lxstat64
)(version
, path
, buf
);
1148 TSAN_INTERCEPTOR(int, lstat64
, const char *path
, void *buf
) {
1149 SCOPED_TSAN_INTERCEPTOR(__lxstat64
, 0, path
, buf
);
1150 return REAL(__lxstat64
)(0, path
, buf
);
1153 TSAN_INTERCEPTOR(int, __fxstat
, int version
, int fd
, void *buf
) {
1154 SCOPED_TSAN_INTERCEPTOR(__fxstat
, version
, fd
, buf
);
1156 FdAccess(thr
, pc
, fd
);
1157 return REAL(__fxstat
)(version
, fd
, buf
);
1160 TSAN_INTERCEPTOR(int, fstat
, int fd
, void *buf
) {
1161 SCOPED_TSAN_INTERCEPTOR(__fxstat
, 0, fd
, buf
);
1163 FdAccess(thr
, pc
, fd
);
1164 return REAL(__fxstat
)(0, fd
, buf
);
1167 TSAN_INTERCEPTOR(int, __fxstat64
, int version
, int fd
, void *buf
) {
1168 SCOPED_TSAN_INTERCEPTOR(__fxstat64
, version
, fd
, buf
);
1170 FdAccess(thr
, pc
, fd
);
1171 return REAL(__fxstat64
)(version
, fd
, buf
);
1174 TSAN_INTERCEPTOR(int, fstat64
, int fd
, void *buf
) {
1175 SCOPED_TSAN_INTERCEPTOR(__fxstat64
, 0, fd
, buf
);
1177 FdAccess(thr
, pc
, fd
);
1178 return REAL(__fxstat64
)(0, fd
, buf
);
1181 TSAN_INTERCEPTOR(int, open
, const char *name
, int flags
, int mode
) {
1182 SCOPED_TSAN_INTERCEPTOR(open
, name
, flags
, mode
);
1183 int fd
= REAL(open
)(name
, flags
, mode
);
1185 FdFileCreate(thr
, pc
, fd
);
1189 TSAN_INTERCEPTOR(int, open64
, const char *name
, int flags
, int mode
) {
1190 SCOPED_TSAN_INTERCEPTOR(open64
, name
, flags
, mode
);
1191 int fd
= REAL(open64
)(name
, flags
, mode
);
1193 FdFileCreate(thr
, pc
, fd
);
1197 TSAN_INTERCEPTOR(int, creat
, const char *name
, int mode
) {
1198 SCOPED_TSAN_INTERCEPTOR(creat
, name
, mode
);
1199 int fd
= REAL(creat
)(name
, mode
);
1201 FdFileCreate(thr
, pc
, fd
);
1205 TSAN_INTERCEPTOR(int, creat64
, const char *name
, int mode
) {
1206 SCOPED_TSAN_INTERCEPTOR(creat64
, name
, mode
);
1207 int fd
= REAL(creat64
)(name
, mode
);
1209 FdFileCreate(thr
, pc
, fd
);
1213 TSAN_INTERCEPTOR(int, dup
, int oldfd
) {
1214 SCOPED_TSAN_INTERCEPTOR(dup
, oldfd
);
1215 int newfd
= REAL(dup
)(oldfd
);
1216 if (oldfd
>= 0 && newfd
>= 0 && newfd
!= oldfd
)
1217 FdDup(thr
, pc
, oldfd
, newfd
);
1221 TSAN_INTERCEPTOR(int, dup2
, int oldfd
, int newfd
) {
1222 SCOPED_TSAN_INTERCEPTOR(dup2
, oldfd
, newfd
);
1223 int newfd2
= REAL(dup2
)(oldfd
, newfd
);
1224 if (oldfd
>= 0 && newfd2
>= 0 && newfd2
!= oldfd
)
1225 FdDup(thr
, pc
, oldfd
, newfd2
);
1229 TSAN_INTERCEPTOR(int, dup3
, int oldfd
, int newfd
, int flags
) {
1230 SCOPED_TSAN_INTERCEPTOR(dup3
, oldfd
, newfd
, flags
);
1231 int newfd2
= REAL(dup3
)(oldfd
, newfd
, flags
);
1232 if (oldfd
>= 0 && newfd2
>= 0 && newfd2
!= oldfd
)
1233 FdDup(thr
, pc
, oldfd
, newfd2
);
1237 TSAN_INTERCEPTOR(int, eventfd
, unsigned initval
, int flags
) {
1238 SCOPED_TSAN_INTERCEPTOR(eventfd
, initval
, flags
);
1239 int fd
= REAL(eventfd
)(initval
, flags
);
1241 FdEventCreate(thr
, pc
, fd
);
1245 TSAN_INTERCEPTOR(int, signalfd
, int fd
, void *mask
, int flags
) {
1246 SCOPED_TSAN_INTERCEPTOR(signalfd
, fd
, mask
, flags
);
1248 FdClose(thr
, pc
, fd
);
1249 fd
= REAL(signalfd
)(fd
, mask
, flags
);
1251 FdSignalCreate(thr
, pc
, fd
);
1255 TSAN_INTERCEPTOR(int, inotify_init
, int fake
) {
1256 SCOPED_TSAN_INTERCEPTOR(inotify_init
, fake
);
1257 int fd
= REAL(inotify_init
)(fake
);
1259 FdInotifyCreate(thr
, pc
, fd
);
1263 TSAN_INTERCEPTOR(int, inotify_init1
, int flags
) {
1264 SCOPED_TSAN_INTERCEPTOR(inotify_init1
, flags
);
1265 int fd
= REAL(inotify_init1
)(flags
);
1267 FdInotifyCreate(thr
, pc
, fd
);
1271 TSAN_INTERCEPTOR(int, socket
, int domain
, int type
, int protocol
) {
1272 SCOPED_TSAN_INTERCEPTOR(socket
, domain
, type
, protocol
);
1273 int fd
= REAL(socket
)(domain
, type
, protocol
);
1275 FdSocketCreate(thr
, pc
, fd
);
1279 TSAN_INTERCEPTOR(int, socketpair
, int domain
, int type
, int protocol
, int *fd
) {
1280 SCOPED_TSAN_INTERCEPTOR(socketpair
, domain
, type
, protocol
, fd
);
1281 int res
= REAL(socketpair
)(domain
, type
, protocol
, fd
);
1282 if (res
== 0 && fd
[0] >= 0 && fd
[1] >= 0)
1283 FdPipeCreate(thr
, pc
, fd
[0], fd
[1]);
1287 TSAN_INTERCEPTOR(int, connect
, int fd
, void *addr
, unsigned addrlen
) {
1288 SCOPED_TSAN_INTERCEPTOR(connect
, fd
, addr
, addrlen
);
1289 FdSocketConnecting(thr
, pc
, fd
);
1290 int res
= REAL(connect
)(fd
, addr
, addrlen
);
1291 if (res
== 0 && fd
>= 0)
1292 FdSocketConnect(thr
, pc
, fd
);
1296 TSAN_INTERCEPTOR(int, bind
, int fd
, void *addr
, unsigned addrlen
) {
1297 SCOPED_TSAN_INTERCEPTOR(bind
, fd
, addr
, addrlen
);
1298 int res
= REAL(bind
)(fd
, addr
, addrlen
);
1299 if (fd
> 0 && res
== 0)
1300 FdAccess(thr
, pc
, fd
);
1304 TSAN_INTERCEPTOR(int, listen
, int fd
, int backlog
) {
1305 SCOPED_TSAN_INTERCEPTOR(listen
, fd
, backlog
);
1306 int res
= REAL(listen
)(fd
, backlog
);
1307 if (fd
> 0 && res
== 0)
1308 FdAccess(thr
, pc
, fd
);
1312 TSAN_INTERCEPTOR(int, accept
, int fd
, void *addr
, unsigned *addrlen
) {
1313 SCOPED_TSAN_INTERCEPTOR(accept
, fd
, addr
, addrlen
);
1314 int fd2
= REAL(accept
)(fd
, addr
, addrlen
);
1315 if (fd
>= 0 && fd2
>= 0)
1316 FdSocketAccept(thr
, pc
, fd
, fd2
);
1320 TSAN_INTERCEPTOR(int, accept4
, int fd
, void *addr
, unsigned *addrlen
, int f
) {
1321 SCOPED_TSAN_INTERCEPTOR(accept4
, fd
, addr
, addrlen
, f
);
1322 int fd2
= REAL(accept4
)(fd
, addr
, addrlen
, f
);
1323 if (fd
>= 0 && fd2
>= 0)
1324 FdSocketAccept(thr
, pc
, fd
, fd2
);
1328 TSAN_INTERCEPTOR(int, epoll_create
, int size
) {
1329 SCOPED_TSAN_INTERCEPTOR(epoll_create
, size
);
1330 int fd
= REAL(epoll_create
)(size
);
1332 FdPollCreate(thr
, pc
, fd
);
1336 TSAN_INTERCEPTOR(int, epoll_create1
, int flags
) {
1337 SCOPED_TSAN_INTERCEPTOR(epoll_create1
, flags
);
1338 int fd
= REAL(epoll_create1
)(flags
);
1340 FdPollCreate(thr
, pc
, fd
);
1344 TSAN_INTERCEPTOR(int, close
, int fd
) {
1345 SCOPED_TSAN_INTERCEPTOR(close
, fd
);
1347 FdClose(thr
, pc
, fd
);
1348 return REAL(close
)(fd
);
1351 TSAN_INTERCEPTOR(int, __close
, int fd
) {
1352 SCOPED_TSAN_INTERCEPTOR(__close
, fd
);
1354 FdClose(thr
, pc
, fd
);
1355 return REAL(__close
)(fd
);
1359 TSAN_INTERCEPTOR(void, __res_iclose
, void *state
, bool free_addr
) {
1360 SCOPED_TSAN_INTERCEPTOR(__res_iclose
, state
, free_addr
);
1362 int cnt
= ExtractResolvFDs(state
, fds
, ARRAY_SIZE(fds
));
1363 for (int i
= 0; i
< cnt
; i
++) {
1365 FdClose(thr
, pc
, fds
[i
]);
1367 REAL(__res_iclose
)(state
, free_addr
);
1370 TSAN_INTERCEPTOR(int, pipe
, int *pipefd
) {
1371 SCOPED_TSAN_INTERCEPTOR(pipe
, pipefd
);
1372 int res
= REAL(pipe
)(pipefd
);
1373 if (res
== 0 && pipefd
[0] >= 0 && pipefd
[1] >= 0)
1374 FdPipeCreate(thr
, pc
, pipefd
[0], pipefd
[1]);
1378 TSAN_INTERCEPTOR(int, pipe2
, int *pipefd
, int flags
) {
1379 SCOPED_TSAN_INTERCEPTOR(pipe2
, pipefd
, flags
);
1380 int res
= REAL(pipe2
)(pipefd
, flags
);
1381 if (res
== 0 && pipefd
[0] >= 0 && pipefd
[1] >= 0)
1382 FdPipeCreate(thr
, pc
, pipefd
[0], pipefd
[1]);
1386 TSAN_INTERCEPTOR(long_t
, readv
, int fd
, void *vec
, int cnt
) {
1387 SCOPED_TSAN_INTERCEPTOR(readv
, fd
, vec
, cnt
);
1388 int res
= REAL(readv
)(fd
, vec
, cnt
);
1389 if (res
>= 0 && fd
>= 0) {
1390 FdAcquire(thr
, pc
, fd
);
1395 TSAN_INTERCEPTOR(long_t
, preadv64
, int fd
, void *vec
, int cnt
, u64 off
) {
1396 SCOPED_TSAN_INTERCEPTOR(preadv64
, fd
, vec
, cnt
, off
);
1397 int res
= REAL(preadv64
)(fd
, vec
, cnt
, off
);
1398 if (res
>= 0 && fd
>= 0) {
1399 FdAcquire(thr
, pc
, fd
);
1404 TSAN_INTERCEPTOR(long_t
, writev
, int fd
, void *vec
, int cnt
) {
1405 SCOPED_TSAN_INTERCEPTOR(writev
, fd
, vec
, cnt
);
1407 FdRelease(thr
, pc
, fd
);
1408 int res
= REAL(writev
)(fd
, vec
, cnt
);
1412 TSAN_INTERCEPTOR(long_t
, pwritev64
, int fd
, void *vec
, int cnt
, u64 off
) {
1413 SCOPED_TSAN_INTERCEPTOR(pwritev64
, fd
, vec
, cnt
, off
);
1415 FdRelease(thr
, pc
, fd
);
1416 int res
= REAL(pwritev64
)(fd
, vec
, cnt
, off
);
1420 TSAN_INTERCEPTOR(long_t
, send
, int fd
, void *buf
, long_t len
, int flags
) {
1421 SCOPED_TSAN_INTERCEPTOR(send
, fd
, buf
, len
, flags
);
1423 FdRelease(thr
, pc
, fd
);
1424 int res
= REAL(send
)(fd
, buf
, len
, flags
);
1428 TSAN_INTERCEPTOR(long_t
, sendmsg
, int fd
, void *msg
, int flags
) {
1429 SCOPED_TSAN_INTERCEPTOR(sendmsg
, fd
, msg
, flags
);
1431 FdRelease(thr
, pc
, fd
);
1432 int res
= REAL(sendmsg
)(fd
, msg
, flags
);
1436 TSAN_INTERCEPTOR(long_t
, recv
, int fd
, void *buf
, long_t len
, int flags
) {
1437 SCOPED_TSAN_INTERCEPTOR(recv
, fd
, buf
, len
, flags
);
1438 int res
= REAL(recv
)(fd
, buf
, len
, flags
);
1439 if (res
>= 0 && fd
>= 0) {
1440 FdAcquire(thr
, pc
, fd
);
1445 TSAN_INTERCEPTOR(long_t
, recvmsg
, int fd
, void *msg
, int flags
) {
1446 SCOPED_TSAN_INTERCEPTOR(recvmsg
, fd
, msg
, flags
);
1447 int res
= REAL(recvmsg
)(fd
, msg
, flags
);
1448 if (res
>= 0 && fd
>= 0) {
1449 FdAcquire(thr
, pc
, fd
);
1454 TSAN_INTERCEPTOR(int, unlink
, char *path
) {
1455 SCOPED_TSAN_INTERCEPTOR(unlink
, path
);
1456 Release(thr
, pc
, File2addr(path
));
1457 int res
= REAL(unlink
)(path
);
1461 TSAN_INTERCEPTOR(void*, fopen
, char *path
, char *mode
) {
1462 SCOPED_TSAN_INTERCEPTOR(fopen
, path
, mode
);
1463 void *res
= REAL(fopen
)(path
, mode
);
1464 Acquire(thr
, pc
, File2addr(path
));
1466 int fd
= fileno_unlocked(res
);
1468 FdFileCreate(thr
, pc
, fd
);
1473 TSAN_INTERCEPTOR(void*, freopen
, char *path
, char *mode
, void *stream
) {
1474 SCOPED_TSAN_INTERCEPTOR(freopen
, path
, mode
, stream
);
1476 int fd
= fileno_unlocked(stream
);
1478 FdClose(thr
, pc
, fd
);
1480 void *res
= REAL(freopen
)(path
, mode
, stream
);
1481 Acquire(thr
, pc
, File2addr(path
));
1483 int fd
= fileno_unlocked(res
);
1485 FdFileCreate(thr
, pc
, fd
);
1490 TSAN_INTERCEPTOR(int, fclose
, void *stream
) {
1492 SCOPED_TSAN_INTERCEPTOR(fclose
, stream
);
1494 int fd
= fileno_unlocked(stream
);
1496 FdClose(thr
, pc
, fd
);
1499 return REAL(fclose
)(stream
);
1502 TSAN_INTERCEPTOR(uptr
, fread
, void *ptr
, uptr size
, uptr nmemb
, void *f
) {
1504 SCOPED_TSAN_INTERCEPTOR(fread
, ptr
, size
, nmemb
, f
);
1505 MemoryAccessRange(thr
, pc
, (uptr
)ptr
, size
* nmemb
, true);
1507 return REAL(fread
)(ptr
, size
, nmemb
, f
);
1510 TSAN_INTERCEPTOR(uptr
, fwrite
, const void *p
, uptr size
, uptr nmemb
, void *f
) {
1512 SCOPED_TSAN_INTERCEPTOR(fwrite
, p
, size
, nmemb
, f
);
1513 MemoryAccessRange(thr
, pc
, (uptr
)p
, size
* nmemb
, false);
1515 return REAL(fwrite
)(p
, size
, nmemb
, f
);
1518 TSAN_INTERCEPTOR(int, puts
, const char *s
) {
1519 SCOPED_TSAN_INTERCEPTOR(puts
, s
);
1520 MemoryAccessRange(thr
, pc
, (uptr
)s
, internal_strlen(s
), false);
1521 return REAL(puts
)(s
);
1524 TSAN_INTERCEPTOR(int, rmdir
, char *path
) {
1525 SCOPED_TSAN_INTERCEPTOR(rmdir
, path
);
1526 Release(thr
, pc
, Dir2addr(path
));
1527 int res
= REAL(rmdir
)(path
);
1531 TSAN_INTERCEPTOR(void*, opendir
, char *path
) {
1532 SCOPED_TSAN_INTERCEPTOR(opendir
, path
);
1533 void *res
= REAL(opendir
)(path
);
1535 Acquire(thr
, pc
, Dir2addr(path
));
1539 TSAN_INTERCEPTOR(int, epoll_ctl
, int epfd
, int op
, int fd
, void *ev
) {
1540 SCOPED_TSAN_INTERCEPTOR(epoll_ctl
, epfd
, op
, fd
, ev
);
1541 if (op
== EPOLL_CTL_ADD
&& epfd
>= 0) {
1542 FdRelease(thr
, pc
, epfd
);
1544 int res
= REAL(epoll_ctl
)(epfd
, op
, fd
, ev
);
1546 FdAccess(thr
, pc
, fd
);
1550 TSAN_INTERCEPTOR(int, epoll_wait
, int epfd
, void *ev
, int cnt
, int timeout
) {
1551 SCOPED_TSAN_INTERCEPTOR(epoll_wait
, epfd
, ev
, cnt
, timeout
);
1552 int res
= BLOCK_REAL(epoll_wait
)(epfd
, ev
, cnt
, timeout
);
1553 if (res
> 0 && epfd
>= 0) {
1554 FdAcquire(thr
, pc
, epfd
);
1559 TSAN_INTERCEPTOR(int, poll
, void *fds
, long_t nfds
, int timeout
) {
1560 SCOPED_TSAN_INTERCEPTOR(poll
, fds
, nfds
, timeout
);
1561 int res
= BLOCK_REAL(poll
)(fds
, nfds
, timeout
);
1565 static void ALWAYS_INLINE
rtl_generic_sighandler(bool sigact
, int sig
,
1566 my_siginfo_t
*info
, void *ctx
) {
1567 ThreadState
*thr
= cur_thread();
1568 SignalContext
*sctx
= SigCtx(thr
);
1569 // Don't mess with synchronous signals.
1570 if (sig
== SIGSEGV
|| sig
== SIGBUS
|| sig
== SIGILL
||
1571 sig
== SIGABRT
|| sig
== SIGFPE
|| sig
== SIGPIPE
||
1572 // If we are sending signal to ourselves, we must process it now.
1573 (sctx
&& sig
== sctx
->int_signal_send
) ||
1574 // If we are in blocking function, we can safely process it now
1575 // (but check if we are in a recursive interceptor,
1576 // i.e. pthread_join()->munmap()).
1577 (sctx
&& sctx
->in_blocking_func
== 1 && thr
->in_rtl
== 1)) {
1578 CHECK(thr
->in_rtl
== 0 || thr
->in_rtl
== 1);
1579 int in_rtl
= thr
->in_rtl
;
1581 CHECK_EQ(thr
->in_signal_handler
, false);
1582 thr
->in_signal_handler
= true;
1584 sigactions
[sig
].sa_sigaction(sig
, info
, ctx
);
1586 sigactions
[sig
].sa_handler(sig
);
1587 CHECK_EQ(thr
->in_signal_handler
, true);
1588 thr
->in_signal_handler
= false;
1589 thr
->in_rtl
= in_rtl
;
1595 SignalDesc
*signal
= &sctx
->pending_signals
[sig
];
1596 if (signal
->armed
== false) {
1597 signal
->armed
= true;
1598 signal
->sigaction
= sigact
;
1600 internal_memcpy(&signal
->siginfo
, info
, sizeof(*info
));
1602 internal_memcpy(&signal
->ctx
, ctx
, sizeof(signal
->ctx
));
1603 sctx
->pending_signal_count
++;
1607 static void rtl_sighandler(int sig
) {
1608 rtl_generic_sighandler(false, sig
, 0, 0);
1611 static void rtl_sigaction(int sig
, my_siginfo_t
*info
, void *ctx
) {
1612 rtl_generic_sighandler(true, sig
, info
, ctx
);
1615 TSAN_INTERCEPTOR(int, sigaction
, int sig
, sigaction_t
*act
, sigaction_t
*old
) {
1616 SCOPED_TSAN_INTERCEPTOR(sigaction
, sig
, act
, old
);
1618 internal_memcpy(old
, &sigactions
[sig
], sizeof(*old
));
1621 internal_memcpy(&sigactions
[sig
], act
, sizeof(*act
));
1623 internal_memcpy(&newact
, act
, sizeof(newact
));
1624 sigfillset(&newact
.sa_mask
);
1625 if (act
->sa_handler
!= SIG_IGN
&& act
->sa_handler
!= SIG_DFL
) {
1626 if (newact
.sa_flags
& SA_SIGINFO
)
1627 newact
.sa_sigaction
= rtl_sigaction
;
1629 newact
.sa_handler
= rtl_sighandler
;
1631 int res
= REAL(sigaction
)(sig
, &newact
, 0);
1635 TSAN_INTERCEPTOR(sighandler_t
, signal
, int sig
, sighandler_t h
) {
1638 REAL(memset
)(&act
.sa_mask
, -1, sizeof(act
.sa_mask
));
1641 int res
= sigaction(sig
, &act
, &old
);
1644 return old
.sa_handler
;
1647 TSAN_INTERCEPTOR(int, raise
, int sig
) {
1648 SCOPED_TSAN_INTERCEPTOR(raise
, sig
);
1649 SignalContext
*sctx
= SigCtx(thr
);
1651 int prev
= sctx
->int_signal_send
;
1652 sctx
->int_signal_send
= sig
;
1653 int res
= REAL(raise
)(sig
);
1654 CHECK_EQ(sctx
->int_signal_send
, sig
);
1655 sctx
->int_signal_send
= prev
;
1659 TSAN_INTERCEPTOR(int, kill
, int pid
, int sig
) {
1660 SCOPED_TSAN_INTERCEPTOR(kill
, pid
, sig
);
1661 SignalContext
*sctx
= SigCtx(thr
);
1663 int prev
= sctx
->int_signal_send
;
1664 if (pid
== GetPid()) {
1665 sctx
->int_signal_send
= sig
;
1667 int res
= REAL(kill
)(pid
, sig
);
1668 if (pid
== GetPid()) {
1669 CHECK_EQ(sctx
->int_signal_send
, sig
);
1670 sctx
->int_signal_send
= prev
;
1675 TSAN_INTERCEPTOR(int, pthread_kill
, void *tid
, int sig
) {
1676 SCOPED_TSAN_INTERCEPTOR(pthread_kill
, tid
, sig
);
1677 SignalContext
*sctx
= SigCtx(thr
);
1679 int prev
= sctx
->int_signal_send
;
1680 if (tid
== pthread_self()) {
1681 sctx
->int_signal_send
= sig
;
1683 int res
= REAL(pthread_kill
)(tid
, sig
);
1684 if (tid
== pthread_self()) {
1685 CHECK_EQ(sctx
->int_signal_send
, sig
);
1686 sctx
->int_signal_send
= prev
;
1691 TSAN_INTERCEPTOR(int, gettimeofday
, void *tv
, void *tz
) {
1692 SCOPED_TSAN_INTERCEPTOR(gettimeofday
, tv
, tz
);
1693 // It's intercepted merely to process pending signals.
1694 return REAL(gettimeofday
)(tv
, tz
);
1697 // Linux kernel has a bug that leads to kernel deadlock if a process
1698 // maps TBs of memory and then calls mlock().
1699 static void MlockIsUnsupported() {
1700 static atomic_uint8_t printed
;
1701 if (atomic_exchange(&printed
, 1, memory_order_relaxed
))
1703 Printf("INFO: ThreadSanitizer ignores mlock/mlockall/munlock/munlockall\n");
1706 TSAN_INTERCEPTOR(int, mlock
, const void *addr
, uptr len
) {
1707 MlockIsUnsupported();
1711 TSAN_INTERCEPTOR(int, munlock
, const void *addr
, uptr len
) {
1712 MlockIsUnsupported();
1716 TSAN_INTERCEPTOR(int, mlockall
, int flags
) {
1717 MlockIsUnsupported();
1721 TSAN_INTERCEPTOR(int, munlockall
, void) {
1722 MlockIsUnsupported();
1726 TSAN_INTERCEPTOR(int, fork
, int fake
) {
1727 SCOPED_TSAN_INTERCEPTOR(fork
, fake
);
1728 // It's intercepted merely to process pending signals.
1729 int pid
= REAL(fork
)(fake
);
1733 } else if (pid
> 0) {
1739 struct TsanInterceptorContext
{
1741 const uptr caller_pc
;
1745 #define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
1746 MemoryAccessRange(((TsanInterceptorContext*)ctx)->thr, \
1747 ((TsanInterceptorContext*)ctx)->pc, \
1748 (uptr)ptr, size, true)
1749 #define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \
1750 MemoryAccessRange(((TsanInterceptorContext*)ctx)->thr, \
1751 ((TsanInterceptorContext*)ctx)->pc, \
1752 (uptr)ptr, size, false)
1753 #define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \
1754 SCOPED_TSAN_INTERCEPTOR(func, __VA_ARGS__) \
1755 TsanInterceptorContext _ctx = {thr, caller_pc, pc}; \
1756 ctx = (void*)&_ctx; \
1758 #define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \
1759 FdAcquire(((TsanInterceptorContext*)ctx)->thr, pc, fd)
1760 #define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \
1761 FdRelease(((TsanInterceptorContext*)ctx)->thr, pc, fd)
1762 #define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) \
1763 ThreadSetName(((TsanInterceptorContext*)ctx)->thr, name)
1764 #include "sanitizer_common/sanitizer_common_interceptors.inc"
1768 void ProcessPendingSignals(ThreadState
*thr
) {
1769 CHECK_EQ(thr
->in_rtl
, 0);
1770 SignalContext
*sctx
= SigCtx(thr
);
1771 if (sctx
== 0 || sctx
->pending_signal_count
== 0 || thr
->in_signal_handler
)
1773 Context
*ctx
= CTX();
1774 thr
->in_signal_handler
= true;
1775 sctx
->pending_signal_count
= 0;
1776 // These are too big for stack.
1777 static THREADLOCAL sigset_t emptyset
, oldset
;
1778 sigfillset(&emptyset
);
1779 pthread_sigmask(SIG_SETMASK
, &emptyset
, &oldset
);
1780 for (int sig
= 0; sig
< kSigCount
; sig
++) {
1781 SignalDesc
*signal
= &sctx
->pending_signals
[sig
];
1782 if (signal
->armed
) {
1783 signal
->armed
= false;
1784 if (sigactions
[sig
].sa_handler
!= SIG_DFL
1785 && sigactions
[sig
].sa_handler
!= SIG_IGN
) {
1786 // Insure that the handler does not spoil errno.
1787 const int saved_errno
= errno
;
1789 if (signal
->sigaction
)
1790 sigactions
[sig
].sa_sigaction(sig
, &signal
->siginfo
, &signal
->ctx
);
1792 sigactions
[sig
].sa_handler(sig
);
1793 if (flags()->report_bugs
&& errno
!= 0) {
1795 __tsan::StackTrace stack
;
1796 uptr pc
= signal
->sigaction
?
1797 (uptr
)sigactions
[sig
].sa_sigaction
:
1798 (uptr
)sigactions
[sig
].sa_handler
;
1800 Lock
l(&ctx
->thread_mtx
);
1801 ScopedReport
rep(ReportTypeErrnoInSignal
);
1802 if (!IsFiredSuppression(ctx
, rep
, stack
)) {
1803 rep
.AddStack(&stack
);
1804 OutputReport(ctx
, rep
, rep
.GetReport()->stacks
[0]);
1807 errno
= saved_errno
;
1811 pthread_sigmask(SIG_SETMASK
, &oldset
, 0);
1812 CHECK_EQ(thr
->in_signal_handler
, true);
1813 thr
->in_signal_handler
= false;
1816 static void unreachable() {
1817 Printf("FATAL: ThreadSanitizer: unreachable called\n");
1821 void InitializeInterceptors() {
1822 CHECK_GT(cur_thread()->in_rtl
, 0);
1824 // We need to setup it early, because functions like dlsym() can call it.
1825 REAL(memset
) = internal_memset
;
1826 REAL(memcpy
) = internal_memcpy
;
1827 REAL(memcmp
) = internal_memcmp
;
1829 SANITIZER_COMMON_INTERCEPTORS_INIT
;
1831 TSAN_INTERCEPT(longjmp
);
1832 TSAN_INTERCEPT(siglongjmp
);
1834 TSAN_INTERCEPT(malloc
);
1835 TSAN_INTERCEPT(__libc_memalign
);
1836 TSAN_INTERCEPT(calloc
);
1837 TSAN_INTERCEPT(realloc
);
1838 TSAN_INTERCEPT(free
);
1839 TSAN_INTERCEPT(cfree
);
1840 TSAN_INTERCEPT(mmap
);
1841 TSAN_INTERCEPT(mmap64
);
1842 TSAN_INTERCEPT(munmap
);
1843 TSAN_INTERCEPT(memalign
);
1844 TSAN_INTERCEPT(valloc
);
1845 TSAN_INTERCEPT(pvalloc
);
1846 TSAN_INTERCEPT(posix_memalign
);
1848 TSAN_INTERCEPT(strlen
);
1849 TSAN_INTERCEPT(memset
);
1850 TSAN_INTERCEPT(memcpy
);
1851 TSAN_INTERCEPT(strcmp
);
1852 TSAN_INTERCEPT(memchr
);
1853 TSAN_INTERCEPT(memrchr
);
1854 TSAN_INTERCEPT(memmove
);
1855 TSAN_INTERCEPT(memcmp
);
1856 TSAN_INTERCEPT(strchr
);
1857 TSAN_INTERCEPT(strchrnul
);
1858 TSAN_INTERCEPT(strrchr
);
1859 TSAN_INTERCEPT(strncmp
);
1860 TSAN_INTERCEPT(strcpy
); // NOLINT
1861 TSAN_INTERCEPT(strncpy
);
1862 TSAN_INTERCEPT(strstr
);
1864 TSAN_INTERCEPT(pthread_create
);
1865 TSAN_INTERCEPT(pthread_join
);
1866 TSAN_INTERCEPT(pthread_detach
);
1868 TSAN_INTERCEPT(pthread_mutex_init
);
1869 TSAN_INTERCEPT(pthread_mutex_destroy
);
1870 TSAN_INTERCEPT(pthread_mutex_lock
);
1871 TSAN_INTERCEPT(pthread_mutex_trylock
);
1872 TSAN_INTERCEPT(pthread_mutex_timedlock
);
1873 TSAN_INTERCEPT(pthread_mutex_unlock
);
1875 TSAN_INTERCEPT(pthread_spin_init
);
1876 TSAN_INTERCEPT(pthread_spin_destroy
);
1877 TSAN_INTERCEPT(pthread_spin_lock
);
1878 TSAN_INTERCEPT(pthread_spin_trylock
);
1879 TSAN_INTERCEPT(pthread_spin_unlock
);
1881 TSAN_INTERCEPT(pthread_rwlock_init
);
1882 TSAN_INTERCEPT(pthread_rwlock_destroy
);
1883 TSAN_INTERCEPT(pthread_rwlock_rdlock
);
1884 TSAN_INTERCEPT(pthread_rwlock_tryrdlock
);
1885 TSAN_INTERCEPT(pthread_rwlock_timedrdlock
);
1886 TSAN_INTERCEPT(pthread_rwlock_wrlock
);
1887 TSAN_INTERCEPT(pthread_rwlock_trywrlock
);
1888 TSAN_INTERCEPT(pthread_rwlock_timedwrlock
);
1889 TSAN_INTERCEPT(pthread_rwlock_unlock
);
1891 // TSAN_INTERCEPT(pthread_cond_init);
1892 TSAN_INTERCEPT(pthread_cond_destroy
);
1893 TSAN_INTERCEPT(pthread_cond_signal
);
1894 TSAN_INTERCEPT(pthread_cond_broadcast
);
1895 TSAN_INTERCEPT(pthread_cond_wait
);
1896 TSAN_INTERCEPT(pthread_cond_timedwait
);
1898 TSAN_INTERCEPT(pthread_barrier_init
);
1899 TSAN_INTERCEPT(pthread_barrier_destroy
);
1900 TSAN_INTERCEPT(pthread_barrier_wait
);
1902 TSAN_INTERCEPT(pthread_once
);
1904 TSAN_INTERCEPT(sem_init
);
1905 TSAN_INTERCEPT(sem_destroy
);
1906 TSAN_INTERCEPT(sem_wait
);
1907 TSAN_INTERCEPT(sem_trywait
);
1908 TSAN_INTERCEPT(sem_timedwait
);
1909 TSAN_INTERCEPT(sem_post
);
1910 TSAN_INTERCEPT(sem_getvalue
);
1912 TSAN_INTERCEPT(stat
);
1913 TSAN_INTERCEPT(__xstat
);
1914 TSAN_INTERCEPT(stat64
);
1915 TSAN_INTERCEPT(__xstat64
);
1916 TSAN_INTERCEPT(lstat
);
1917 TSAN_INTERCEPT(__lxstat
);
1918 TSAN_INTERCEPT(lstat64
);
1919 TSAN_INTERCEPT(__lxstat64
);
1920 TSAN_INTERCEPT(fstat
);
1921 TSAN_INTERCEPT(__fxstat
);
1922 TSAN_INTERCEPT(fstat64
);
1923 TSAN_INTERCEPT(__fxstat64
);
1924 TSAN_INTERCEPT(open
);
1925 TSAN_INTERCEPT(open64
);
1926 TSAN_INTERCEPT(creat
);
1927 TSAN_INTERCEPT(creat64
);
1928 TSAN_INTERCEPT(dup
);
1929 TSAN_INTERCEPT(dup2
);
1930 TSAN_INTERCEPT(dup3
);
1931 TSAN_INTERCEPT(eventfd
);
1932 TSAN_INTERCEPT(signalfd
);
1933 TSAN_INTERCEPT(inotify_init
);
1934 TSAN_INTERCEPT(inotify_init1
);
1935 TSAN_INTERCEPT(socket
);
1936 TSAN_INTERCEPT(socketpair
);
1937 TSAN_INTERCEPT(connect
);
1938 TSAN_INTERCEPT(bind
);
1939 TSAN_INTERCEPT(listen
);
1940 TSAN_INTERCEPT(accept
);
1941 TSAN_INTERCEPT(accept4
);
1942 TSAN_INTERCEPT(epoll_create
);
1943 TSAN_INTERCEPT(epoll_create1
);
1944 TSAN_INTERCEPT(close
);
1945 TSAN_INTERCEPT(__close
);
1946 TSAN_INTERCEPT(__res_iclose
);
1947 TSAN_INTERCEPT(pipe
);
1948 TSAN_INTERCEPT(pipe2
);
1950 TSAN_INTERCEPT(readv
);
1951 TSAN_INTERCEPT(preadv64
);
1952 TSAN_INTERCEPT(writev
);
1953 TSAN_INTERCEPT(pwritev64
);
1954 TSAN_INTERCEPT(send
);
1955 TSAN_INTERCEPT(sendmsg
);
1956 TSAN_INTERCEPT(recv
);
1957 TSAN_INTERCEPT(recvmsg
);
1959 TSAN_INTERCEPT(unlink
);
1960 TSAN_INTERCEPT(fopen
);
1961 TSAN_INTERCEPT(freopen
);
1962 TSAN_INTERCEPT(fclose
);
1963 TSAN_INTERCEPT(fread
);
1964 TSAN_INTERCEPT(fwrite
);
1965 TSAN_INTERCEPT(puts
);
1966 TSAN_INTERCEPT(rmdir
);
1967 TSAN_INTERCEPT(opendir
);
1969 TSAN_INTERCEPT(epoll_ctl
);
1970 TSAN_INTERCEPT(epoll_wait
);
1971 TSAN_INTERCEPT(poll
);
1973 TSAN_INTERCEPT(sigaction
);
1974 TSAN_INTERCEPT(signal
);
1975 TSAN_INTERCEPT(raise
);
1976 TSAN_INTERCEPT(kill
);
1977 TSAN_INTERCEPT(pthread_kill
);
1978 TSAN_INTERCEPT(sleep
);
1979 TSAN_INTERCEPT(usleep
);
1980 TSAN_INTERCEPT(nanosleep
);
1981 TSAN_INTERCEPT(gettimeofday
);
1983 TSAN_INTERCEPT(mlock
);
1984 TSAN_INTERCEPT(munlock
);
1985 TSAN_INTERCEPT(mlockall
);
1986 TSAN_INTERCEPT(munlockall
);
1988 TSAN_INTERCEPT(fork
);
1989 TSAN_INTERCEPT(on_exit
);
1990 TSAN_INTERCEPT(__cxa_atexit
);
1992 // Need to setup it, because interceptors check that the function is resolved.
1993 // But atexit is emitted directly into the module, so can't be resolved.
1994 REAL(atexit
) = (int(*)(void(*)()))unreachable
;
1995 atexit_ctx
= new(internal_alloc(MBlockAtExit
, sizeof(AtExitContext
)))
1998 if (REAL(__cxa_atexit
)(&finalize
, 0, 0)) {
1999 Printf("ThreadSanitizer: failed to setup atexit callback\n");
2003 if (pthread_key_create(&g_thread_finalize_key
, &thread_finalize
)) {
2004 Printf("ThreadSanitizer: failed to create thread key\n");
2011 void internal_start_thread(void(*func
)(void *arg
), void *arg
) {
2013 REAL(pthread_create
)(&th
, 0, (void*(*)(void *arg
))func
, arg
);
2014 REAL(pthread_detach
)(th
);
2017 } // namespace __tsan