14f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov//===-- tsan_interceptors.cc ----------------------------------------------===// 27ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// 37ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// The LLVM Compiler Infrastructure 47ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// 57ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// This file is distributed under the University of Illinois Open Source 67ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// License. See LICENSE.TXT for details. 77ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// 87ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany//===----------------------------------------------------------------------===// 97ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// 107ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// This file is a part of ThreadSanitizer (TSan), a race detector. 117ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// 128530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany// FIXME: move as many interceptors as possible into 138530e2b953f0b34ecd267a6aba5f155d5c08c5c8Kostya Serebryany// sanitizer_common/sanitizer_common_interceptors.h 147ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany//===----------------------------------------------------------------------===// 157ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 16fce5bd4cc29fddb5e8f0cb9c12df7c10187a991dDmitry Vyukov#include "sanitizer_common/sanitizer_atomic.h" 17230c3be6cdd094a187f48e27ba0961dbeee70344Alexey Samsonov#include "sanitizer_common/sanitizer_libc.h" 1847a0f6edc48eb6dc46b2e1f203d6783fd7e07505Alexey Samsonov#include "sanitizer_common/sanitizer_platform_limits_posix.h" 1947b1634df012507799eb39aa17d4022d748ba67bAlexey Samsonov#include "sanitizer_common/sanitizer_placement_new.h" 207eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov#include "sanitizer_common/sanitizer_stacktrace.h" 2136decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov#include "interception/interception.h" 227ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#include "tsan_interface.h" 237ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#include "tsan_platform.h" 244f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov#include "tsan_rtl.h" 257ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#include "tsan_mman.h" 26c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov#include "tsan_fd.h" 277ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 287ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyusing namespace __tsan; // NOLINT 297ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 30e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukovconst int kSigCount = 128; 31e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov 32e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukovstruct my_siginfo_t { 33e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov int opaque[128]; 34e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov}; 35e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov 367ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystruct sigset_t { 37e294d09d45aa97d1d2c8ee237ee2ac225442d330Dmitry Vyukov u64 val[1024 / 8 / sizeof(u64)]; 387ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}; 397ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 407ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystruct ucontext_t { 41a5562db12c5331433407ac21602086f34561c25cDmitry Vyukov uptr opaque[117]; 427ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}; 437ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 447ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyextern "C" int pthread_attr_init(void *attr); 457ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyextern "C" int pthread_attr_destroy(void *attr); 467ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyextern "C" int pthread_attr_getdetachstate(void *attr, int *v); 477ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyextern "C" int pthread_attr_setstacksize(void *attr, uptr stacksize); 487ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyextern "C" int pthread_attr_getstacksize(void *attr, uptr *stacksize); 497ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyextern "C" int pthread_key_create(unsigned *key, void (*destructor)(void* v)); 507ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyextern "C" int pthread_setspecific(unsigned key, const void *v); 517ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyextern "C" int pthread_mutexattr_gettype(void *a, int *type); 527ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyextern "C" int pthread_yield(); 537ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyextern "C" int pthread_sigmask(int how, const sigset_t *set, sigset_t *oldset); 547ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyextern "C" int sigfillset(sigset_t *set); 557ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyextern "C" void *pthread_self(); 567ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyextern "C" void _exit(int status); 577ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyextern "C" int *__errno_location(); 58f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukovextern "C" int fileno_unlocked(void *stream); 5931c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukovextern "C" void *__libc_malloc(uptr size); 6031c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukovextern "C" void *__libc_calloc(uptr size, uptr n); 6131c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukovextern "C" void *__libc_realloc(void *ptr, uptr size); 6231c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukovextern "C" void __libc_free(void *ptr); 637ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyconst int PTHREAD_MUTEX_RECURSIVE = 1; 647ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyconst int PTHREAD_MUTEX_RECURSIVE_NP = 1; 657ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyconst int kPthreadAttrSize = 56; 667ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyconst int EINVAL = 22; 677ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyconst int EBUSY = 16; 687ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyconst int EPOLL_CTL_ADD = 1; 69d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukovconst int SIGILL = 4; 70d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukovconst int SIGABRT = 6; 71d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukovconst int SIGFPE = 8; 72d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukovconst int SIGSEGV = 11; 73d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukovconst int SIGPIPE = 13; 74d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukovconst int SIGBUS = 7; 757ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyvoid *const MAP_FAILED = (void*)-1; 767ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyconst int PTHREAD_BARRIER_SERIAL_THREAD = -1; 777ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyconst int MAP_FIXED = 0x10; 787ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanytypedef long long_t; // NOLINT 797ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 800ce948e0887e2c23c6510c32a639da9730bbce25Alexander Potapenko// From /usr/include/unistd.h 810ce948e0887e2c23c6510c32a639da9730bbce25Alexander Potapenko# define F_ULOCK 0 /* Unlock a previously locked region. */ 820ce948e0887e2c23c6510c32a639da9730bbce25Alexander Potapenko# define F_LOCK 1 /* Lock a region for exclusive use. */ 830ce948e0887e2c23c6510c32a639da9730bbce25Alexander Potapenko# define F_TLOCK 2 /* Test and lock a region for exclusive use. */ 840ce948e0887e2c23c6510c32a639da9730bbce25Alexander Potapenko# define F_TEST 3 /* Test a region for other processes locks. */ 850ce948e0887e2c23c6510c32a639da9730bbce25Alexander Potapenko 867ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanytypedef void (*sighandler_t)(int sig); 877ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 887a72b4a0f04f7f043ab86396b0faa552f55aa857Dmitry Vyukov#define errno (*__errno_location()) 897a72b4a0f04f7f043ab86396b0faa552f55aa857Dmitry Vyukov 907ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystruct sigaction_t { 917ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany union { 927ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany sighandler_t sa_handler; 937ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany void (*sa_sigaction)(int sig, my_siginfo_t *siginfo, void *uctx); 947ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany }; 957ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany sigset_t sa_mask; 967ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int sa_flags; 977ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany void (*sa_restorer)(); 987ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}; 997ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 1007ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyconst sighandler_t SIG_DFL = (sighandler_t)0; 1017ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyconst sighandler_t SIG_IGN = (sighandler_t)1; 102d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukovconst sighandler_t SIG_ERR = (sighandler_t)-1; 1037ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyconst int SA_SIGINFO = 4; 1047ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyconst int SIG_SETMASK = 2; 1057ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 1067eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonovnamespace std { 1077eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonovstruct nothrow_t {}; 1087eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov} // namespace std 1097eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov 1107ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic sigaction_t sigactions[kSigCount]; 1117ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 112e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukovnamespace __tsan { 113e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukovstruct SignalDesc { 114e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov bool armed; 115e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov bool sigaction; 116e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov my_siginfo_t siginfo; 117e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov ucontext_t ctx; 118e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov}; 119e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov 120e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukovstruct SignalContext { 121ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov int in_blocking_func; 122e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov int int_signal_send; 123e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov int pending_signal_count; 124e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov SignalDesc pending_signals[kSigCount]; 125e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov}; 126ba5e99668e3030cc5bab357a04271a1bdbac209cAlexey Samsonov} // namespace __tsan 127e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov 128e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukovstatic SignalContext *SigCtx(ThreadState *thr) { 129e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov SignalContext *ctx = (SignalContext*)thr->signal_ctx; 1301fc03d50a87302689482efa24b045a393097b6c3Dmitry Vyukov if (ctx == 0 && thr->is_alive) { 131e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov ScopedInRtl in_rtl; 132c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov ctx = (SignalContext*)MmapOrDie(sizeof(*ctx), "SignalContext"); 133c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov MemoryResetRange(thr, (uptr)&SigCtx, (uptr)ctx, sizeof(*ctx)); 134e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov thr->signal_ctx = ctx; 135e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov } 136e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov return ctx; 137e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov} 138e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov 1397ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic unsigned g_thread_finalize_key; 1407ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 14136decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukovclass ScopedInterceptor { 14236decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov public: 14336decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov ScopedInterceptor(ThreadState *thr, const char *fname, uptr pc); 14436decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov ~ScopedInterceptor(); 14536decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov private: 14636decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov ThreadState *const thr_; 14736decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov const int in_rtl_; 14836decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov}; 14936decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov 1504f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey SamsonovScopedInterceptor::ScopedInterceptor(ThreadState *thr, const char *fname, 1514f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov uptr pc) 1524f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov : thr_(thr) 1534f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov , in_rtl_(thr->in_rtl) { 1544f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov if (thr_->in_rtl == 0) { 1554f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov Initialize(thr); 1564f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov FuncEntry(thr, pc); 1574f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov thr_->in_rtl++; 1584f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov DPrintf("#%d: intercept %s()\n", thr_->tid, fname); 1594f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov } else { 1604f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov thr_->in_rtl++; 1617ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 16205906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov} 16305906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov 1644f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey SamsonovScopedInterceptor::~ScopedInterceptor() { 1654f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov thr_->in_rtl--; 1664f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov if (thr_->in_rtl == 0) { 1674f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov FuncExit(thr_); 168ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov ProcessPendingSignals(thr_); 1694f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov } 1704f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov CHECK_EQ(in_rtl_, thr_->in_rtl); 17105906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov} 17205906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov 17336decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov#define SCOPED_INTERCEPTOR_RAW(func, ...) \ 17436decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov ThreadState *thr = cur_thread(); \ 17536decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov StatInc(thr, StatInterceptor); \ 17636decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov StatInc(thr, StatInt_##func); \ 17736decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov const uptr caller_pc = GET_CALLER_PC(); \ 17836decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov ScopedInterceptor si(thr, #func, caller_pc); \ 179d2f08ffcb97726452f4ba11c199a1e06dc2a7e54Alexey Samsonov const uptr pc = __sanitizer::StackTrace::GetPreviousInstructionPc( \ 180d2f08ffcb97726452f4ba11c199a1e06dc2a7e54Alexey Samsonov __sanitizer::StackTrace::GetCurrentPc()); \ 18136decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov (void)pc; \ 18236decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov/**/ 18336decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov 18436decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov#define SCOPED_TSAN_INTERCEPTOR(func, ...) \ 18536decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov SCOPED_INTERCEPTOR_RAW(func, __VA_ARGS__); \ 18636decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov if (REAL(func) == 0) { \ 18736decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov Printf("FATAL: ThreadSanitizer: failed to intercept %s\n", #func); \ 18836decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov Die(); \ 18936decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov } \ 19036decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov if (thr->in_rtl > 1) \ 19136decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov return REAL(func)(__VA_ARGS__); \ 19236decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov/**/ 19336decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov 19436decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov#define TSAN_INTERCEPTOR(ret, func, ...) INTERCEPTOR(ret, func, __VA_ARGS__) 19536decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov#define TSAN_INTERCEPT(func) INTERCEPT_FUNCTION(func) 19636decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov 197ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov#define BLOCK_REAL(name) (BlockingCall(thr), REAL(name)) 198ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov 199ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukovstruct BlockingCall { 200b717f4d415cafbb8526bb33f737b9c07409a73bbAlexey Samsonov explicit BlockingCall(ThreadState *thr) 201ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov : ctx(SigCtx(thr)) { 202ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov ctx->in_blocking_func++; 203ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov } 204ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov 205ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov ~BlockingCall() { 206ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov ctx->in_blocking_func--; 207ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov } 208ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov 209ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov SignalContext *ctx; 210ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov}; 211ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov 212848531192777acecf79747dc7c1ffeedf5c1da9fDmitry VyukovTSAN_INTERCEPTOR(unsigned, sleep, unsigned sec) { 213848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov SCOPED_TSAN_INTERCEPTOR(sleep, sec); 214ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov unsigned res = BLOCK_REAL(sleep)(sec); 215848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov AfterSleep(thr, pc); 216848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov return res; 217848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov} 218848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov 219848531192777acecf79747dc7c1ffeedf5c1da9fDmitry VyukovTSAN_INTERCEPTOR(int, usleep, long_t usec) { 220848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov SCOPED_TSAN_INTERCEPTOR(usleep, usec); 221ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov int res = BLOCK_REAL(usleep)(usec); 222848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov AfterSleep(thr, pc); 223848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov return res; 224848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov} 225848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov 226848531192777acecf79747dc7c1ffeedf5c1da9fDmitry VyukovTSAN_INTERCEPTOR(int, nanosleep, void *req, void *rem) { 227848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov SCOPED_TSAN_INTERCEPTOR(nanosleep, req, rem); 228ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov int res = BLOCK_REAL(nanosleep)(req, rem); 229848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov AfterSleep(thr, pc); 230848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov return res; 231848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov} 232848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov 2337ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyclass AtExitContext { 2347ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany public: 2357ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany AtExitContext() 2367ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany : mtx_(MutexTypeAtExit, StatMtxAtExit) 2377ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany , pos_() { 2387ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 2397ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 2407ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany typedef void(*atexit_t)(); 2417ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 24231c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov int atexit(ThreadState *thr, uptr pc, bool is_on_exit, 24331c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov atexit_t f, void *arg) { 2447ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany Lock l(&mtx_); 2457ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (pos_ == kMaxAtExit) 2467ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return 1; 2477ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany Release(thr, pc, (uptr)this); 2487ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany stack_[pos_] = f; 24931c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov args_[pos_] = arg; 25031c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov is_on_exits_[pos_] = is_on_exit; 2517ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany pos_++; 2527ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return 0; 2537ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 2547ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 2557ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany void exit(ThreadState *thr, uptr pc) { 2567ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany CHECK_EQ(thr->in_rtl, 0); 2577ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany for (;;) { 2587ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany atexit_t f = 0; 25931c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov void *arg = 0; 26031c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov bool is_on_exit = false; 2617ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany { 2627ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany Lock l(&mtx_); 2637ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (pos_) { 2647ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany pos_--; 2657ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany f = stack_[pos_]; 26631c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov arg = args_[pos_]; 26731c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov is_on_exit = is_on_exits_[pos_]; 2687ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany ScopedInRtl in_rtl; 2697ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany Acquire(thr, pc, (uptr)this); 2707ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 2717ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 2727ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (f == 0) 2737ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany break; 2747ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany DPrintf("#%d: executing atexit func %p\n", thr->tid, f); 2757ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany CHECK_EQ(thr->in_rtl, 0); 27631c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov if (is_on_exit) 27731c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov ((void(*)(int status, void *arg))f)(0, arg); 27831c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov else 27931c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov ((void(*)(void *arg, void *dso))f)(arg, 0); 2807ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 2817ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 2827ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 2837ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany private: 2847ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany static const int kMaxAtExit = 128; 2857ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany Mutex mtx_; 2867ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany atexit_t stack_[kMaxAtExit]; 28731c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov void *args_[kMaxAtExit]; 28831c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov bool is_on_exits_[kMaxAtExit]; 2897ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int pos_; 2907ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}; 2917ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 2927ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic AtExitContext *atexit_ctx; 2937ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 2947ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic void finalize(void *arg) { 2957ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany ThreadState * thr = cur_thread(); 2967ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany uptr pc = 0; 2977ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany atexit_ctx->exit(thr, pc); 2987ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int status = Finalize(cur_thread()); 299b7b6b1cd9df0c954b1f890fcebf373db984923b3Dmitry Vyukov if (status) 300b7b6b1cd9df0c954b1f890fcebf373db984923b3Dmitry Vyukov _exit(status); 3017ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 3027ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 3037ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, atexit, void (*f)()) { 30431c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov if (cur_thread()->in_symbolizer) 30531c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov return 0; 3067ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(atexit, f); 30731c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov return atexit_ctx->atexit(thr, pc, false, (void(*)())f, 0); 30831c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov} 30931c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov 31031c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry VyukovTSAN_INTERCEPTOR(int, on_exit, void(*f)(int, void*), void *arg) { 31131c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov if (cur_thread()->in_symbolizer) 31231c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov return 0; 31331c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(on_exit, f, arg); 31431c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov return atexit_ctx->atexit(thr, pc, true, (void(*)())f, arg); 31531c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov} 31631c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov 31731c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry VyukovTSAN_INTERCEPTOR(int, __cxa_atexit, void (*f)(void *a), void *arg, void *dso) { 31831c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov if (cur_thread()->in_symbolizer) 31931c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov return 0; 32031c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(__cxa_atexit, f, arg, dso); 32131c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov if (dso) 32231c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov return REAL(__cxa_atexit)(f, arg, dso); 32331c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov return atexit_ctx->atexit(thr, pc, false, (void(*)())f, arg); 3247ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 3257ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 326f037f565b2e02878ceb6e7b49647e814e2990ef5Dmitry VyukovTSAN_INTERCEPTOR(void, longjmp, void *env, int val) { 327f037f565b2e02878ceb6e7b49647e814e2990ef5Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(longjmp, env, val); 328b1fe3021eca0843e37878d224ee7f32e32f40d99Alexey Samsonov Printf("ThreadSanitizer: longjmp() is not supported\n"); 329f037f565b2e02878ceb6e7b49647e814e2990ef5Dmitry Vyukov Die(); 330f037f565b2e02878ceb6e7b49647e814e2990ef5Dmitry Vyukov} 331f037f565b2e02878ceb6e7b49647e814e2990ef5Dmitry Vyukov 332f037f565b2e02878ceb6e7b49647e814e2990ef5Dmitry VyukovTSAN_INTERCEPTOR(void, siglongjmp, void *env, int val) { 333f037f565b2e02878ceb6e7b49647e814e2990ef5Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(siglongjmp, env, val); 334b1fe3021eca0843e37878d224ee7f32e32f40d99Alexey Samsonov Printf("ThreadSanitizer: siglongjmp() is not supported\n"); 335f037f565b2e02878ceb6e7b49647e814e2990ef5Dmitry Vyukov Die(); 336f037f565b2e02878ceb6e7b49647e814e2990ef5Dmitry Vyukov} 337f037f565b2e02878ceb6e7b49647e814e2990ef5Dmitry Vyukov 3387ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(void*, malloc, uptr size) { 33931c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov if (cur_thread()->in_symbolizer) 34031c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov return __libc_malloc(size); 34105906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov void *p = 0; 34205906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov { 34305906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov SCOPED_INTERCEPTOR_RAW(malloc, size); 34405906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov p = user_alloc(thr, pc, size); 34505906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov } 34605906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov invoke_malloc_hook(p, size); 34705906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov return p; 3487ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 3497ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 35007ba8ef44deb54baa9307298fbffe25ddb30c362Dmitry VyukovTSAN_INTERCEPTOR(void*, __libc_memalign, uptr align, uptr sz) { 35107ba8ef44deb54baa9307298fbffe25ddb30c362Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(__libc_memalign, align, sz); 352543b94a5cd102c0795b44d78234d5458eed2c75eDmitry Vyukov return user_alloc(thr, pc, sz, align); 35307ba8ef44deb54baa9307298fbffe25ddb30c362Dmitry Vyukov} 35407ba8ef44deb54baa9307298fbffe25ddb30c362Dmitry Vyukov 3557ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(void*, calloc, uptr size, uptr n) { 35631c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov if (cur_thread()->in_symbolizer) 35731c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov return __libc_calloc(size, n); 35865199f1b253c4bfb225805629217acb8f0b1e185Kostya Serebryany if (__sanitizer::CallocShouldReturnNullDueToOverflow(size, n)) return 0; 35905906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov void *p = 0; 36005906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov { 36105906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov SCOPED_INTERCEPTOR_RAW(calloc, size, n); 36205906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov p = user_alloc(thr, pc, n * size); 3630ce948e0887e2c23c6510c32a639da9730bbce25Alexander Potapenko if (p) internal_memset(p, 0, n * size); 36405906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov } 36505906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov invoke_malloc_hook(p, n * size); 3667ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return p; 3677ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 3687ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 3697ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(void*, realloc, void *p, uptr size) { 37031c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov if (cur_thread()->in_symbolizer) 37131c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov return __libc_realloc(p, size); 37205906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov if (p) 37305906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov invoke_free_hook(p); 37405906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov { 37505906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov SCOPED_INTERCEPTOR_RAW(realloc, p, size); 37605906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov p = user_realloc(thr, pc, p, size); 37705906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov } 37805906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov invoke_malloc_hook(p, size); 37905906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov return p; 3807ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 3817ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 3827ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(void, free, void *p) { 3837ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (p == 0) 3847ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return; 38531c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov if (cur_thread()->in_symbolizer) 38631c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov return __libc_free(p); 38705906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov invoke_free_hook(p); 3887ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_INTERCEPTOR_RAW(free, p); 3897ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany user_free(thr, pc, p); 3907ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 3917ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 3927ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(void, cfree, void *p) { 3937ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (p == 0) 3947ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return; 39531c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov if (cur_thread()->in_symbolizer) 39631c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov return __libc_free(p); 39705906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov invoke_free_hook(p); 3987ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_INTERCEPTOR_RAW(cfree, p); 3997ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany user_free(thr, pc, p); 4007ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 4017ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 4028a6b5e551ab8a331f7e7bc4bfcd74926fbffa3f6Alexey SamsonovTSAN_INTERCEPTOR(uptr, malloc_usable_size, void *p) { 4038a6b5e551ab8a331f7e7bc4bfcd74926fbffa3f6Alexey Samsonov SCOPED_INTERCEPTOR_RAW(malloc_usable_size, p); 4048a6b5e551ab8a331f7e7bc4bfcd74926fbffa3f6Alexey Samsonov return user_alloc_usable_size(thr, pc, p); 4058a6b5e551ab8a331f7e7bc4bfcd74926fbffa3f6Alexey Samsonov} 4068a6b5e551ab8a331f7e7bc4bfcd74926fbffa3f6Alexey Samsonov 4077eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov#define OPERATOR_NEW_BODY(mangled_name) \ 40831c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov if (cur_thread()->in_symbolizer) \ 40931c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov return __libc_malloc(size); \ 4107eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov void *p = 0; \ 4117eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov { \ 4127eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov SCOPED_INTERCEPTOR_RAW(mangled_name, size); \ 4137eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov p = user_alloc(thr, pc, size); \ 4147eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov } \ 4157eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov invoke_malloc_hook(p, size); \ 4167eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov return p; 4177eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov 4187eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonovvoid *operator new(__sanitizer::uptr size) { 4197eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov OPERATOR_NEW_BODY(_Znwm); 4207eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov} 4217eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonovvoid *operator new[](__sanitizer::uptr size) { 4227eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov OPERATOR_NEW_BODY(_Znam); 4237eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov} 4247eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonovvoid *operator new(__sanitizer::uptr size, std::nothrow_t const&) { 4257eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov OPERATOR_NEW_BODY(_ZnwmRKSt9nothrow_t); 4267eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov} 4277eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonovvoid *operator new[](__sanitizer::uptr size, std::nothrow_t const&) { 4287eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov OPERATOR_NEW_BODY(_ZnamRKSt9nothrow_t); 4297eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov} 4307eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov 4317eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov#define OPERATOR_DELETE_BODY(mangled_name) \ 4327eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov if (ptr == 0) return; \ 43331c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov if (cur_thread()->in_symbolizer) \ 43431c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov return __libc_free(ptr); \ 4357eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov invoke_free_hook(ptr); \ 4367eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov SCOPED_INTERCEPTOR_RAW(mangled_name, ptr); \ 4377eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov user_free(thr, pc, ptr); 4387eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov 4397eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonovvoid operator delete(void *ptr) { 4407eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov OPERATOR_DELETE_BODY(_ZdlPv); 4417eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov} 4427eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonovvoid operator delete[](void *ptr) { 4437eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov OPERATOR_DELETE_BODY(_ZdlPvRKSt9nothrow_t); 4447eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov} 4457eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonovvoid operator delete(void *ptr, std::nothrow_t const&) { 4467eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov OPERATOR_DELETE_BODY(_ZdaPv); 4477eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov} 4487eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonovvoid operator delete[](void *ptr, std::nothrow_t const&) { 4497eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov OPERATOR_DELETE_BODY(_ZdaPvRKSt9nothrow_t); 4507eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov} 4517eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov 452d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry VyukovTSAN_INTERCEPTOR(uptr, strlen, const char *s) { 4537ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(strlen, s); 454d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov uptr len = internal_strlen(s); 4557ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)s, len + 1, false); 4567ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return len; 4577ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 4587ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 459065c4ac846589d04436cb7f19f938ff42035313eDmitry VyukovTSAN_INTERCEPTOR(void*, memset, void *dst, int v, uptr size) { 460065c4ac846589d04436cb7f19f938ff42035313eDmitry Vyukov SCOPED_TSAN_INTERCEPTOR(memset, dst, v, size); 4617ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)dst, size, true); 462065c4ac846589d04436cb7f19f938ff42035313eDmitry Vyukov return internal_memset(dst, v, size); 4637ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 4647ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 465065c4ac846589d04436cb7f19f938ff42035313eDmitry VyukovTSAN_INTERCEPTOR(void*, memcpy, void *dst, const void *src, uptr size) { 466065c4ac846589d04436cb7f19f938ff42035313eDmitry Vyukov SCOPED_TSAN_INTERCEPTOR(memcpy, dst, src, size); 4677ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)dst, size, true); 4687ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)src, size, false); 469065c4ac846589d04436cb7f19f938ff42035313eDmitry Vyukov return internal_memcpy(dst, src, size); 4707ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 4717ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 472065c4ac846589d04436cb7f19f938ff42035313eDmitry VyukovTSAN_INTERCEPTOR(int, memcmp, const void *s1, const void *s2, uptr n) { 473065c4ac846589d04436cb7f19f938ff42035313eDmitry Vyukov SCOPED_TSAN_INTERCEPTOR(memcmp, s1, s2, n); 474d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov int res = 0; 475d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov uptr len = 0; 476d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov for (; len < n; len++) { 477d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov if ((res = ((unsigned char*)s1)[len] - ((unsigned char*)s2)[len])) 478d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov break; 479d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov } 480d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov MemoryAccessRange(thr, pc, (uptr)s1, len < n ? len + 1 : n, false); 481d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov MemoryAccessRange(thr, pc, (uptr)s2, len < n ? len + 1 : n, false); 482d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov return res; 483d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov} 484d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov 4857ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, strcmp, const char *s1, const char *s2) { 4867ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(strcmp, s1, s2); 4877ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany uptr len = 0; 4887ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany for (; s1[len] && s2[len]; len++) { 4897ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (s1[len] != s2[len]) 4907ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany break; 4917ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 4927ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)s1, len + 1, false); 4937ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)s2, len + 1, false); 4947ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return s1[len] - s2[len]; 4957ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 4967ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 4977ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr n) { 4987ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(strncmp, s1, s2, n); 4997ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany uptr len = 0; 5007d38634b30beed9bed44dfa6cb8e977ec51d7c6cDmitry Vyukov for (; len < n && s1[len] && s2[len]; len++) { 5017ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (s1[len] != s2[len]) 5027ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany break; 5037ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 5047ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)s1, len < n ? len + 1 : n, false); 5057ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)s2, len < n ? len + 1 : n, false); 5067ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return len == n ? 0 : s1[len] - s2[len]; 5077ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 5087ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 5097ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(void*, memchr, void *s, int c, uptr n) { 5107ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(memchr, s, c, n); 5117ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany void *res = REAL(memchr)(s, c, n); 5127ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany uptr len = res ? (char*)res - (char*)s + 1 : n; 5137ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)s, len, false); 5147ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 5157ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 5167ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 5177ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(void*, memrchr, char *s, int c, uptr n) { 5187ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(memrchr, s, c, n); 5197ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)s, n, false); 5207ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return REAL(memrchr)(s, c, n); 5217ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 5227ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 5237ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(void*, memmove, void *dst, void *src, uptr n) { 5247ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(memmove, dst, src, n); 5257ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)dst, n, true); 5267ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)src, n, false); 5277ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return REAL(memmove)(dst, src, n); 5287ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 5297ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 530d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry VyukovTSAN_INTERCEPTOR(char*, strchr, char *s, int c) { 5317ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(strchr, s, c); 532d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov char *res = REAL(strchr)(s, c); 533d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov uptr len = res ? (char*)res - (char*)s + 1 : internal_strlen(s) + 1; 5347ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)s, len, false); 5357ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 5367ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 5377ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 538d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry VyukovTSAN_INTERCEPTOR(char*, strchrnul, char *s, int c) { 5397ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(strchrnul, s, c); 540d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov char *res = REAL(strchrnul)(s, c); 5417ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany uptr len = (char*)res - (char*)s + 1; 5427ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)s, len, false); 5437ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 5447ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 5457ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 546d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry VyukovTSAN_INTERCEPTOR(char*, strrchr, char *s, int c) { 5477ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(strrchr, s, c); 548d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov MemoryAccessRange(thr, pc, (uptr)s, internal_strlen(s) + 1, false); 5497ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return REAL(strrchr)(s, c); 5507ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 5517ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 552d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry VyukovTSAN_INTERCEPTOR(char*, strcpy, char *dst, const char *src) { // NOLINT 5537ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(strcpy, dst, src); // NOLINT 554d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov uptr srclen = internal_strlen(src); 5557ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)dst, srclen + 1, true); 5567ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)src, srclen + 1, false); 5577ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return REAL(strcpy)(dst, src); // NOLINT 5587ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 5597ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 560d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry VyukovTSAN_INTERCEPTOR(char*, strncpy, char *dst, char *src, uptr n) { 5617ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(strncpy, dst, src, n); 562b93c3d5badc4066120edf3ed1c515cdd516a8776Kostya Serebryany uptr srclen = internal_strnlen(src, n); 5637ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)dst, n, true); 5647ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)src, min(srclen + 1, n), false); 5657ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return REAL(strncpy)(dst, src, n); 5667ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 5677ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 5687ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(const char*, strstr, const char *s1, const char *s2) { 5697ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(strstr, s1, s2); 5707ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany const char *res = REAL(strstr)(s1, s2); 571d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov uptr len1 = internal_strlen(s1); 572d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov uptr len2 = internal_strlen(s2); 5737ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)s1, len1 + 1, false); 5747ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)s2, len2 + 1, false); 5757ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 5767ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 5777ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 5787ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic bool fix_mmap_addr(void **addr, long_t sz, int flags) { 5797ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (*addr) { 5807ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (!IsAppMem((uptr)*addr) || !IsAppMem((uptr)*addr + sz - 1)) { 5817ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (flags & MAP_FIXED) { 5827a72b4a0f04f7f043ab86396b0faa552f55aa857Dmitry Vyukov errno = EINVAL; 5837ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return false; 5847ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } else { 5857ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany *addr = 0; 5867ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 5877ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 5887ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 5897ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return true; 5907ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 5917ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 5927ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(void*, mmap, void *addr, long_t sz, int prot, 5937ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int flags, int fd, unsigned off) { 5947ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(mmap, addr, sz, prot, flags, fd, off); 5957ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (!fix_mmap_addr(&addr, sz, flags)) 5967ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return MAP_FAILED; 5977ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany void *res = REAL(mmap)(addr, sz, prot, flags, fd, off); 5987ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res != MAP_FAILED) { 599c05cbca0988c296068e0da1556bd6af7edd43c69Dmitry Vyukov if (fd > 0) 600c05cbca0988c296068e0da1556bd6af7edd43c69Dmitry Vyukov FdAccess(thr, pc, fd); 60174172de3ce25bf52d9d3918c94216f2eef5956e2Dmitry Vyukov MemoryRangeImitateWrite(thr, pc, (uptr)res, sz); 6027ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 6037ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 6047ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 6057ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 6067ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(void*, mmap64, void *addr, long_t sz, int prot, 6077ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int flags, int fd, u64 off) { 6087ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(mmap64, addr, sz, prot, flags, fd, off); 6097ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (!fix_mmap_addr(&addr, sz, flags)) 6107ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return MAP_FAILED; 6117ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany void *res = REAL(mmap64)(addr, sz, prot, flags, fd, off); 6127ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res != MAP_FAILED) { 613c05cbca0988c296068e0da1556bd6af7edd43c69Dmitry Vyukov if (fd > 0) 614c05cbca0988c296068e0da1556bd6af7edd43c69Dmitry Vyukov FdAccess(thr, pc, fd); 61574172de3ce25bf52d9d3918c94216f2eef5956e2Dmitry Vyukov MemoryRangeImitateWrite(thr, pc, (uptr)res, sz); 6167ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 6177ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 6187ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 6197ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 6207ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, munmap, void *addr, long_t sz) { 6217ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(munmap, addr, sz); 6227ac33ac529ff93a57419f5ddf71b1fde68428577Dmitry Vyukov DontNeedShadowFor((uptr)addr, sz); 6237ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(munmap)(addr, sz); 6247ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 6257ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 6267ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 6277ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(void*, memalign, uptr align, uptr sz) { 6287ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(memalign, align, sz); 6292e87051d136db3150a3ca322d8862f92b0a684bbDmitry Vyukov return user_alloc(thr, pc, sz, align); 6307ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 6317ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 6327ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(void*, valloc, uptr sz) { 6337ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(valloc, sz); 634f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany return user_alloc(thr, pc, sz, GetPageSizeCached()); 6357ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 6367ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 6377ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(void*, pvalloc, uptr sz) { 6387ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pvalloc, sz); 639f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany sz = RoundUp(sz, GetPageSizeCached()); 640f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany return user_alloc(thr, pc, sz, GetPageSizeCached()); 6417ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 6427ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 6437ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, posix_memalign, void **memptr, uptr align, uptr sz) { 6447ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(posix_memalign, memptr, align, sz); 6452e87051d136db3150a3ca322d8862f92b0a684bbDmitry Vyukov *memptr = user_alloc(thr, pc, sz, align); 6467ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return 0; 6477ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 6487ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 6497ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// Used in thread-safe function static initialization. 6501ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukovextern "C" int INTERFACE_ATTRIBUTE __cxa_guard_acquire(atomic_uint32_t *g) { 6511ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov SCOPED_INTERCEPTOR_RAW(__cxa_guard_acquire, g); 6521ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov for (;;) { 6531ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov u32 cmp = atomic_load(g, memory_order_acquire); 6541ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov if (cmp == 0) { 6551ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov if (atomic_compare_exchange_strong(g, &cmp, 1<<16, memory_order_relaxed)) 6561ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov return 1; 6571ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov } else if (cmp == 1) { 6581ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov Acquire(thr, pc, (uptr)g); 6591ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov return 0; 6601ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov } else { 6611ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov internal_sched_yield(); 6621ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov } 6637ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 6647ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 6657ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 6661ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukovextern "C" void INTERFACE_ATTRIBUTE __cxa_guard_release(atomic_uint32_t *g) { 6671ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov SCOPED_INTERCEPTOR_RAW(__cxa_guard_release, g); 6681ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov Release(thr, pc, (uptr)g); 6691ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov atomic_store(g, 1, memory_order_release); 6701ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov} 6711ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov 6721ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukovextern "C" void INTERFACE_ATTRIBUTE __cxa_guard_abort(atomic_uint32_t *g) { 6731ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov SCOPED_INTERCEPTOR_RAW(__cxa_guard_abort, g); 6741ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov atomic_store(g, 0, memory_order_relaxed); 6757ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 6767ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 6777ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic void thread_finalize(void *v) { 6787ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany uptr iter = (uptr)v; 6797ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (iter > 1) { 6807ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (pthread_setspecific(g_thread_finalize_key, (void*)(iter - 1))) { 681b1fe3021eca0843e37878d224ee7f32e32f40d99Alexey Samsonov Printf("ThreadSanitizer: failed to set thread key\n"); 6827ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany Die(); 6837ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 6847ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return; 6857ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 6867ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany { 6877ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany ScopedInRtl in_rtl; 688e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov ThreadState *thr = cur_thread(); 689e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov ThreadFinish(thr); 6901fc03d50a87302689482efa24b045a393097b6c3Dmitry Vyukov SignalContext *sctx = thr->signal_ctx; 6911fc03d50a87302689482efa24b045a393097b6c3Dmitry Vyukov if (sctx) { 6921fc03d50a87302689482efa24b045a393097b6c3Dmitry Vyukov thr->signal_ctx = 0; 693c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov UnmapOrDie(sctx, sizeof(*sctx)); 6941fc03d50a87302689482efa24b045a393097b6c3Dmitry Vyukov } 6957ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 6967ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 6977ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 6987ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 6997ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystruct ThreadParam { 7007ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany void* (*callback)(void *arg); 7017ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany void *param; 7027ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany atomic_uintptr_t tid; 7037ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}; 7047ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 7057ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyextern "C" void *__tsan_thread_start_func(void *arg) { 7067ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany ThreadParam *p = (ThreadParam*)arg; 7077ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany void* (*callback)(void *arg) = p->callback; 7087ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany void *param = p->param; 7097ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int tid = 0; 7107ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany { 7117ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany ThreadState *thr = cur_thread(); 7127ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany ScopedInRtl in_rtl; 7137ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (pthread_setspecific(g_thread_finalize_key, (void*)4)) { 714b1fe3021eca0843e37878d224ee7f32e32f40d99Alexey Samsonov Printf("ThreadSanitizer: failed to set thread key\n"); 7157ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany Die(); 7167ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 7177ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany while ((tid = atomic_load(&p->tid, memory_order_acquire)) == 0) 7187ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany pthread_yield(); 7197ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany atomic_store(&p->tid, 0, memory_order_release); 7207dccf3f92a867f917ad19f9a6b37bcf93e64b35bDmitry Vyukov ThreadStart(thr, tid, GetTid()); 7217ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany CHECK_EQ(thr->in_rtl, 1); 7227ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 7237ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany void *res = callback(param); 7247ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany // Prevent the callback from being tail called, 7257ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany // it mixes up stack traces. 7267ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany volatile int foo = 42; 7277ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany foo++; 7287ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 7297ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 7307ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 7317ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_create, 7327ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany void *th, void *attr, void *(*callback)(void*), void * param) { 7337ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_create, th, attr, callback, param); 734f110e356170fbe990b99c0939d77eeaa89b25497Alexey Samsonov __sanitizer_pthread_attr_t myattr; 7357ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (attr == 0) { 7367ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany pthread_attr_init(&myattr); 7377ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany attr = &myattr; 7387ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 7397ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int detached = 0; 7407ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany pthread_attr_getdetachstate(attr, &detached); 7417ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany uptr stacksize = 0; 7427ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany pthread_attr_getstacksize(attr, &stacksize); 7437ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany // We place the huge ThreadState object into TLS, account for that. 7447ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany const uptr minstacksize = GetTlsSize() + 128*1024; 7457ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (stacksize < minstacksize) { 746e954101f6602ac181a2c3accfbbad0ae51b0bf7cAlexey Samsonov DPrintf("ThreadSanitizer: stacksize %zu->%zu\n", stacksize, minstacksize); 7477ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany pthread_attr_setstacksize(attr, minstacksize); 7487ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 7497ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany ThreadParam p; 7507ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany p.callback = callback; 7517ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany p.param = param; 7527ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany atomic_store(&p.tid, 0, memory_order_relaxed); 7537ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_create)(th, attr, __tsan_thread_start_func, &p); 7547ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 75564310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov int tid = ThreadCreate(thr, pc, *(uptr*)th, detached); 7567ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany CHECK_NE(tid, 0); 7577ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany atomic_store(&p.tid, tid, memory_order_release); 7587ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany while (atomic_load(&p.tid, memory_order_acquire) != 0) 7597ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany pthread_yield(); 7607ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 7617ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (attr == &myattr) 7627ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany pthread_attr_destroy(&myattr); 7637ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 7647ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 7657ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 7667ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_join, void *th, void **ret) { 7677ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_join, th, ret); 7687ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int tid = ThreadTid(thr, pc, (uptr)th); 769ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov int res = BLOCK_REAL(pthread_join)(th, ret); 7707ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 77164310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov ThreadJoin(thr, pc, tid); 7727ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 7737ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 7747ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 7757ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 7767ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_detach, void *th) { 7777ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_detach, th); 7787ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int tid = ThreadTid(thr, pc, (uptr)th); 7797ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_detach)(th); 7807ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 78164310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov ThreadDetach(thr, pc, tid); 7827ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 7837ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 7847ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 7857ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 7867ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_mutex_init, void *m, void *a) { 7877ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_mutex_init, m, a); 7887ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_mutex_init)(m, a); 7897ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 7907ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany bool recursive = false; 7917ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (a) { 7927ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int type = 0; 7937ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (pthread_mutexattr_gettype(a, &type) == 0) 7947ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany recursive = (type == PTHREAD_MUTEX_RECURSIVE 7957ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany || type == PTHREAD_MUTEX_RECURSIVE_NP); 7967ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 797c20e9ba760a93706c9160133cdcce62194f9694fDmitry Vyukov MutexCreate(thr, pc, (uptr)m, false, recursive, false); 7987ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 7997ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 8007ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 8017ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 8027ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_mutex_destroy, void *m) { 8037ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_mutex_destroy, m); 8047ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_mutex_destroy)(m); 8057ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0 || res == EBUSY) { 80664310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexDestroy(thr, pc, (uptr)m); 8077ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 8087ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 8097ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 8107ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 8117ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_mutex_lock, void *m) { 8127ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_mutex_lock, m); 8137ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_mutex_lock)(m); 8147ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 81564310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexLock(thr, pc, (uptr)m); 8167ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 8177ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 8187ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 8197ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 8207ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_mutex_trylock, void *m) { 8217ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_mutex_trylock, m); 8227ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_mutex_trylock)(m); 8237ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 82464310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexLock(thr, pc, (uptr)m); 8257ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 8267ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 8277ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 8287ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 8297ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_mutex_timedlock, void *m, void *abstime) { 8307ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_mutex_timedlock, m, abstime); 8317ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_mutex_timedlock)(m, abstime); 8327ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 83364310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexLock(thr, pc, (uptr)m); 8347ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 8357ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 8367ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 8377ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 8387ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_mutex_unlock, void *m) { 8397ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_mutex_unlock, m); 84064310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexUnlock(thr, pc, (uptr)m); 8417ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_mutex_unlock)(m); 8427ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 8437ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 8447ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 8457ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_spin_init, void *m, int pshared) { 8467ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_spin_init, m, pshared); 8477ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_spin_init)(m, pshared); 8487ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 849c20e9ba760a93706c9160133cdcce62194f9694fDmitry Vyukov MutexCreate(thr, pc, (uptr)m, false, false, false); 8507ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 8517ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 8527ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 8537ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 8547ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_spin_destroy, void *m) { 8557ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_spin_destroy, m); 8567ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_spin_destroy)(m); 8577ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 85864310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexDestroy(thr, pc, (uptr)m); 8597ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 8607ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 8617ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 8627ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 8637ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_spin_lock, void *m) { 8647ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_spin_lock, m); 8657ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_spin_lock)(m); 8667ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 86764310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexLock(thr, pc, (uptr)m); 8687ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 8697ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 8707ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 8717ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 8727ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_spin_trylock, void *m) { 8737ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_spin_trylock, m); 8747ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_spin_trylock)(m); 8757ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 87664310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexLock(thr, pc, (uptr)m); 8777ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 8787ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 8797ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 8807ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 8817ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_spin_unlock, void *m) { 8827ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_spin_unlock, m); 88364310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexUnlock(thr, pc, (uptr)m); 8847ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_spin_unlock)(m); 8857ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 8867ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 8877ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 8887ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_rwlock_init, void *m, void *a) { 8897ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_init, m, a); 8907ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_rwlock_init)(m, a); 8917ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 892c20e9ba760a93706c9160133cdcce62194f9694fDmitry Vyukov MutexCreate(thr, pc, (uptr)m, true, false, false); 8937ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 8947ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 8957ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 8967ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 8977ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_rwlock_destroy, void *m) { 8987ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_destroy, m); 8997ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_rwlock_destroy)(m); 9007ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 90164310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexDestroy(thr, pc, (uptr)m); 9027ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 9037ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 9047ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 9057ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 9067ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_rwlock_rdlock, void *m) { 9077ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_rdlock, m); 9087ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_rwlock_rdlock)(m); 9097ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 91064310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexReadLock(thr, pc, (uptr)m); 9117ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 9127ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 9137ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 9147ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 9157ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_rwlock_tryrdlock, void *m) { 9167ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_tryrdlock, m); 9177ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_rwlock_tryrdlock)(m); 9187ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 91964310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexReadLock(thr, pc, (uptr)m); 9207ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 9217ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 9227ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 9237ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 9247ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_rwlock_timedrdlock, void *m, void *abstime) { 9257ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_timedrdlock, m, abstime); 9267ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_rwlock_timedrdlock)(m, abstime); 9277ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 92864310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexReadLock(thr, pc, (uptr)m); 9297ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 9307ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 9317ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 9327ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 9337ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_rwlock_wrlock, void *m) { 9347ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_wrlock, m); 9357ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_rwlock_wrlock)(m); 9367ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 93764310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexLock(thr, pc, (uptr)m); 9387ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 9397ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 9407ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 9417ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 9427ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_rwlock_trywrlock, void *m) { 9437ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_trywrlock, m); 9447ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_rwlock_trywrlock)(m); 9457ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 94664310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexLock(thr, pc, (uptr)m); 9477ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 9487ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 9497ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 9507ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 9517ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_rwlock_timedwrlock, void *m, void *abstime) { 9527ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_timedwrlock, m, abstime); 9537ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_rwlock_timedwrlock)(m, abstime); 9547ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 95564310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexLock(thr, pc, (uptr)m); 9567ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 9577ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 9587ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 9597ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 9607ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_rwlock_unlock, void *m) { 9617ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_unlock, m); 96264310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexReadOrWriteUnlock(thr, pc, (uptr)m); 9637ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_rwlock_unlock)(m); 9647ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 9657ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 9667ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 967703e4e4a133aa6585361a2c6130cfc2874efff75Dmitry Vyukov// libpthread.so contains several versions of pthread_cond_init symbol. 968703e4e4a133aa6585361a2c6130cfc2874efff75Dmitry Vyukov// When we just dlsym() it, we get the wrong (old) version. 969c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov/* 9707ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_cond_init, void *c, void *a) { 9717ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_cond_init, c, a); 9727ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_cond_init)(c, a); 9737ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 9747ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 975c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov*/ 9767ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 9777ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_cond_destroy, void *c) { 9787ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_cond_destroy, c); 9797ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_cond_destroy)(c); 9807ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 9817ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 9827ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 9837ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_cond_signal, void *c) { 9847ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_cond_signal, c); 9857ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_cond_signal)(c); 9867ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 9877ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 9887ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 9897ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_cond_broadcast, void *c) { 9907ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_cond_broadcast, c); 9917ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_cond_broadcast)(c); 9927ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 9937ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 9947ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 9957ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_cond_wait, void *c, void *m) { 9967ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_cond_wait, c, m); 99764310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexUnlock(thr, pc, (uptr)m); 9987ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_cond_wait)(c, m); 99964310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexLock(thr, pc, (uptr)m); 10007ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 10017ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 10027ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 10037ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_cond_timedwait, void *c, void *m, void *abstime) { 10047ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_cond_timedwait, c, m, abstime); 100564310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexUnlock(thr, pc, (uptr)m); 10067ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_cond_timedwait)(c, m, abstime); 100764310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexLock(thr, pc, (uptr)m); 10087ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 10097ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 10107ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 10117ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_barrier_init, void *b, void *a, unsigned count) { 10127ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_barrier_init, b, a, count); 1013334553ec45d8982df45a6f5e656e068142ecde3fDmitry Vyukov MemoryWrite(thr, pc, (uptr)b, kSizeLog1); 10147ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_barrier_init)(b, a, count); 10157ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 10167ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 10177ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 10187ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_barrier_destroy, void *b) { 10197ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_barrier_destroy, b); 1020334553ec45d8982df45a6f5e656e068142ecde3fDmitry Vyukov MemoryWrite(thr, pc, (uptr)b, kSizeLog1); 10217ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_barrier_destroy)(b); 10227ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 10237ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 10247ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 10257ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_barrier_wait, void *b) { 10267ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_barrier_wait, b); 102764310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov Release(thr, pc, (uptr)b); 1028334553ec45d8982df45a6f5e656e068142ecde3fDmitry Vyukov MemoryRead(thr, pc, (uptr)b, kSizeLog1); 10297ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_barrier_wait)(b); 1030334553ec45d8982df45a6f5e656e068142ecde3fDmitry Vyukov MemoryRead(thr, pc, (uptr)b, kSizeLog1); 10317ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0 || res == PTHREAD_BARRIER_SERIAL_THREAD) { 103264310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov Acquire(thr, pc, (uptr)b); 10337ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 10347ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 10357ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 10367ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 10377ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_once, void *o, void (*f)()) { 10387ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_once, o, f); 10397ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (o == 0 || f == 0) 10407ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return EINVAL; 10417ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany atomic_uint32_t *a = static_cast<atomic_uint32_t*>(o); 10427ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany u32 v = atomic_load(a, memory_order_acquire); 10437ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (v == 0 && atomic_compare_exchange_strong(a, &v, 1, 10447ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany memory_order_relaxed)) { 10457ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany const int old_in_rtl = thr->in_rtl; 10467ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany thr->in_rtl = 0; 10477ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany (*f)(); 10487ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany CHECK_EQ(thr->in_rtl, 0); 10497ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany thr->in_rtl = old_in_rtl; 105064310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov Release(thr, pc, (uptr)o); 10517ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany atomic_store(a, 2, memory_order_release); 10527ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } else { 10537ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany while (v != 2) { 10547ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany pthread_yield(); 10557ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany v = atomic_load(a, memory_order_acquire); 10567ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 105764310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov Acquire(thr, pc, (uptr)o); 10587ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 10597ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return 0; 10607ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 10617ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 10627ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, sem_init, void *s, int pshared, unsigned value) { 10637ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(sem_init, s, pshared, value); 10647ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(sem_init)(s, pshared, value); 10657ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 10667ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 10677ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 10687ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, sem_destroy, void *s) { 10697ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(sem_destroy, s); 10707ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(sem_destroy)(s); 10717ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 10727ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 10737ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 10747ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, sem_wait, void *s) { 10757ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(sem_wait, s); 1076ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov int res = BLOCK_REAL(sem_wait)(s); 10777ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 107864310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov Acquire(thr, pc, (uptr)s); 10797ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 10807ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 10817ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 10827ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 10837ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, sem_trywait, void *s) { 10847ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(sem_trywait, s); 1085ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov int res = BLOCK_REAL(sem_trywait)(s); 10867ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 108764310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov Acquire(thr, pc, (uptr)s); 10887ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 10897ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 10907ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 10917ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 10927ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, sem_timedwait, void *s, void *abstime) { 10937ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(sem_timedwait, s, abstime); 1094ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov int res = BLOCK_REAL(sem_timedwait)(s, abstime); 10957ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 109664310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov Acquire(thr, pc, (uptr)s); 10977ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 10987ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 10997ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 11007ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 11017ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, sem_post, void *s) { 11027ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(sem_post, s); 110364310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov Release(thr, pc, (uptr)s); 11047ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(sem_post)(s); 11057ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 11067ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 11077ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 11087ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, sem_getvalue, void *s, int *sval) { 11097ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(sem_getvalue, s, sval); 11107ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(sem_getvalue)(s, sval); 11117ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 111264310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov Acquire(thr, pc, (uptr)s); 11137ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 11147ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 11157ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 11167ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 111761ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry VyukovTSAN_INTERCEPTOR(int, __xstat, int version, const char *path, void *buf) { 111861ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(__xstat, version, path, buf); 111961ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov return REAL(__xstat)(version, path, buf); 112061ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov} 112161ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov 112261ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry VyukovTSAN_INTERCEPTOR(int, stat, const char *path, void *buf) { 112361ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(__xstat, 0, path, buf); 112461ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov return REAL(__xstat)(0, path, buf); 112561ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov} 112661ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov 112761ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry VyukovTSAN_INTERCEPTOR(int, __xstat64, int version, const char *path, void *buf) { 112861ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(__xstat64, version, path, buf); 112961ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov return REAL(__xstat64)(version, path, buf); 113061ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov} 113161ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov 113261ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry VyukovTSAN_INTERCEPTOR(int, stat64, const char *path, void *buf) { 113361ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(__xstat64, 0, path, buf); 113461ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov return REAL(__xstat64)(0, path, buf); 113561ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov} 113661ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov 113761ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry VyukovTSAN_INTERCEPTOR(int, __lxstat, int version, const char *path, void *buf) { 113861ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(__lxstat, version, path, buf); 113961ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov return REAL(__lxstat)(version, path, buf); 114061ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov} 114161ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov 114261ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry VyukovTSAN_INTERCEPTOR(int, lstat, const char *path, void *buf) { 114361ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(__lxstat, 0, path, buf); 114461ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov return REAL(__lxstat)(0, path, buf); 114561ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov} 114661ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov 114761ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry VyukovTSAN_INTERCEPTOR(int, __lxstat64, int version, const char *path, void *buf) { 114861ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(__lxstat64, version, path, buf); 114961ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov return REAL(__lxstat64)(version, path, buf); 115061ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov} 115161ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov 115261ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry VyukovTSAN_INTERCEPTOR(int, lstat64, const char *path, void *buf) { 115361ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(__lxstat64, 0, path, buf); 115461ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov return REAL(__lxstat64)(0, path, buf); 115561ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov} 115661ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov 115761ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry VyukovTSAN_INTERCEPTOR(int, __fxstat, int version, int fd, void *buf) { 115861ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(__fxstat, version, fd, buf); 1159c05cbca0988c296068e0da1556bd6af7edd43c69Dmitry Vyukov if (fd > 0) 1160c05cbca0988c296068e0da1556bd6af7edd43c69Dmitry Vyukov FdAccess(thr, pc, fd); 116161ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov return REAL(__fxstat)(version, fd, buf); 116261ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov} 116361ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov 116461ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry VyukovTSAN_INTERCEPTOR(int, fstat, int fd, void *buf) { 116561ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(__fxstat, 0, fd, buf); 1166c05cbca0988c296068e0da1556bd6af7edd43c69Dmitry Vyukov if (fd > 0) 1167c05cbca0988c296068e0da1556bd6af7edd43c69Dmitry Vyukov FdAccess(thr, pc, fd); 116861ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov return REAL(__fxstat)(0, fd, buf); 116961ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov} 117061ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov 117161ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry VyukovTSAN_INTERCEPTOR(int, __fxstat64, int version, int fd, void *buf) { 117261ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(__fxstat64, version, fd, buf); 1173c05cbca0988c296068e0da1556bd6af7edd43c69Dmitry Vyukov if (fd > 0) 1174c05cbca0988c296068e0da1556bd6af7edd43c69Dmitry Vyukov FdAccess(thr, pc, fd); 117561ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov return REAL(__fxstat64)(version, fd, buf); 117661ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov} 117761ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov 117861ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry VyukovTSAN_INTERCEPTOR(int, fstat64, int fd, void *buf) { 117961ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(__fxstat64, 0, fd, buf); 1180c05cbca0988c296068e0da1556bd6af7edd43c69Dmitry Vyukov if (fd > 0) 1181c05cbca0988c296068e0da1556bd6af7edd43c69Dmitry Vyukov FdAccess(thr, pc, fd); 118261ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov return REAL(__fxstat64)(0, fd, buf); 118361ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov} 118461ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov 1185ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry VyukovTSAN_INTERCEPTOR(int, open, const char *name, int flags, int mode) { 1186ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(open, name, flags, mode); 1187ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov int fd = REAL(open)(name, flags, mode); 1188ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov if (fd >= 0) 118968230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov FdFileCreate(thr, pc, fd); 1190ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov return fd; 1191ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov} 1192ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov 1193c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry VyukovTSAN_INTERCEPTOR(int, open64, const char *name, int flags, int mode) { 1194c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov SCOPED_TSAN_INTERCEPTOR(open64, name, flags, mode); 1195c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov int fd = REAL(open64)(name, flags, mode); 1196c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov if (fd >= 0) 1197c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov FdFileCreate(thr, pc, fd); 1198c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov return fd; 1199c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov} 1200c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov 1201ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry VyukovTSAN_INTERCEPTOR(int, creat, const char *name, int mode) { 1202ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(creat, name, mode); 1203ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov int fd = REAL(creat)(name, mode); 1204ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov if (fd >= 0) 120568230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov FdFileCreate(thr, pc, fd); 1206ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov return fd; 1207ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov} 1208ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov 1209c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry VyukovTSAN_INTERCEPTOR(int, creat64, const char *name, int mode) { 1210c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov SCOPED_TSAN_INTERCEPTOR(creat64, name, mode); 1211c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov int fd = REAL(creat64)(name, mode); 1212c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov if (fd >= 0) 1213c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov FdFileCreate(thr, pc, fd); 1214c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov return fd; 1215c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov} 1216c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov 1217ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry VyukovTSAN_INTERCEPTOR(int, dup, int oldfd) { 1218ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(dup, oldfd); 1219ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov int newfd = REAL(dup)(oldfd); 1220b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (oldfd >= 0 && newfd >= 0 && newfd != oldfd) 1221ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov FdDup(thr, pc, oldfd, newfd); 1222ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov return newfd; 1223ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov} 1224ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov 1225ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry VyukovTSAN_INTERCEPTOR(int, dup2, int oldfd, int newfd) { 1226ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(dup2, oldfd, newfd); 1227ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov int newfd2 = REAL(dup2)(oldfd, newfd); 1228b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (oldfd >= 0 && newfd2 >= 0 && newfd2 != oldfd) 1229ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov FdDup(thr, pc, oldfd, newfd2); 1230ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov return newfd2; 1231ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov} 1232ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov 1233ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry VyukovTSAN_INTERCEPTOR(int, dup3, int oldfd, int newfd, int flags) { 1234ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(dup3, oldfd, newfd, flags); 1235ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov int newfd2 = REAL(dup3)(oldfd, newfd, flags); 1236b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (oldfd >= 0 && newfd2 >= 0 && newfd2 != oldfd) 1237ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov FdDup(thr, pc, oldfd, newfd2); 1238ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov return newfd2; 1239ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov} 1240ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov 124168230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry VyukovTSAN_INTERCEPTOR(int, eventfd, unsigned initval, int flags) { 124268230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(eventfd, initval, flags); 124368230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov int fd = REAL(eventfd)(initval, flags); 124468230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov if (fd >= 0) 124568230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov FdEventCreate(thr, pc, fd); 124668230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov return fd; 124768230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov} 124868230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov 124945d4324bf5b0ec282f0a8f96312233e09a882502Dmitry VyukovTSAN_INTERCEPTOR(int, signalfd, int fd, void *mask, int flags) { 125045d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(signalfd, fd, mask, flags); 1251b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (fd >= 0) 1252b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov FdClose(thr, pc, fd); 125345d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov fd = REAL(signalfd)(fd, mask, flags); 125445d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov if (fd >= 0) 125545d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov FdSignalCreate(thr, pc, fd); 125645d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov return fd; 125745d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov} 125845d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov 1259b75c67b495ca13801cc629b2c2c9dd0010e54739Dmitry VyukovTSAN_INTERCEPTOR(int, inotify_init, int fake) { 1260b75c67b495ca13801cc629b2c2c9dd0010e54739Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(inotify_init, fake); 1261b75c67b495ca13801cc629b2c2c9dd0010e54739Dmitry Vyukov int fd = REAL(inotify_init)(fake); 126245d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov if (fd >= 0) 126345d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov FdInotifyCreate(thr, pc, fd); 126445d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov return fd; 126545d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov} 126645d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov 126745d4324bf5b0ec282f0a8f96312233e09a882502Dmitry VyukovTSAN_INTERCEPTOR(int, inotify_init1, int flags) { 126845d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(inotify_init1, flags); 126945d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov int fd = REAL(inotify_init1)(flags); 127045d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov if (fd >= 0) 127145d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov FdInotifyCreate(thr, pc, fd); 127245d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov return fd; 127345d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov} 127445d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov 127568230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry VyukovTSAN_INTERCEPTOR(int, socket, int domain, int type, int protocol) { 127668230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(socket, domain, type, protocol); 127768230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov int fd = REAL(socket)(domain, type, protocol); 127868230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov if (fd >= 0) 127968230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov FdSocketCreate(thr, pc, fd); 128068230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov return fd; 128168230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov} 128268230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov 1283983518e360a179d92bdbddebe05a87db3c6cc3c0Dmitry VyukovTSAN_INTERCEPTOR(int, socketpair, int domain, int type, int protocol, int *fd) { 1284983518e360a179d92bdbddebe05a87db3c6cc3c0Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(socketpair, domain, type, protocol, fd); 1285983518e360a179d92bdbddebe05a87db3c6cc3c0Dmitry Vyukov int res = REAL(socketpair)(domain, type, protocol, fd); 1286983518e360a179d92bdbddebe05a87db3c6cc3c0Dmitry Vyukov if (res == 0 && fd[0] >= 0 && fd[1] >= 0) 1287983518e360a179d92bdbddebe05a87db3c6cc3c0Dmitry Vyukov FdPipeCreate(thr, pc, fd[0], fd[1]); 1288983518e360a179d92bdbddebe05a87db3c6cc3c0Dmitry Vyukov return res; 1289983518e360a179d92bdbddebe05a87db3c6cc3c0Dmitry Vyukov} 1290983518e360a179d92bdbddebe05a87db3c6cc3c0Dmitry Vyukov 129168230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry VyukovTSAN_INTERCEPTOR(int, connect, int fd, void *addr, unsigned addrlen) { 129268230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(connect, fd, addr, addrlen); 1293ed513f69b8017a69214509105e7ec59fec77b468Dmitry Vyukov FdSocketConnecting(thr, pc, fd); 129468230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov int res = REAL(connect)(fd, addr, addrlen); 1295b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (res == 0 && fd >= 0) 129668230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov FdSocketConnect(thr, pc, fd); 129768230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov return res; 129868230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov} 129968230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov 130052c70e5818727521b89f7fc95a2a383df8985ca6Dmitry VyukovTSAN_INTERCEPTOR(int, bind, int fd, void *addr, unsigned addrlen) { 130152c70e5818727521b89f7fc95a2a383df8985ca6Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(bind, fd, addr, addrlen); 130252c70e5818727521b89f7fc95a2a383df8985ca6Dmitry Vyukov int res = REAL(bind)(fd, addr, addrlen); 130352c70e5818727521b89f7fc95a2a383df8985ca6Dmitry Vyukov if (fd > 0 && res == 0) 130452c70e5818727521b89f7fc95a2a383df8985ca6Dmitry Vyukov FdAccess(thr, pc, fd); 130552c70e5818727521b89f7fc95a2a383df8985ca6Dmitry Vyukov return res; 130652c70e5818727521b89f7fc95a2a383df8985ca6Dmitry Vyukov} 130752c70e5818727521b89f7fc95a2a383df8985ca6Dmitry Vyukov 130852c70e5818727521b89f7fc95a2a383df8985ca6Dmitry VyukovTSAN_INTERCEPTOR(int, listen, int fd, int backlog) { 130952c70e5818727521b89f7fc95a2a383df8985ca6Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(listen, fd, backlog); 131052c70e5818727521b89f7fc95a2a383df8985ca6Dmitry Vyukov int res = REAL(listen)(fd, backlog); 131152c70e5818727521b89f7fc95a2a383df8985ca6Dmitry Vyukov if (fd > 0 && res == 0) 131252c70e5818727521b89f7fc95a2a383df8985ca6Dmitry Vyukov FdAccess(thr, pc, fd); 131352c70e5818727521b89f7fc95a2a383df8985ca6Dmitry Vyukov return res; 131452c70e5818727521b89f7fc95a2a383df8985ca6Dmitry Vyukov} 131552c70e5818727521b89f7fc95a2a383df8985ca6Dmitry Vyukov 131668230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry VyukovTSAN_INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) { 131768230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(accept, fd, addr, addrlen); 131868230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov int fd2 = REAL(accept)(fd, addr, addrlen); 1319b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (fd >= 0 && fd2 >= 0) 132068230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov FdSocketAccept(thr, pc, fd, fd2); 132168230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov return fd2; 132268230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov} 132368230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov 132468230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry VyukovTSAN_INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) { 132568230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(accept4, fd, addr, addrlen, f); 132668230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov int fd2 = REAL(accept4)(fd, addr, addrlen, f); 1327b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (fd >= 0 && fd2 >= 0) 132868230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov FdSocketAccept(thr, pc, fd, fd2); 132968230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov return fd2; 133068230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov} 133168230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov 133268230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry VyukovTSAN_INTERCEPTOR(int, epoll_create, int size) { 133368230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(epoll_create, size); 133468230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov int fd = REAL(epoll_create)(size); 133568230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov if (fd >= 0) 133668230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov FdPollCreate(thr, pc, fd); 133768230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov return fd; 133868230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov} 133968230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov 134068230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry VyukovTSAN_INTERCEPTOR(int, epoll_create1, int flags) { 134168230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(epoll_create1, flags); 134268230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov int fd = REAL(epoll_create1)(flags); 134368230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov if (fd >= 0) 134468230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov FdPollCreate(thr, pc, fd); 134568230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov return fd; 134668230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov} 134768230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov 1348ddeb2c354235818494d86827e88a0c2fa44bebccDmitry VyukovTSAN_INTERCEPTOR(int, close, int fd) { 1349ddeb2c354235818494d86827e88a0c2fa44bebccDmitry Vyukov SCOPED_TSAN_INTERCEPTOR(close, fd); 1350c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov if (fd >= 0) 1351c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov FdClose(thr, pc, fd); 1352ddeb2c354235818494d86827e88a0c2fa44bebccDmitry Vyukov return REAL(close)(fd); 1353ddeb2c354235818494d86827e88a0c2fa44bebccDmitry Vyukov} 1354ddeb2c354235818494d86827e88a0c2fa44bebccDmitry Vyukov 1355c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry VyukovTSAN_INTERCEPTOR(int, __close, int fd) { 1356c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov SCOPED_TSAN_INTERCEPTOR(__close, fd); 1357c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov if (fd >= 0) 1358c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov FdClose(thr, pc, fd); 1359c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov return REAL(__close)(fd); 1360c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov} 1361c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov 136203f224835f46801a0e22cc2951d21b67304e0457Dmitry Vyukov// glibc guts 136303f224835f46801a0e22cc2951d21b67304e0457Dmitry VyukovTSAN_INTERCEPTOR(void, __res_iclose, void *state, bool free_addr) { 136403f224835f46801a0e22cc2951d21b67304e0457Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(__res_iclose, state, free_addr); 136503f224835f46801a0e22cc2951d21b67304e0457Dmitry Vyukov int fds[64]; 136603f224835f46801a0e22cc2951d21b67304e0457Dmitry Vyukov int cnt = ExtractResolvFDs(state, fds, ARRAY_SIZE(fds)); 136703f224835f46801a0e22cc2951d21b67304e0457Dmitry Vyukov for (int i = 0; i < cnt; i++) { 136803f224835f46801a0e22cc2951d21b67304e0457Dmitry Vyukov if (fds[i] > 0) 136903f224835f46801a0e22cc2951d21b67304e0457Dmitry Vyukov FdClose(thr, pc, fds[i]); 137003f224835f46801a0e22cc2951d21b67304e0457Dmitry Vyukov } 137103f224835f46801a0e22cc2951d21b67304e0457Dmitry Vyukov REAL(__res_iclose)(state, free_addr); 137203f224835f46801a0e22cc2951d21b67304e0457Dmitry Vyukov} 137303f224835f46801a0e22cc2951d21b67304e0457Dmitry Vyukov 137401e96987f557524a351b9f2229e7c920cdb96aadDmitry VyukovTSAN_INTERCEPTOR(int, pipe, int *pipefd) { 1375ddeb2c354235818494d86827e88a0c2fa44bebccDmitry Vyukov SCOPED_TSAN_INTERCEPTOR(pipe, pipefd); 1376ddeb2c354235818494d86827e88a0c2fa44bebccDmitry Vyukov int res = REAL(pipe)(pipefd); 1377b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (res == 0 && pipefd[0] >= 0 && pipefd[1] >= 0) 137868230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov FdPipeCreate(thr, pc, pipefd[0], pipefd[1]); 137901e96987f557524a351b9f2229e7c920cdb96aadDmitry Vyukov return res; 1380ddeb2c354235818494d86827e88a0c2fa44bebccDmitry Vyukov} 1381ddeb2c354235818494d86827e88a0c2fa44bebccDmitry Vyukov 138201e96987f557524a351b9f2229e7c920cdb96aadDmitry VyukovTSAN_INTERCEPTOR(int, pipe2, int *pipefd, int flags) { 1383ddeb2c354235818494d86827e88a0c2fa44bebccDmitry Vyukov SCOPED_TSAN_INTERCEPTOR(pipe2, pipefd, flags); 1384ddeb2c354235818494d86827e88a0c2fa44bebccDmitry Vyukov int res = REAL(pipe2)(pipefd, flags); 1385b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (res == 0 && pipefd[0] >= 0 && pipefd[1] >= 0) 138668230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov FdPipeCreate(thr, pc, pipefd[0], pipefd[1]); 1387ddeb2c354235818494d86827e88a0c2fa44bebccDmitry Vyukov return res; 1388ddeb2c354235818494d86827e88a0c2fa44bebccDmitry Vyukov} 1389ddeb2c354235818494d86827e88a0c2fa44bebccDmitry Vyukov 13907ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(long_t, readv, int fd, void *vec, int cnt) { 13917ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(readv, fd, vec, cnt); 13927ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(readv)(fd, vec, cnt); 1393b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (res >= 0 && fd >= 0) { 13943f4e6d9b75fb3f7f2674a31008738cfda9cda9edDmitry Vyukov FdAcquire(thr, pc, fd); 13957ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 13967ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 13977ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 13987ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 13997ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(long_t, preadv64, int fd, void *vec, int cnt, u64 off) { 14007ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(preadv64, fd, vec, cnt, off); 14017ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(preadv64)(fd, vec, cnt, off); 1402b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (res >= 0 && fd >= 0) { 14033f4e6d9b75fb3f7f2674a31008738cfda9cda9edDmitry Vyukov FdAcquire(thr, pc, fd); 14047ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 14057ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 14067ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 14077ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 14087ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(long_t, writev, int fd, void *vec, int cnt) { 14097ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(writev, fd, vec, cnt); 1410b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (fd >= 0) 1411b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov FdRelease(thr, pc, fd); 14127ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(writev)(fd, vec, cnt); 14137ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 14147ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 14157ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 14167ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(long_t, pwritev64, int fd, void *vec, int cnt, u64 off) { 14177ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pwritev64, fd, vec, cnt, off); 1418b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (fd >= 0) 1419b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov FdRelease(thr, pc, fd); 14207ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pwritev64)(fd, vec, cnt, off); 14217ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 14227ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 14237ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 14247ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(long_t, send, int fd, void *buf, long_t len, int flags) { 14257ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(send, fd, buf, len, flags); 1426b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (fd >= 0) 1427b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov FdRelease(thr, pc, fd); 14287ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(send)(fd, buf, len, flags); 14297ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 14307ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 14317ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 14327ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(long_t, sendmsg, int fd, void *msg, int flags) { 14337ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(sendmsg, fd, msg, flags); 1434b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (fd >= 0) 1435b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov FdRelease(thr, pc, fd); 14367ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(sendmsg)(fd, msg, flags); 14377ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 14387ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 14397ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 14407ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(long_t, recv, int fd, void *buf, long_t len, int flags) { 14417ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(recv, fd, buf, len, flags); 14427ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(recv)(fd, buf, len, flags); 1443b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (res >= 0 && fd >= 0) { 14443f4e6d9b75fb3f7f2674a31008738cfda9cda9edDmitry Vyukov FdAcquire(thr, pc, fd); 14457ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 14467ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 14477ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 14487ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 14497ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(long_t, recvmsg, int fd, void *msg, int flags) { 14507ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(recvmsg, fd, msg, flags); 14517ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(recvmsg)(fd, msg, flags); 1452b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (res >= 0 && fd >= 0) { 14533f4e6d9b75fb3f7f2674a31008738cfda9cda9edDmitry Vyukov FdAcquire(thr, pc, fd); 14547ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 14557ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 14567ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 14577ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 14587ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, unlink, char *path) { 14597ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(unlink, path); 1460c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov Release(thr, pc, File2addr(path)); 14617ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(unlink)(path); 14627ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 14637ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 14647ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 14657ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(void*, fopen, char *path, char *mode) { 14667ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(fopen, path, mode); 14677ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany void *res = REAL(fopen)(path, mode); 1468c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov Acquire(thr, pc, File2addr(path)); 1469c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov if (res) { 1470f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov int fd = fileno_unlocked(res); 1471c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov if (fd >= 0) 1472c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov FdFileCreate(thr, pc, fd); 1473c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov } 1474c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov return res; 1475c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov} 1476c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov 1477c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry VyukovTSAN_INTERCEPTOR(void*, freopen, char *path, char *mode, void *stream) { 1478c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov SCOPED_TSAN_INTERCEPTOR(freopen, path, mode, stream); 1479c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov if (stream) { 1480f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov int fd = fileno_unlocked(stream); 1481c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov if (fd >= 0) 1482c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov FdClose(thr, pc, fd); 1483c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov } 1484c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov void *res = REAL(freopen)(path, mode, stream); 1485c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov Acquire(thr, pc, File2addr(path)); 1486c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov if (res) { 1487f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov int fd = fileno_unlocked(res); 1488c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov if (fd >= 0) 1489c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov FdFileCreate(thr, pc, fd); 1490c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov } 1491c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov return res; 1492c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov} 1493c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov 1494c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry VyukovTSAN_INTERCEPTOR(int, fclose, void *stream) { 1495f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov { 1496f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(fclose, stream); 1497f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov if (stream) { 1498f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov int fd = fileno_unlocked(stream); 1499f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov if (fd >= 0) 1500f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov FdClose(thr, pc, fd); 1501f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov } 1502c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov } 1503f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov return REAL(fclose)(stream); 15047ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 15057ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 15067ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(uptr, fread, void *ptr, uptr size, uptr nmemb, void *f) { 1507f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov { 1508f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(fread, ptr, size, nmemb, f); 1509f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov MemoryAccessRange(thr, pc, (uptr)ptr, size * nmemb, true); 1510f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov } 15117ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return REAL(fread)(ptr, size, nmemb, f); 15127ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 15137ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 15147ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(uptr, fwrite, const void *p, uptr size, uptr nmemb, void *f) { 1515f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov { 1516f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(fwrite, p, size, nmemb, f); 1517f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov MemoryAccessRange(thr, pc, (uptr)p, size * nmemb, false); 1518f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov } 15197ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return REAL(fwrite)(p, size, nmemb, f); 15207ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 15217ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 15227ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, puts, const char *s) { 15237ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(puts, s); 1524d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov MemoryAccessRange(thr, pc, (uptr)s, internal_strlen(s), false); 15257ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return REAL(puts)(s); 15267ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 15277ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 15287ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, rmdir, char *path) { 15297ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(rmdir, path); 1530c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov Release(thr, pc, Dir2addr(path)); 15317ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(rmdir)(path); 15327ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 15337ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 15347ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 15357ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(void*, opendir, char *path) { 15367ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(opendir, path); 15377ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany void *res = REAL(opendir)(path); 1538c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov if (res != 0) 1539c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov Acquire(thr, pc, Dir2addr(path)); 15407ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 15417ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 15427ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 15437ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, epoll_ctl, int epfd, int op, int fd, void *ev) { 15447ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(epoll_ctl, epfd, op, fd, ev); 1545b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (op == EPOLL_CTL_ADD && epfd >= 0) { 15463f4e6d9b75fb3f7f2674a31008738cfda9cda9edDmitry Vyukov FdRelease(thr, pc, epfd); 15477ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 15487ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(epoll_ctl)(epfd, op, fd, ev); 1549f5d4273457ca3d26e6cf658b266cd61062a65101Dmitry Vyukov if (fd >= 0) 1550f5d4273457ca3d26e6cf658b266cd61062a65101Dmitry Vyukov FdAccess(thr, pc, fd); 15517ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 15527ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 15537ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 15547ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, epoll_wait, int epfd, void *ev, int cnt, int timeout) { 15557ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(epoll_wait, epfd, ev, cnt, timeout); 1556ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov int res = BLOCK_REAL(epoll_wait)(epfd, ev, cnt, timeout); 1557b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (res > 0 && epfd >= 0) { 15583f4e6d9b75fb3f7f2674a31008738cfda9cda9edDmitry Vyukov FdAcquire(thr, pc, epfd); 15597ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 15607ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 15617ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 15627ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 1563ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry VyukovTSAN_INTERCEPTOR(int, poll, void *fds, long_t nfds, int timeout) { 1564ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(poll, fds, nfds, timeout); 1565ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov int res = BLOCK_REAL(poll)(fds, nfds, timeout); 1566ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov return res; 1567ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov} 1568ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov 1569d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukovstatic void ALWAYS_INLINE rtl_generic_sighandler(bool sigact, int sig, 1570d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov my_siginfo_t *info, void *ctx) { 15717ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany ThreadState *thr = cur_thread(); 1572e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov SignalContext *sctx = SigCtx(thr); 1573d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov // Don't mess with synchronous signals. 15741fc03d50a87302689482efa24b045a393097b6c3Dmitry Vyukov if (sig == SIGSEGV || sig == SIGBUS || sig == SIGILL || 15751fc03d50a87302689482efa24b045a393097b6c3Dmitry Vyukov sig == SIGABRT || sig == SIGFPE || sig == SIGPIPE || 1576ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov // If we are sending signal to ourselves, we must process it now. 1577ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov (sctx && sig == sctx->int_signal_send) || 15780bf04eab1910cc8bf622c20ba08c339dc25e297eDmitry Vyukov // If we are in blocking function, we can safely process it now 15790bf04eab1910cc8bf622c20ba08c339dc25e297eDmitry Vyukov // (but check if we are in a recursive interceptor, 15800bf04eab1910cc8bf622c20ba08c339dc25e297eDmitry Vyukov // i.e. pthread_join()->munmap()). 158180d46a2fbc0ae5086511a91119a6e28883b9f880Dmitry Vyukov (sctx && sctx->in_blocking_func == 1 && thr->in_rtl == 1)) { 1582d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov CHECK(thr->in_rtl == 0 || thr->in_rtl == 1); 1583d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov int in_rtl = thr->in_rtl; 1584d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov thr->in_rtl = 0; 1585d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov CHECK_EQ(thr->in_signal_handler, false); 1586d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov thr->in_signal_handler = true; 1587d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov if (sigact) 1588d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov sigactions[sig].sa_sigaction(sig, info, ctx); 1589d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov else 1590d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov sigactions[sig].sa_handler(sig); 1591d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov CHECK_EQ(thr->in_signal_handler, true); 1592d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov thr->in_signal_handler = false; 1593d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov thr->in_rtl = in_rtl; 1594d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov return; 1595d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov } 1596d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov 15971fc03d50a87302689482efa24b045a393097b6c3Dmitry Vyukov if (sctx == 0) 15981fc03d50a87302689482efa24b045a393097b6c3Dmitry Vyukov return; 1599e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov SignalDesc *signal = &sctx->pending_signals[sig]; 16007ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (signal->armed == false) { 16017ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany signal->armed = true; 1602d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov signal->sigaction = sigact; 1603d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov if (info) 16046e4815579e5b48b48de092afcc3b092dfb97df5cDmitry Vyukov internal_memcpy(&signal->siginfo, info, sizeof(*info)); 1605a5562db12c5331433407ac21602086f34561c25cDmitry Vyukov if (ctx) 16066e4815579e5b48b48de092afcc3b092dfb97df5cDmitry Vyukov internal_memcpy(&signal->ctx, ctx, sizeof(signal->ctx)); 1607e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov sctx->pending_signal_count++; 16087ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 16097ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 16107ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 1611d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukovstatic void rtl_sighandler(int sig) { 1612d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov rtl_generic_sighandler(false, sig, 0, 0); 1613d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov} 1614d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov 16157ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic void rtl_sigaction(int sig, my_siginfo_t *info, void *ctx) { 1616d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov rtl_generic_sighandler(true, sig, info, ctx); 16177ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 16187ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 16197ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, sigaction, int sig, sigaction_t *act, sigaction_t *old) { 16207ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(sigaction, sig, act, old); 1621d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov if (old) 16226e4815579e5b48b48de092afcc3b092dfb97df5cDmitry Vyukov internal_memcpy(old, &sigactions[sig], sizeof(*old)); 1623d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov if (act == 0) 1624d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov return 0; 16256e4815579e5b48b48de092afcc3b092dfb97df5cDmitry Vyukov internal_memcpy(&sigactions[sig], act, sizeof(*act)); 16266e4815579e5b48b48de092afcc3b092dfb97df5cDmitry Vyukov sigaction_t newact; 16276e4815579e5b48b48de092afcc3b092dfb97df5cDmitry Vyukov internal_memcpy(&newact, act, sizeof(newact)); 1628b4b9fa707324095e3590a57963fd754d7a4dd40eDmitry Vyukov sigfillset(&newact.sa_mask); 1629d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov if (act->sa_handler != SIG_IGN && act->sa_handler != SIG_DFL) { 16307ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (newact.sa_flags & SA_SIGINFO) 16317ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany newact.sa_sigaction = rtl_sigaction; 16327ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany else 16337ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany newact.sa_handler = rtl_sighandler; 1634d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov } 1635d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov int res = REAL(sigaction)(sig, &newact, 0); 1636d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov return res; 1637d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov} 1638d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov 1639d91d06794506f10fb7599a2b835222fba29394e0Dmitry VyukovTSAN_INTERCEPTOR(sighandler_t, signal, int sig, sighandler_t h) { 16402135d8a7f4ba30fe35ed02d5e6ffd59a95b26219Alexey Samsonov sigaction_t act; 1641d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov act.sa_handler = h; 164288207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov REAL(memset)(&act.sa_mask, -1, sizeof(act.sa_mask)); 1643d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov act.sa_flags = 0; 16442135d8a7f4ba30fe35ed02d5e6ffd59a95b26219Alexey Samsonov sigaction_t old; 1645d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov int res = sigaction(sig, &act, &old); 1646d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov if (res) 1647d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov return SIG_ERR; 1648d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov return old.sa_handler; 1649d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov} 1650d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov 1651d91d06794506f10fb7599a2b835222fba29394e0Dmitry VyukovTSAN_INTERCEPTOR(int, raise, int sig) { 1652d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(raise, sig); 1653e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov SignalContext *sctx = SigCtx(thr); 16541fc03d50a87302689482efa24b045a393097b6c3Dmitry Vyukov CHECK_NE(sctx, 0); 1655e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov int prev = sctx->int_signal_send; 1656e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov sctx->int_signal_send = sig; 1657d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov int res = REAL(raise)(sig); 1658e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov CHECK_EQ(sctx->int_signal_send, sig); 1659e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov sctx->int_signal_send = prev; 1660d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov return res; 1661d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov} 1662d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov 1663d91d06794506f10fb7599a2b835222fba29394e0Dmitry VyukovTSAN_INTERCEPTOR(int, kill, int pid, int sig) { 1664d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(kill, pid, sig); 1665e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov SignalContext *sctx = SigCtx(thr); 16661fc03d50a87302689482efa24b045a393097b6c3Dmitry Vyukov CHECK_NE(sctx, 0); 1667e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov int prev = sctx->int_signal_send; 1668d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov if (pid == GetPid()) { 1669e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov sctx->int_signal_send = sig; 1670d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov } 1671d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov int res = REAL(kill)(pid, sig); 1672d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov if (pid == GetPid()) { 1673e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov CHECK_EQ(sctx->int_signal_send, sig); 1674e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov sctx->int_signal_send = prev; 1675d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov } 1676d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov return res; 1677d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov} 1678d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov 1679d91d06794506f10fb7599a2b835222fba29394e0Dmitry VyukovTSAN_INTERCEPTOR(int, pthread_kill, void *tid, int sig) { 1680d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(pthread_kill, tid, sig); 1681e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov SignalContext *sctx = SigCtx(thr); 16821fc03d50a87302689482efa24b045a393097b6c3Dmitry Vyukov CHECK_NE(sctx, 0); 1683e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov int prev = sctx->int_signal_send; 1684d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov if (tid == pthread_self()) { 1685e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov sctx->int_signal_send = sig; 1686d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov } 1687d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov int res = REAL(pthread_kill)(tid, sig); 1688d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov if (tid == pthread_self()) { 1689e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov CHECK_EQ(sctx->int_signal_send, sig); 1690e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov sctx->int_signal_send = prev; 16917ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 16927ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 16937ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 16947ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 1695ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry VyukovTSAN_INTERCEPTOR(int, gettimeofday, void *tv, void *tz) { 1696ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(gettimeofday, tv, tz); 1697ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov // It's intercepted merely to process pending signals. 1698ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov return REAL(gettimeofday)(tv, tz); 1699ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov} 1700ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov 170192733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov// Linux kernel has a bug that leads to kernel deadlock if a process 170292733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov// maps TBs of memory and then calls mlock(). 170392733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukovstatic void MlockIsUnsupported() { 170492733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov static atomic_uint8_t printed; 170592733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov if (atomic_exchange(&printed, 1, memory_order_relaxed)) 170692733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov return; 170792733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov Printf("INFO: ThreadSanitizer ignores mlock/mlockall/munlock/munlockall\n"); 170892733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov} 170992733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov 171092733f94292cd36795238e1a6ed0a99a1dc0454dDmitry VyukovTSAN_INTERCEPTOR(int, mlock, const void *addr, uptr len) { 171192733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov MlockIsUnsupported(); 171292733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov return 0; 171392733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov} 171492733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov 171592733f94292cd36795238e1a6ed0a99a1dc0454dDmitry VyukovTSAN_INTERCEPTOR(int, munlock, const void *addr, uptr len) { 171692733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov MlockIsUnsupported(); 171792733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov return 0; 171892733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov} 171992733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov 172092733f94292cd36795238e1a6ed0a99a1dc0454dDmitry VyukovTSAN_INTERCEPTOR(int, mlockall, int flags) { 172192733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov MlockIsUnsupported(); 172292733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov return 0; 172392733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov} 172492733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov 172592733f94292cd36795238e1a6ed0a99a1dc0454dDmitry VyukovTSAN_INTERCEPTOR(int, munlockall, void) { 172692733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov MlockIsUnsupported(); 172792733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov return 0; 172892733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov} 172992733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov 1730b75c67b495ca13801cc629b2c2c9dd0010e54739Dmitry VyukovTSAN_INTERCEPTOR(int, fork, int fake) { 1731b75c67b495ca13801cc629b2c2c9dd0010e54739Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(fork, fake); 17324554b7a7b345cd50ff8138b3cda8dd1135b965faDmitry Vyukov // It's intercepted merely to process pending signals. 1733b75c67b495ca13801cc629b2c2c9dd0010e54739Dmitry Vyukov int pid = REAL(fork)(fake); 17344554b7a7b345cd50ff8138b3cda8dd1135b965faDmitry Vyukov if (pid == 0) { 17354554b7a7b345cd50ff8138b3cda8dd1135b965faDmitry Vyukov // child 17364554b7a7b345cd50ff8138b3cda8dd1135b965faDmitry Vyukov FdOnFork(thr, pc); 17374554b7a7b345cd50ff8138b3cda8dd1135b965faDmitry Vyukov } else if (pid > 0) { 17384554b7a7b345cd50ff8138b3cda8dd1135b965faDmitry Vyukov // parent 17394554b7a7b345cd50ff8138b3cda8dd1135b965faDmitry Vyukov } 17404554b7a7b345cd50ff8138b3cda8dd1135b965faDmitry Vyukov return pid; 17414554b7a7b345cd50ff8138b3cda8dd1135b965faDmitry Vyukov} 17424554b7a7b345cd50ff8138b3cda8dd1135b965faDmitry Vyukov 1743996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanovstruct TsanInterceptorContext { 1744996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov ThreadState *thr; 1745996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov const uptr caller_pc; 1746996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov const uptr pc; 1747996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov}; 1748996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov 1749996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \ 1750996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov MemoryAccessRange(((TsanInterceptorContext*)ctx)->thr, \ 1751996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov ((TsanInterceptorContext*)ctx)->pc, \ 1752996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov (uptr)ptr, size, true) 1753996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \ 1754996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov MemoryAccessRange(((TsanInterceptorContext*)ctx)->thr, \ 1755996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov ((TsanInterceptorContext*)ctx)->pc, \ 1756996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov (uptr)ptr, size, false) 1757996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \ 1758996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov SCOPED_TSAN_INTERCEPTOR(func, __VA_ARGS__) \ 1759996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov TsanInterceptorContext _ctx = {thr, caller_pc, pc}; \ 176082a9080eaff95d69b270cd863e9df63e3b4e59adEvgeniy Stepanov ctx = (void*)&_ctx; \ 176182a9080eaff95d69b270cd863e9df63e3b4e59adEvgeniy Stepanov (void)ctx; 1762996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \ 1763996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov FdAcquire(((TsanInterceptorContext*)ctx)->thr, pc, fd) 1764996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \ 1765996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov FdRelease(((TsanInterceptorContext*)ctx)->thr, pc, fd) 1766996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) \ 1767996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov ThreadSetName(((TsanInterceptorContext*)ctx)->thr, name) 17684f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov#include "sanitizer_common/sanitizer_common_interceptors.inc" 1769c8033193376c3326478a345c4ae6633d4d2862c6Kostya Serebryany 1770ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukovnamespace __tsan { 1771ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov 1772ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukovvoid ProcessPendingSignals(ThreadState *thr) { 17737ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany CHECK_EQ(thr->in_rtl, 0); 1774e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov SignalContext *sctx = SigCtx(thr); 17751fc03d50a87302689482efa24b045a393097b6c3Dmitry Vyukov if (sctx == 0 || sctx->pending_signal_count == 0 || thr->in_signal_handler) 17767ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return; 1777158c6ac3bb46753db217f9c2c73485811a3a1890Dmitry Vyukov Context *ctx = CTX(); 17787ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany thr->in_signal_handler = true; 1779e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov sctx->pending_signal_count = 0; 17807ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany // These are too big for stack. 17817ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany static THREADLOCAL sigset_t emptyset, oldset; 17827ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany sigfillset(&emptyset); 17837ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany pthread_sigmask(SIG_SETMASK, &emptyset, &oldset); 17847ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany for (int sig = 0; sig < kSigCount; sig++) { 1785e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov SignalDesc *signal = &sctx->pending_signals[sig]; 17867ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (signal->armed) { 17877ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany signal->armed = false; 1788d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov if (sigactions[sig].sa_handler != SIG_DFL 1789d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov && sigactions[sig].sa_handler != SIG_IGN) { 17907a72b4a0f04f7f043ab86396b0faa552f55aa857Dmitry Vyukov // Insure that the handler does not spoil errno. 17917a72b4a0f04f7f043ab86396b0faa552f55aa857Dmitry Vyukov const int saved_errno = errno; 17927a72b4a0f04f7f043ab86396b0faa552f55aa857Dmitry Vyukov errno = 0; 1793d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov if (signal->sigaction) 1794a5562db12c5331433407ac21602086f34561c25cDmitry Vyukov sigactions[sig].sa_sigaction(sig, &signal->siginfo, &signal->ctx); 1795d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov else 1796d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov sigactions[sig].sa_handler(sig); 17978a326776e41dc68c810ba3719a24328de517d8f9Dmitry Vyukov if (flags()->report_bugs && errno != 0) { 17987a72b4a0f04f7f043ab86396b0faa552f55aa857Dmitry Vyukov ScopedInRtl in_rtl; 17994f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov __tsan::StackTrace stack; 18007a72b4a0f04f7f043ab86396b0faa552f55aa857Dmitry Vyukov uptr pc = signal->sigaction ? 18017a72b4a0f04f7f043ab86396b0faa552f55aa857Dmitry Vyukov (uptr)sigactions[sig].sa_sigaction : 18027a72b4a0f04f7f043ab86396b0faa552f55aa857Dmitry Vyukov (uptr)sigactions[sig].sa_handler; 18037a72b4a0f04f7f043ab86396b0faa552f55aa857Dmitry Vyukov stack.Init(&pc, 1); 18042bbd8bec77c2fdb41c5f5b6cb0d83d22bc576650Alexey Samsonov ThreadRegistryLock l(ctx->thread_registry); 18057a72b4a0f04f7f043ab86396b0faa552f55aa857Dmitry Vyukov ScopedReport rep(ReportTypeErrnoInSignal); 1806158c6ac3bb46753db217f9c2c73485811a3a1890Dmitry Vyukov if (!IsFiredSuppression(ctx, rep, stack)) { 1807158c6ac3bb46753db217f9c2c73485811a3a1890Dmitry Vyukov rep.AddStack(&stack); 1808158c6ac3bb46753db217f9c2c73485811a3a1890Dmitry Vyukov OutputReport(ctx, rep, rep.GetReport()->stacks[0]); 1809158c6ac3bb46753db217f9c2c73485811a3a1890Dmitry Vyukov } 18107a72b4a0f04f7f043ab86396b0faa552f55aa857Dmitry Vyukov } 18117a72b4a0f04f7f043ab86396b0faa552f55aa857Dmitry Vyukov errno = saved_errno; 1812d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov } 18137ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 18147ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 18157ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany pthread_sigmask(SIG_SETMASK, &oldset, 0); 18167ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany CHECK_EQ(thr->in_signal_handler, true); 18177ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany thr->in_signal_handler = false; 18187ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 18197ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 182091ac008b435b879bb366bcf9516c53f2d07c30b1Dmitry Vyukovstatic void unreachable() { 182191ac008b435b879bb366bcf9516c53f2d07c30b1Dmitry Vyukov Printf("FATAL: ThreadSanitizer: unreachable called\n"); 182291ac008b435b879bb366bcf9516c53f2d07c30b1Dmitry Vyukov Die(); 182391ac008b435b879bb366bcf9516c53f2d07c30b1Dmitry Vyukov} 182491ac008b435b879bb366bcf9516c53f2d07c30b1Dmitry Vyukov 18257ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyvoid InitializeInterceptors() { 18267ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany CHECK_GT(cur_thread()->in_rtl, 0); 18277ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 18287ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany // We need to setup it early, because functions like dlsym() can call it. 1829065c4ac846589d04436cb7f19f938ff42035313eDmitry Vyukov REAL(memset) = internal_memset; 1830065c4ac846589d04436cb7f19f938ff42035313eDmitry Vyukov REAL(memcpy) = internal_memcpy; 1831065c4ac846589d04436cb7f19f938ff42035313eDmitry Vyukov REAL(memcmp) = internal_memcmp; 18327ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 1833c8033193376c3326478a345c4ae6633d4d2862c6Kostya Serebryany SANITIZER_COMMON_INTERCEPTORS_INIT; 1834c8033193376c3326478a345c4ae6633d4d2862c6Kostya Serebryany 1835f037f565b2e02878ceb6e7b49647e814e2990ef5Dmitry Vyukov TSAN_INTERCEPT(longjmp); 1836f037f565b2e02878ceb6e7b49647e814e2990ef5Dmitry Vyukov TSAN_INTERCEPT(siglongjmp); 1837f037f565b2e02878ceb6e7b49647e814e2990ef5Dmitry Vyukov 18387ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(malloc); 183907ba8ef44deb54baa9307298fbffe25ddb30c362Dmitry Vyukov TSAN_INTERCEPT(__libc_memalign); 18407ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(calloc); 18417ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(realloc); 18427ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(free); 18437ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(cfree); 18447ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(mmap); 18457ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(mmap64); 18467ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(munmap); 18477ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(memalign); 18487ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(valloc); 18497ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pvalloc); 18507ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(posix_memalign); 18517ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 18527ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(strlen); 18537ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(memset); 18547ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(memcpy); 18557ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(strcmp); 18567ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(memchr); 18577ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(memrchr); 18587ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(memmove); 18597ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(memcmp); 18607ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(strchr); 18617ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(strchrnul); 18627ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(strrchr); 18637ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(strncmp); 18647ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(strcpy); // NOLINT 18657ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(strncpy); 18667ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(strstr); 18677ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 18687ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_create); 18697ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_join); 18707ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_detach); 18717ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 18727ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_mutex_init); 18737ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_mutex_destroy); 18747ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_mutex_lock); 18757ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_mutex_trylock); 18767ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_mutex_timedlock); 18777ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_mutex_unlock); 18787ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 18797ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_spin_init); 18807ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_spin_destroy); 18817ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_spin_lock); 18827ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_spin_trylock); 18837ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_spin_unlock); 18847ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 18857ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_rwlock_init); 18867ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_rwlock_destroy); 18877ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_rwlock_rdlock); 18887ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_rwlock_tryrdlock); 18897ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_rwlock_timedrdlock); 18907ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_rwlock_wrlock); 18917ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_rwlock_trywrlock); 18927ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_rwlock_timedwrlock); 18937ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_rwlock_unlock); 18947ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 1895c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov // TSAN_INTERCEPT(pthread_cond_init); 18967ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_cond_destroy); 18977ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_cond_signal); 18987ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_cond_broadcast); 18997ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_cond_wait); 19007ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_cond_timedwait); 19017ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 19027ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_barrier_init); 19037ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_barrier_destroy); 19047ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_barrier_wait); 19057ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 19067ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_once); 19077ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 19087ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(sem_init); 19097ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(sem_destroy); 19107ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(sem_wait); 19117ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(sem_trywait); 19127ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(sem_timedwait); 19137ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(sem_post); 19147ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(sem_getvalue); 19157ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 191661ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov TSAN_INTERCEPT(stat); 191761ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov TSAN_INTERCEPT(__xstat); 191861ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov TSAN_INTERCEPT(stat64); 191961ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov TSAN_INTERCEPT(__xstat64); 192061ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov TSAN_INTERCEPT(lstat); 192161ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov TSAN_INTERCEPT(__lxstat); 192261ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov TSAN_INTERCEPT(lstat64); 192361ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov TSAN_INTERCEPT(__lxstat64); 192461ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov TSAN_INTERCEPT(fstat); 192561ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov TSAN_INTERCEPT(__fxstat); 192661ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov TSAN_INTERCEPT(fstat64); 192761ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov TSAN_INTERCEPT(__fxstat64); 1928ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov TSAN_INTERCEPT(open); 1929c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov TSAN_INTERCEPT(open64); 1930ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov TSAN_INTERCEPT(creat); 1931c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov TSAN_INTERCEPT(creat64); 1932ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov TSAN_INTERCEPT(dup); 1933ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov TSAN_INTERCEPT(dup2); 1934ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov TSAN_INTERCEPT(dup3); 193568230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov TSAN_INTERCEPT(eventfd); 193645d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov TSAN_INTERCEPT(signalfd); 193745d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov TSAN_INTERCEPT(inotify_init); 193845d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov TSAN_INTERCEPT(inotify_init1); 193968230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov TSAN_INTERCEPT(socket); 1940983518e360a179d92bdbddebe05a87db3c6cc3c0Dmitry Vyukov TSAN_INTERCEPT(socketpair); 194168230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov TSAN_INTERCEPT(connect); 194252c70e5818727521b89f7fc95a2a383df8985ca6Dmitry Vyukov TSAN_INTERCEPT(bind); 194352c70e5818727521b89f7fc95a2a383df8985ca6Dmitry Vyukov TSAN_INTERCEPT(listen); 194468230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov TSAN_INTERCEPT(accept); 194568230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov TSAN_INTERCEPT(accept4); 194668230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov TSAN_INTERCEPT(epoll_create); 194768230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov TSAN_INTERCEPT(epoll_create1); 1948ddeb2c354235818494d86827e88a0c2fa44bebccDmitry Vyukov TSAN_INTERCEPT(close); 194903f224835f46801a0e22cc2951d21b67304e0457Dmitry Vyukov TSAN_INTERCEPT(__close); 195003f224835f46801a0e22cc2951d21b67304e0457Dmitry Vyukov TSAN_INTERCEPT(__res_iclose); 1951ddeb2c354235818494d86827e88a0c2fa44bebccDmitry Vyukov TSAN_INTERCEPT(pipe); 1952ddeb2c354235818494d86827e88a0c2fa44bebccDmitry Vyukov TSAN_INTERCEPT(pipe2); 1953ddeb2c354235818494d86827e88a0c2fa44bebccDmitry Vyukov 19547ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(readv); 19557ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(preadv64); 19567ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(writev); 19577ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pwritev64); 19587ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(send); 19597ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(sendmsg); 19607ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(recv); 19617ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(recvmsg); 19627ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 19637ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(unlink); 19647ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(fopen); 1965c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov TSAN_INTERCEPT(freopen); 1966c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov TSAN_INTERCEPT(fclose); 19677ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(fread); 19687ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(fwrite); 19697ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(puts); 19707ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(rmdir); 19717ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(opendir); 19727ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 19737ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(epoll_ctl); 19747ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(epoll_wait); 1975ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov TSAN_INTERCEPT(poll); 19767ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 19777ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(sigaction); 1978d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov TSAN_INTERCEPT(signal); 1979d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov TSAN_INTERCEPT(raise); 1980d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov TSAN_INTERCEPT(kill); 1981d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov TSAN_INTERCEPT(pthread_kill); 1982848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov TSAN_INTERCEPT(sleep); 1983848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov TSAN_INTERCEPT(usleep); 1984848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov TSAN_INTERCEPT(nanosleep); 1985aad173b2f1dae9f88bbffd217ebd46ed1f020bcbDmitry Vyukov TSAN_INTERCEPT(gettimeofday); 19867ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 198792733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov TSAN_INTERCEPT(mlock); 198892733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov TSAN_INTERCEPT(munlock); 198992733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov TSAN_INTERCEPT(mlockall); 199092733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov TSAN_INTERCEPT(munlockall); 199192733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov 19924554b7a7b345cd50ff8138b3cda8dd1135b965faDmitry Vyukov TSAN_INTERCEPT(fork); 199331c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov TSAN_INTERCEPT(on_exit); 199431c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov TSAN_INTERCEPT(__cxa_atexit); 19954554b7a7b345cd50ff8138b3cda8dd1135b965faDmitry Vyukov 199691ac008b435b879bb366bcf9516c53f2d07c30b1Dmitry Vyukov // Need to setup it, because interceptors check that the function is resolved. 199791ac008b435b879bb366bcf9516c53f2d07c30b1Dmitry Vyukov // But atexit is emitted directly into the module, so can't be resolved. 199891ac008b435b879bb366bcf9516c53f2d07c30b1Dmitry Vyukov REAL(atexit) = (int(*)(void(*)()))unreachable; 19997ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany atexit_ctx = new(internal_alloc(MBlockAtExit, sizeof(AtExitContext))) 20007ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany AtExitContext(); 20017ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 200231c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov if (REAL(__cxa_atexit)(&finalize, 0, 0)) { 2003b1fe3021eca0843e37878d224ee7f32e32f40d99Alexey Samsonov Printf("ThreadSanitizer: failed to setup atexit callback\n"); 20047ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany Die(); 20057ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 20067ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 20077ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (pthread_key_create(&g_thread_finalize_key, &thread_finalize)) { 2008b1fe3021eca0843e37878d224ee7f32e32f40d99Alexey Samsonov Printf("ThreadSanitizer: failed to create thread key\n"); 20097ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany Die(); 20107ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 20113f4e6d9b75fb3f7f2674a31008738cfda9cda9edDmitry Vyukov 20123f4e6d9b75fb3f7f2674a31008738cfda9cda9edDmitry Vyukov FdInit(); 20137ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 20147ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 201526127735454fddae3495794f38189d57dde6510fDmitry Vyukovvoid internal_start_thread(void(*func)(void *arg), void *arg) { 201626127735454fddae3495794f38189d57dde6510fDmitry Vyukov void *th; 201726127735454fddae3495794f38189d57dde6510fDmitry Vyukov REAL(pthread_create)(&th, 0, (void*(*)(void *arg))func, arg); 201826127735454fddae3495794f38189d57dde6510fDmitry Vyukov REAL(pthread_detach)(th); 201926127735454fddae3495794f38189d57dde6510fDmitry Vyukov} 202026127735454fddae3495794f38189d57dde6510fDmitry Vyukov 20217ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} // namespace __tsan 2022