tsan_interceptors.cc revision f110e356170fbe990b99c0939d77eeaa89b25497
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" 1847b1634df012507799eb39aa17d4022d748ba67bAlexey Samsonov#include "sanitizer_common/sanitizer_placement_new.h" 197eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov#include "sanitizer_common/sanitizer_stacktrace.h" 2036decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov#include "interception/interception.h" 217ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#include "tsan_interface.h" 227ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#include "tsan_platform.h" 234f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov#include "tsan_rtl.h" 247ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany#include "tsan_mman.h" 25c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov#include "tsan_fd.h" 267ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 277ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyusing namespace __tsan; // NOLINT 287ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 29e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukovconst int kSigCount = 128; 30e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov 31e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukovstruct my_siginfo_t { 32e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov int opaque[128]; 33e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov}; 34e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov 357ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystruct sigset_t { 36e294d09d45aa97d1d2c8ee237ee2ac225442d330Dmitry Vyukov u64 val[1024 / 8 / sizeof(u64)]; 377ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}; 387ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 397ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystruct ucontext_t { 40a5562db12c5331433407ac21602086f34561c25cDmitry Vyukov uptr opaque[117]; 417ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}; 427ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 437ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyextern "C" int pthread_attr_init(void *attr); 447ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyextern "C" int pthread_attr_destroy(void *attr); 457ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyextern "C" int pthread_attr_getdetachstate(void *attr, int *v); 467ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyextern "C" int pthread_attr_setstacksize(void *attr, uptr stacksize); 477ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyextern "C" int pthread_attr_getstacksize(void *attr, uptr *stacksize); 487ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyextern "C" int pthread_key_create(unsigned *key, void (*destructor)(void* v)); 497ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyextern "C" int pthread_setspecific(unsigned key, const void *v); 507ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyextern "C" int pthread_mutexattr_gettype(void *a, int *type); 517ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyextern "C" int pthread_yield(); 527ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyextern "C" int pthread_sigmask(int how, const sigset_t *set, sigset_t *oldset); 537ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyextern "C" int sigfillset(sigset_t *set); 547ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyextern "C" void *pthread_self(); 557ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyextern "C" void _exit(int status); 567ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyextern "C" int *__errno_location(); 57f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukovextern "C" int fileno_unlocked(void *stream); 5831c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukovextern "C" void *__libc_malloc(uptr size); 5931c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukovextern "C" void *__libc_calloc(uptr size, uptr n); 6031c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukovextern "C" void *__libc_realloc(void *ptr, uptr size); 6131c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukovextern "C" void __libc_free(void *ptr); 627ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyconst int PTHREAD_MUTEX_RECURSIVE = 1; 637ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyconst int PTHREAD_MUTEX_RECURSIVE_NP = 1; 647ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyconst int kPthreadAttrSize = 56; 657ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyconst int EINVAL = 22; 667ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyconst int EBUSY = 16; 677ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyconst int EPOLL_CTL_ADD = 1; 68d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukovconst int SIGILL = 4; 69d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukovconst int SIGABRT = 6; 70d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukovconst int SIGFPE = 8; 71d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukovconst int SIGSEGV = 11; 72d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukovconst int SIGPIPE = 13; 73d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukovconst int SIGBUS = 7; 747ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyvoid *const MAP_FAILED = (void*)-1; 757ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyconst int PTHREAD_BARRIER_SERIAL_THREAD = -1; 767ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyconst int MAP_FIXED = 0x10; 777ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanytypedef long long_t; // NOLINT 787ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 790ce948e0887e2c23c6510c32a639da9730bbce25Alexander Potapenko// From /usr/include/unistd.h 800ce948e0887e2c23c6510c32a639da9730bbce25Alexander Potapenko# define F_ULOCK 0 /* Unlock a previously locked region. */ 810ce948e0887e2c23c6510c32a639da9730bbce25Alexander Potapenko# define F_LOCK 1 /* Lock a region for exclusive use. */ 820ce948e0887e2c23c6510c32a639da9730bbce25Alexander Potapenko# define F_TLOCK 2 /* Test and lock a region for exclusive use. */ 830ce948e0887e2c23c6510c32a639da9730bbce25Alexander Potapenko# define F_TEST 3 /* Test a region for other processes locks. */ 840ce948e0887e2c23c6510c32a639da9730bbce25Alexander Potapenko 857ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanytypedef void (*sighandler_t)(int sig); 867ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 877a72b4a0f04f7f043ab86396b0faa552f55aa857Dmitry Vyukov#define errno (*__errno_location()) 887a72b4a0f04f7f043ab86396b0faa552f55aa857Dmitry Vyukov 897ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystruct sigaction_t { 907ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany union { 917ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany sighandler_t sa_handler; 927ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany void (*sa_sigaction)(int sig, my_siginfo_t *siginfo, void *uctx); 937ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany }; 947ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany sigset_t sa_mask; 957ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int sa_flags; 967ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany void (*sa_restorer)(); 977ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}; 987ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 997ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyconst sighandler_t SIG_DFL = (sighandler_t)0; 1007ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyconst sighandler_t SIG_IGN = (sighandler_t)1; 101d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukovconst sighandler_t SIG_ERR = (sighandler_t)-1; 1027ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyconst int SA_SIGINFO = 4; 1037ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyconst int SIG_SETMASK = 2; 1047ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 1057eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonovnamespace std { 1067eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonovstruct nothrow_t {}; 1077eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov} // namespace std 1087eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov 1097ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic sigaction_t sigactions[kSigCount]; 1107ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 111e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukovnamespace __tsan { 112e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukovstruct SignalDesc { 113e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov bool armed; 114e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov bool sigaction; 115e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov my_siginfo_t siginfo; 116e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov ucontext_t ctx; 117e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov}; 118e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov 119e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukovstruct SignalContext { 120ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov int in_blocking_func; 121e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov int int_signal_send; 122e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov int pending_signal_count; 123e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov SignalDesc pending_signals[kSigCount]; 124e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov}; 125ba5e99668e3030cc5bab357a04271a1bdbac209cAlexey Samsonov} // namespace __tsan 126e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov 127e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukovstatic SignalContext *SigCtx(ThreadState *thr) { 128e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov SignalContext *ctx = (SignalContext*)thr->signal_ctx; 1291fc03d50a87302689482efa24b045a393097b6c3Dmitry Vyukov if (ctx == 0 && thr->is_alive) { 130e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov ScopedInRtl in_rtl; 131c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov ctx = (SignalContext*)MmapOrDie(sizeof(*ctx), "SignalContext"); 132c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov MemoryResetRange(thr, (uptr)&SigCtx, (uptr)ctx, sizeof(*ctx)); 133e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov thr->signal_ctx = ctx; 134e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov } 135e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov return ctx; 136e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov} 137e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov 1387ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic unsigned g_thread_finalize_key; 1397ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 14036decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukovclass ScopedInterceptor { 14136decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov public: 14236decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov ScopedInterceptor(ThreadState *thr, const char *fname, uptr pc); 14336decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov ~ScopedInterceptor(); 14436decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov private: 14536decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov ThreadState *const thr_; 14636decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov const int in_rtl_; 14736decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov}; 14836decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov 1494f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey SamsonovScopedInterceptor::ScopedInterceptor(ThreadState *thr, const char *fname, 1504f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov uptr pc) 1514f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov : thr_(thr) 1524f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov , in_rtl_(thr->in_rtl) { 1534f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov if (thr_->in_rtl == 0) { 1544f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov Initialize(thr); 1554f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov FuncEntry(thr, pc); 1564f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov thr_->in_rtl++; 1574f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov DPrintf("#%d: intercept %s()\n", thr_->tid, fname); 1584f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov } else { 1594f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov thr_->in_rtl++; 1607ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 16105906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov} 16205906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov 1634f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey SamsonovScopedInterceptor::~ScopedInterceptor() { 1644f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov thr_->in_rtl--; 1654f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov if (thr_->in_rtl == 0) { 1664f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov FuncExit(thr_); 167ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov ProcessPendingSignals(thr_); 1684f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov } 1694f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov CHECK_EQ(in_rtl_, thr_->in_rtl); 17005906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov} 17105906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov 17236decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov#define SCOPED_INTERCEPTOR_RAW(func, ...) \ 17336decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov ThreadState *thr = cur_thread(); \ 17436decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov StatInc(thr, StatInterceptor); \ 17536decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov StatInc(thr, StatInt_##func); \ 17636decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov const uptr caller_pc = GET_CALLER_PC(); \ 17736decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov ScopedInterceptor si(thr, #func, caller_pc); \ 178d2f08ffcb97726452f4ba11c199a1e06dc2a7e54Alexey Samsonov const uptr pc = __sanitizer::StackTrace::GetPreviousInstructionPc( \ 179d2f08ffcb97726452f4ba11c199a1e06dc2a7e54Alexey Samsonov __sanitizer::StackTrace::GetCurrentPc()); \ 18036decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov (void)pc; \ 18136decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov/**/ 18236decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov 18336decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov#define SCOPED_TSAN_INTERCEPTOR(func, ...) \ 18436decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov SCOPED_INTERCEPTOR_RAW(func, __VA_ARGS__); \ 18536decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov if (REAL(func) == 0) { \ 18636decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov Printf("FATAL: ThreadSanitizer: failed to intercept %s\n", #func); \ 18736decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov Die(); \ 18836decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov } \ 18936decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov if (thr->in_rtl > 1) \ 19036decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov return REAL(func)(__VA_ARGS__); \ 19136decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov/**/ 19236decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov 19336decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov#define TSAN_INTERCEPTOR(ret, func, ...) INTERCEPTOR(ret, func, __VA_ARGS__) 19436decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov#define TSAN_INTERCEPT(func) INTERCEPT_FUNCTION(func) 19536decbf426ea75eef9ce6f6f43b74a66e66795d3Dmitry Vyukov 196ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov#define BLOCK_REAL(name) (BlockingCall(thr), REAL(name)) 197ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov 198ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukovstruct BlockingCall { 199b717f4d415cafbb8526bb33f737b9c07409a73bbAlexey Samsonov explicit BlockingCall(ThreadState *thr) 200ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov : ctx(SigCtx(thr)) { 201ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov ctx->in_blocking_func++; 202ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov } 203ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov 204ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov ~BlockingCall() { 205ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov ctx->in_blocking_func--; 206ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov } 207ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov 208ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov SignalContext *ctx; 209ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov}; 210ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov 211848531192777acecf79747dc7c1ffeedf5c1da9fDmitry VyukovTSAN_INTERCEPTOR(unsigned, sleep, unsigned sec) { 212848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov SCOPED_TSAN_INTERCEPTOR(sleep, sec); 213ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov unsigned res = BLOCK_REAL(sleep)(sec); 214848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov AfterSleep(thr, pc); 215848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov return res; 216848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov} 217848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov 218848531192777acecf79747dc7c1ffeedf5c1da9fDmitry VyukovTSAN_INTERCEPTOR(int, usleep, long_t usec) { 219848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov SCOPED_TSAN_INTERCEPTOR(usleep, usec); 220ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov int res = BLOCK_REAL(usleep)(usec); 221848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov AfterSleep(thr, pc); 222848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov return res; 223848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov} 224848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov 225848531192777acecf79747dc7c1ffeedf5c1da9fDmitry VyukovTSAN_INTERCEPTOR(int, nanosleep, void *req, void *rem) { 226848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov SCOPED_TSAN_INTERCEPTOR(nanosleep, req, rem); 227ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov int res = BLOCK_REAL(nanosleep)(req, rem); 228848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov AfterSleep(thr, pc); 229848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov return res; 230848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov} 231848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov 2327ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyclass AtExitContext { 2337ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany public: 2347ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany AtExitContext() 2357ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany : mtx_(MutexTypeAtExit, StatMtxAtExit) 2367ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany , pos_() { 2377ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 2387ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 2397ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany typedef void(*atexit_t)(); 2407ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 24131c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov int atexit(ThreadState *thr, uptr pc, bool is_on_exit, 24231c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov atexit_t f, void *arg) { 2437ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany Lock l(&mtx_); 2447ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (pos_ == kMaxAtExit) 2457ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return 1; 2467ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany Release(thr, pc, (uptr)this); 2477ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany stack_[pos_] = f; 24831c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov args_[pos_] = arg; 24931c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov is_on_exits_[pos_] = is_on_exit; 2507ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany pos_++; 2517ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return 0; 2527ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 2537ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 2547ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany void exit(ThreadState *thr, uptr pc) { 2557ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany CHECK_EQ(thr->in_rtl, 0); 2567ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany for (;;) { 2577ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany atexit_t f = 0; 25831c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov void *arg = 0; 25931c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov bool is_on_exit = false; 2607ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany { 2617ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany Lock l(&mtx_); 2627ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (pos_) { 2637ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany pos_--; 2647ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany f = stack_[pos_]; 26531c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov arg = args_[pos_]; 26631c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov is_on_exit = is_on_exits_[pos_]; 2677ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany ScopedInRtl in_rtl; 2687ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany Acquire(thr, pc, (uptr)this); 2697ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 2707ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 2717ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (f == 0) 2727ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany break; 2737ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany DPrintf("#%d: executing atexit func %p\n", thr->tid, f); 2747ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany CHECK_EQ(thr->in_rtl, 0); 27531c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov if (is_on_exit) 27631c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov ((void(*)(int status, void *arg))f)(0, arg); 27731c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov else 27831c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov ((void(*)(void *arg, void *dso))f)(arg, 0); 2797ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 2807ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 2817ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 2827ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany private: 2837ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany static const int kMaxAtExit = 128; 2847ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany Mutex mtx_; 2857ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany atexit_t stack_[kMaxAtExit]; 28631c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov void *args_[kMaxAtExit]; 28731c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov bool is_on_exits_[kMaxAtExit]; 2887ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int pos_; 2897ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}; 2907ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 2917ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic AtExitContext *atexit_ctx; 2927ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 2937ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic void finalize(void *arg) { 2947ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany ThreadState * thr = cur_thread(); 2957ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany uptr pc = 0; 2967ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany atexit_ctx->exit(thr, pc); 2977ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int status = Finalize(cur_thread()); 298b7b6b1cd9df0c954b1f890fcebf373db984923b3Dmitry Vyukov if (status) 299b7b6b1cd9df0c954b1f890fcebf373db984923b3Dmitry Vyukov _exit(status); 3007ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 3017ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 3027ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, atexit, void (*f)()) { 30331c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov if (cur_thread()->in_symbolizer) 30431c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov return 0; 3057ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(atexit, f); 30631c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov return atexit_ctx->atexit(thr, pc, false, (void(*)())f, 0); 30731c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov} 30831c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov 30931c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry VyukovTSAN_INTERCEPTOR(int, on_exit, void(*f)(int, void*), void *arg) { 31031c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov if (cur_thread()->in_symbolizer) 31131c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov return 0; 31231c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(on_exit, f, arg); 31331c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov return atexit_ctx->atexit(thr, pc, true, (void(*)())f, arg); 31431c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov} 31531c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov 31631c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry VyukovTSAN_INTERCEPTOR(int, __cxa_atexit, void (*f)(void *a), void *arg, void *dso) { 31731c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov if (cur_thread()->in_symbolizer) 31831c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov return 0; 31931c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(__cxa_atexit, f, arg, dso); 32031c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov if (dso) 32131c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov return REAL(__cxa_atexit)(f, arg, dso); 32231c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov return atexit_ctx->atexit(thr, pc, false, (void(*)())f, arg); 3237ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 3247ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 325f037f565b2e02878ceb6e7b49647e814e2990ef5Dmitry VyukovTSAN_INTERCEPTOR(void, longjmp, void *env, int val) { 326f037f565b2e02878ceb6e7b49647e814e2990ef5Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(longjmp, env, val); 327b1fe3021eca0843e37878d224ee7f32e32f40d99Alexey Samsonov Printf("ThreadSanitizer: longjmp() is not supported\n"); 328f037f565b2e02878ceb6e7b49647e814e2990ef5Dmitry Vyukov Die(); 329f037f565b2e02878ceb6e7b49647e814e2990ef5Dmitry Vyukov} 330f037f565b2e02878ceb6e7b49647e814e2990ef5Dmitry Vyukov 331f037f565b2e02878ceb6e7b49647e814e2990ef5Dmitry VyukovTSAN_INTERCEPTOR(void, siglongjmp, void *env, int val) { 332f037f565b2e02878ceb6e7b49647e814e2990ef5Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(siglongjmp, env, val); 333b1fe3021eca0843e37878d224ee7f32e32f40d99Alexey Samsonov Printf("ThreadSanitizer: siglongjmp() is not supported\n"); 334f037f565b2e02878ceb6e7b49647e814e2990ef5Dmitry Vyukov Die(); 335f037f565b2e02878ceb6e7b49647e814e2990ef5Dmitry Vyukov} 336f037f565b2e02878ceb6e7b49647e814e2990ef5Dmitry Vyukov 3377ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(void*, malloc, uptr size) { 33831c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov if (cur_thread()->in_symbolizer) 33931c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov return __libc_malloc(size); 34005906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov void *p = 0; 34105906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov { 34205906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov SCOPED_INTERCEPTOR_RAW(malloc, size); 34305906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov p = user_alloc(thr, pc, size); 34405906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov } 34505906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov invoke_malloc_hook(p, size); 34605906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov return p; 3477ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 3487ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 34907ba8ef44deb54baa9307298fbffe25ddb30c362Dmitry VyukovTSAN_INTERCEPTOR(void*, __libc_memalign, uptr align, uptr sz) { 35007ba8ef44deb54baa9307298fbffe25ddb30c362Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(__libc_memalign, align, sz); 351543b94a5cd102c0795b44d78234d5458eed2c75eDmitry Vyukov return user_alloc(thr, pc, sz, align); 35207ba8ef44deb54baa9307298fbffe25ddb30c362Dmitry Vyukov} 35307ba8ef44deb54baa9307298fbffe25ddb30c362Dmitry Vyukov 3547ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(void*, calloc, uptr size, uptr n) { 35531c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov if (cur_thread()->in_symbolizer) 35631c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov return __libc_calloc(size, n); 35765199f1b253c4bfb225805629217acb8f0b1e185Kostya Serebryany if (__sanitizer::CallocShouldReturnNullDueToOverflow(size, n)) return 0; 35805906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov void *p = 0; 35905906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov { 36005906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov SCOPED_INTERCEPTOR_RAW(calloc, size, n); 36105906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov p = user_alloc(thr, pc, n * size); 3620ce948e0887e2c23c6510c32a639da9730bbce25Alexander Potapenko if (p) internal_memset(p, 0, n * size); 36305906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov } 36405906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov invoke_malloc_hook(p, n * size); 3657ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return p; 3667ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 3677ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 3687ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(void*, realloc, void *p, uptr size) { 36931c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov if (cur_thread()->in_symbolizer) 37031c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov return __libc_realloc(p, size); 37105906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov if (p) 37205906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov invoke_free_hook(p); 37305906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov { 37405906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov SCOPED_INTERCEPTOR_RAW(realloc, p, size); 37505906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov p = user_realloc(thr, pc, p, size); 37605906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov } 37705906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov invoke_malloc_hook(p, size); 37805906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov return p; 3797ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 3807ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 3817ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(void, free, void *p) { 3827ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (p == 0) 3837ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return; 38431c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov if (cur_thread()->in_symbolizer) 38531c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov return __libc_free(p); 38605906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov invoke_free_hook(p); 3877ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_INTERCEPTOR_RAW(free, p); 3887ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany user_free(thr, pc, p); 3897ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 3907ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 3917ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(void, cfree, void *p) { 3927ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (p == 0) 3937ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return; 39431c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov if (cur_thread()->in_symbolizer) 39531c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov return __libc_free(p); 39605906a7a12865b0fb0f5f6d607848cf7b5a1e5e0Dmitry Vyukov invoke_free_hook(p); 3977ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_INTERCEPTOR_RAW(cfree, p); 3987ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany user_free(thr, pc, p); 3997ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 4007ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 4018a6b5e551ab8a331f7e7bc4bfcd74926fbffa3f6Alexey SamsonovTSAN_INTERCEPTOR(uptr, malloc_usable_size, void *p) { 4028a6b5e551ab8a331f7e7bc4bfcd74926fbffa3f6Alexey Samsonov SCOPED_INTERCEPTOR_RAW(malloc_usable_size, p); 4038a6b5e551ab8a331f7e7bc4bfcd74926fbffa3f6Alexey Samsonov return user_alloc_usable_size(thr, pc, p); 4048a6b5e551ab8a331f7e7bc4bfcd74926fbffa3f6Alexey Samsonov} 4058a6b5e551ab8a331f7e7bc4bfcd74926fbffa3f6Alexey Samsonov 4067eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov#define OPERATOR_NEW_BODY(mangled_name) \ 40731c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov if (cur_thread()->in_symbolizer) \ 40831c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov return __libc_malloc(size); \ 4097eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov void *p = 0; \ 4107eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov { \ 4117eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov SCOPED_INTERCEPTOR_RAW(mangled_name, size); \ 4127eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov p = user_alloc(thr, pc, size); \ 4137eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov } \ 4147eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov invoke_malloc_hook(p, size); \ 4157eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov return p; 4167eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov 4177eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonovvoid *operator new(__sanitizer::uptr size) { 4187eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov OPERATOR_NEW_BODY(_Znwm); 4197eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov} 4207eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonovvoid *operator new[](__sanitizer::uptr size) { 4217eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov OPERATOR_NEW_BODY(_Znam); 4227eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov} 4237eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonovvoid *operator new(__sanitizer::uptr size, std::nothrow_t const&) { 4247eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov OPERATOR_NEW_BODY(_ZnwmRKSt9nothrow_t); 4257eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov} 4267eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonovvoid *operator new[](__sanitizer::uptr size, std::nothrow_t const&) { 4277eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov OPERATOR_NEW_BODY(_ZnamRKSt9nothrow_t); 4287eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov} 4297eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov 4307eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov#define OPERATOR_DELETE_BODY(mangled_name) \ 4317eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov if (ptr == 0) return; \ 43231c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov if (cur_thread()->in_symbolizer) \ 43331c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov return __libc_free(ptr); \ 4347eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov invoke_free_hook(ptr); \ 4357eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov SCOPED_INTERCEPTOR_RAW(mangled_name, ptr); \ 4367eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov user_free(thr, pc, ptr); 4377eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov 4387eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonovvoid operator delete(void *ptr) { 4397eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov OPERATOR_DELETE_BODY(_ZdlPv); 4407eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov} 4417eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonovvoid operator delete[](void *ptr) { 4427eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov OPERATOR_DELETE_BODY(_ZdlPvRKSt9nothrow_t); 4437eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov} 4447eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonovvoid operator delete(void *ptr, std::nothrow_t const&) { 4457eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov OPERATOR_DELETE_BODY(_ZdaPv); 4467eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov} 4477eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonovvoid operator delete[](void *ptr, std::nothrow_t const&) { 4487eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov OPERATOR_DELETE_BODY(_ZdaPvRKSt9nothrow_t); 4497eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov} 4507eff311e3e969ae084aadba7d7812591e34d08abAlexey Samsonov 451d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry VyukovTSAN_INTERCEPTOR(uptr, strlen, const char *s) { 4527ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(strlen, s); 453d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov uptr len = internal_strlen(s); 4547ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)s, len + 1, false); 4557ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return len; 4567ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 4577ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 458065c4ac846589d04436cb7f19f938ff42035313eDmitry VyukovTSAN_INTERCEPTOR(void*, memset, void *dst, int v, uptr size) { 459065c4ac846589d04436cb7f19f938ff42035313eDmitry Vyukov SCOPED_TSAN_INTERCEPTOR(memset, dst, v, size); 4607ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)dst, size, true); 461065c4ac846589d04436cb7f19f938ff42035313eDmitry Vyukov return internal_memset(dst, v, size); 4627ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 4637ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 464065c4ac846589d04436cb7f19f938ff42035313eDmitry VyukovTSAN_INTERCEPTOR(void*, memcpy, void *dst, const void *src, uptr size) { 465065c4ac846589d04436cb7f19f938ff42035313eDmitry Vyukov SCOPED_TSAN_INTERCEPTOR(memcpy, dst, src, size); 4667ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)dst, size, true); 4677ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)src, size, false); 468065c4ac846589d04436cb7f19f938ff42035313eDmitry Vyukov return internal_memcpy(dst, src, size); 4697ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 4707ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 471065c4ac846589d04436cb7f19f938ff42035313eDmitry VyukovTSAN_INTERCEPTOR(int, memcmp, const void *s1, const void *s2, uptr n) { 472065c4ac846589d04436cb7f19f938ff42035313eDmitry Vyukov SCOPED_TSAN_INTERCEPTOR(memcmp, s1, s2, n); 473d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov int res = 0; 474d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov uptr len = 0; 475d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov for (; len < n; len++) { 476d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov if ((res = ((unsigned char*)s1)[len] - ((unsigned char*)s2)[len])) 477d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov break; 478d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov } 479d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov MemoryAccessRange(thr, pc, (uptr)s1, len < n ? len + 1 : n, false); 480d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov MemoryAccessRange(thr, pc, (uptr)s2, len < n ? len + 1 : n, false); 481d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov return res; 482d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov} 483d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov 4847ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, strcmp, const char *s1, const char *s2) { 4857ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(strcmp, s1, s2); 4867ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany uptr len = 0; 4877ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany for (; s1[len] && s2[len]; len++) { 4887ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (s1[len] != s2[len]) 4897ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany break; 4907ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 4917ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)s1, len + 1, false); 4927ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)s2, len + 1, false); 4937ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return s1[len] - s2[len]; 4947ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 4957ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 4967ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr n) { 4977ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(strncmp, s1, s2, n); 4987ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany uptr len = 0; 4997d38634b30beed9bed44dfa6cb8e977ec51d7c6cDmitry Vyukov for (; len < n && s1[len] && s2[len]; len++) { 5007ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (s1[len] != s2[len]) 5017ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany break; 5027ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 5037ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)s1, len < n ? len + 1 : n, false); 5047ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)s2, len < n ? len + 1 : n, false); 5057ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return len == n ? 0 : s1[len] - s2[len]; 5067ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 5077ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 5087ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(void*, memchr, void *s, int c, uptr n) { 5097ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(memchr, s, c, n); 5107ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany void *res = REAL(memchr)(s, c, n); 5117ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany uptr len = res ? (char*)res - (char*)s + 1 : n; 5127ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)s, len, false); 5137ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 5147ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 5157ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 5167ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(void*, memrchr, char *s, int c, uptr n) { 5177ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(memrchr, s, c, n); 5187ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)s, n, false); 5197ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return REAL(memrchr)(s, c, n); 5207ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 5217ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 5227ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(void*, memmove, void *dst, void *src, uptr n) { 5237ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(memmove, dst, src, n); 5247ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)dst, n, true); 5257ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)src, n, false); 5267ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return REAL(memmove)(dst, src, n); 5277ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 5287ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 529d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry VyukovTSAN_INTERCEPTOR(char*, strchr, char *s, int c) { 5307ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(strchr, s, c); 531d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov char *res = REAL(strchr)(s, c); 532d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov uptr len = res ? (char*)res - (char*)s + 1 : internal_strlen(s) + 1; 5337ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)s, len, false); 5347ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 5357ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 5367ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 537d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry VyukovTSAN_INTERCEPTOR(char*, strchrnul, char *s, int c) { 5387ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(strchrnul, s, c); 539d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov char *res = REAL(strchrnul)(s, c); 5407ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany uptr len = (char*)res - (char*)s + 1; 5417ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)s, len, false); 5427ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 5437ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 5447ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 545d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry VyukovTSAN_INTERCEPTOR(char*, strrchr, char *s, int c) { 5467ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(strrchr, s, c); 547d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov MemoryAccessRange(thr, pc, (uptr)s, internal_strlen(s) + 1, false); 5487ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return REAL(strrchr)(s, c); 5497ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 5507ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 551d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry VyukovTSAN_INTERCEPTOR(char*, strcpy, char *dst, const char *src) { // NOLINT 5527ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(strcpy, dst, src); // NOLINT 553d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov uptr srclen = internal_strlen(src); 5547ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)dst, srclen + 1, true); 5557ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)src, srclen + 1, false); 5567ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return REAL(strcpy)(dst, src); // NOLINT 5577ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 5587ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 559d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry VyukovTSAN_INTERCEPTOR(char*, strncpy, char *dst, char *src, uptr n) { 5607ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(strncpy, dst, src, n); 561b93c3d5badc4066120edf3ed1c515cdd516a8776Kostya Serebryany uptr srclen = internal_strnlen(src, n); 5627ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)dst, n, true); 5637ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)src, min(srclen + 1, n), false); 5647ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return REAL(strncpy)(dst, src, n); 5657ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 5667ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 5677ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(const char*, strstr, const char *s1, const char *s2) { 5687ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(strstr, s1, s2); 5697ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany const char *res = REAL(strstr)(s1, s2); 570d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov uptr len1 = internal_strlen(s1); 571d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov uptr len2 = internal_strlen(s2); 5727ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)s1, len1 + 1, false); 5737ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryAccessRange(thr, pc, (uptr)s2, len2 + 1, false); 5747ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 5757ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 5767ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 5777ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic bool fix_mmap_addr(void **addr, long_t sz, int flags) { 5787ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (*addr) { 5797ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (!IsAppMem((uptr)*addr) || !IsAppMem((uptr)*addr + sz - 1)) { 5807ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (flags & MAP_FIXED) { 5817a72b4a0f04f7f043ab86396b0faa552f55aa857Dmitry Vyukov errno = EINVAL; 5827ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return false; 5837ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } else { 5847ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany *addr = 0; 5857ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 5867ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 5877ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 5887ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return true; 5897ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 5907ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 5917ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(void*, mmap, void *addr, long_t sz, int prot, 5927ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int flags, int fd, unsigned off) { 5937ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(mmap, addr, sz, prot, flags, fd, off); 5947ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (!fix_mmap_addr(&addr, sz, flags)) 5957ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return MAP_FAILED; 5967ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany void *res = REAL(mmap)(addr, sz, prot, flags, fd, off); 5977ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res != MAP_FAILED) { 598c05cbca0988c296068e0da1556bd6af7edd43c69Dmitry Vyukov if (fd > 0) 599c05cbca0988c296068e0da1556bd6af7edd43c69Dmitry Vyukov FdAccess(thr, pc, fd); 6007ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryResetRange(thr, pc, (uptr)res, sz); 6017ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 6027ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 6037ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 6047ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 6057ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(void*, mmap64, void *addr, long_t sz, int prot, 6067ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int flags, int fd, u64 off) { 6077ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(mmap64, addr, sz, prot, flags, fd, off); 6087ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (!fix_mmap_addr(&addr, sz, flags)) 6097ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return MAP_FAILED; 6107ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany void *res = REAL(mmap64)(addr, sz, prot, flags, fd, off); 6117ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res != MAP_FAILED) { 612c05cbca0988c296068e0da1556bd6af7edd43c69Dmitry Vyukov if (fd > 0) 613c05cbca0988c296068e0da1556bd6af7edd43c69Dmitry Vyukov FdAccess(thr, pc, fd); 6147ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany MemoryResetRange(thr, pc, (uptr)res, sz); 6157ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 6167ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 6177ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 6187ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 6197ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, munmap, void *addr, long_t sz) { 6207ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(munmap, addr, sz); 6217ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(munmap)(addr, sz); 6227ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 6237ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 6247ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 6257ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(void*, memalign, uptr align, uptr sz) { 6267ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(memalign, align, sz); 6272e87051d136db3150a3ca322d8862f92b0a684bbDmitry Vyukov return user_alloc(thr, pc, sz, align); 6287ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 6297ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 6307ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(void*, valloc, uptr sz) { 6317ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(valloc, sz); 632f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany return user_alloc(thr, pc, sz, GetPageSizeCached()); 6337ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 6347ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 6357ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(void*, pvalloc, uptr sz) { 6367ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pvalloc, sz); 637f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany sz = RoundUp(sz, GetPageSizeCached()); 638f67ec2b6e8d2ae328c27de0b026eea2d6667836eKostya Serebryany return user_alloc(thr, pc, sz, GetPageSizeCached()); 6397ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 6407ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 6417ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, posix_memalign, void **memptr, uptr align, uptr sz) { 6427ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(posix_memalign, memptr, align, sz); 6432e87051d136db3150a3ca322d8862f92b0a684bbDmitry Vyukov *memptr = user_alloc(thr, pc, sz, align); 6447ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return 0; 6457ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 6467ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 6477ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany// Used in thread-safe function static initialization. 6481ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukovextern "C" int INTERFACE_ATTRIBUTE __cxa_guard_acquire(atomic_uint32_t *g) { 6491ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov SCOPED_INTERCEPTOR_RAW(__cxa_guard_acquire, g); 6501ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov for (;;) { 6511ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov u32 cmp = atomic_load(g, memory_order_acquire); 6521ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov if (cmp == 0) { 6531ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov if (atomic_compare_exchange_strong(g, &cmp, 1<<16, memory_order_relaxed)) 6541ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov return 1; 6551ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov } else if (cmp == 1) { 6561ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov Acquire(thr, pc, (uptr)g); 6571ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov return 0; 6581ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov } else { 6591ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov internal_sched_yield(); 6601ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov } 6617ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 6627ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 6637ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 6641ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukovextern "C" void INTERFACE_ATTRIBUTE __cxa_guard_release(atomic_uint32_t *g) { 6651ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov SCOPED_INTERCEPTOR_RAW(__cxa_guard_release, g); 6661ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov Release(thr, pc, (uptr)g); 6671ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov atomic_store(g, 1, memory_order_release); 6681ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov} 6691ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov 6701ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukovextern "C" void INTERFACE_ATTRIBUTE __cxa_guard_abort(atomic_uint32_t *g) { 6711ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov SCOPED_INTERCEPTOR_RAW(__cxa_guard_abort, g); 6721ffeded71b960d8a0f018a46a0035203b1484a7aDmitry Vyukov atomic_store(g, 0, memory_order_relaxed); 6737ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 6747ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 6757ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic void thread_finalize(void *v) { 6767ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany uptr iter = (uptr)v; 6777ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (iter > 1) { 6787ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (pthread_setspecific(g_thread_finalize_key, (void*)(iter - 1))) { 679b1fe3021eca0843e37878d224ee7f32e32f40d99Alexey Samsonov Printf("ThreadSanitizer: failed to set thread key\n"); 6807ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany Die(); 6817ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 6827ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return; 6837ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 6847ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany { 6857ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany ScopedInRtl in_rtl; 686e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov ThreadState *thr = cur_thread(); 687e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov ThreadFinish(thr); 6881fc03d50a87302689482efa24b045a393097b6c3Dmitry Vyukov SignalContext *sctx = thr->signal_ctx; 6891fc03d50a87302689482efa24b045a393097b6c3Dmitry Vyukov if (sctx) { 6901fc03d50a87302689482efa24b045a393097b6c3Dmitry Vyukov thr->signal_ctx = 0; 691c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov UnmapOrDie(sctx, sizeof(*sctx)); 6921fc03d50a87302689482efa24b045a393097b6c3Dmitry Vyukov } 6937ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 6947ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 6957ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 6967ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 6977ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystruct ThreadParam { 6987ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany void* (*callback)(void *arg); 6997ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany void *param; 7007ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany atomic_uintptr_t tid; 7017ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany}; 7027ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 7037ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyextern "C" void *__tsan_thread_start_func(void *arg) { 7047ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany ThreadParam *p = (ThreadParam*)arg; 7057ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany void* (*callback)(void *arg) = p->callback; 7067ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany void *param = p->param; 7077ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int tid = 0; 7087ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany { 7097ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany ThreadState *thr = cur_thread(); 7107ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany ScopedInRtl in_rtl; 7117ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (pthread_setspecific(g_thread_finalize_key, (void*)4)) { 712b1fe3021eca0843e37878d224ee7f32e32f40d99Alexey Samsonov Printf("ThreadSanitizer: failed to set thread key\n"); 7137ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany Die(); 7147ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 7157ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany while ((tid = atomic_load(&p->tid, memory_order_acquire)) == 0) 7167ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany pthread_yield(); 7177ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany atomic_store(&p->tid, 0, memory_order_release); 7187dccf3f92a867f917ad19f9a6b37bcf93e64b35bDmitry Vyukov ThreadStart(thr, tid, GetTid()); 7197ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany CHECK_EQ(thr->in_rtl, 1); 7207ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 7217ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany void *res = callback(param); 7227ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany // Prevent the callback from being tail called, 7237ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany // it mixes up stack traces. 7247ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany volatile int foo = 42; 7257ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany foo++; 7267ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 7277ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 7287ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 7297ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_create, 7307ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany void *th, void *attr, void *(*callback)(void*), void * param) { 7317ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_create, th, attr, callback, param); 732f110e356170fbe990b99c0939d77eeaa89b25497Alexey Samsonov __sanitizer_pthread_attr_t myattr; 7337ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (attr == 0) { 7347ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany pthread_attr_init(&myattr); 7357ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany attr = &myattr; 7367ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 7377ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int detached = 0; 7387ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany pthread_attr_getdetachstate(attr, &detached); 7397ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany uptr stacksize = 0; 7407ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany pthread_attr_getstacksize(attr, &stacksize); 7417ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany // We place the huge ThreadState object into TLS, account for that. 7427ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany const uptr minstacksize = GetTlsSize() + 128*1024; 7437ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (stacksize < minstacksize) { 744e954101f6602ac181a2c3accfbbad0ae51b0bf7cAlexey Samsonov DPrintf("ThreadSanitizer: stacksize %zu->%zu\n", stacksize, minstacksize); 7457ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany pthread_attr_setstacksize(attr, minstacksize); 7467ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 7477ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany ThreadParam p; 7487ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany p.callback = callback; 7497ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany p.param = param; 7507ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany atomic_store(&p.tid, 0, memory_order_relaxed); 7517ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_create)(th, attr, __tsan_thread_start_func, &p); 7527ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 75364310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov int tid = ThreadCreate(thr, pc, *(uptr*)th, detached); 7547ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany CHECK_NE(tid, 0); 7557ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany atomic_store(&p.tid, tid, memory_order_release); 7567ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany while (atomic_load(&p.tid, memory_order_acquire) != 0) 7577ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany pthread_yield(); 7587ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 7597ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (attr == &myattr) 7607ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany pthread_attr_destroy(&myattr); 7617ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 7627ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 7637ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 7647ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_join, void *th, void **ret) { 7657ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_join, th, ret); 7667ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int tid = ThreadTid(thr, pc, (uptr)th); 767ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov int res = BLOCK_REAL(pthread_join)(th, ret); 7687ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 76964310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov ThreadJoin(thr, pc, tid); 7707ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 7717ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 7727ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 7737ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 7747ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_detach, void *th) { 7757ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_detach, th); 7767ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int tid = ThreadTid(thr, pc, (uptr)th); 7777ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_detach)(th); 7787ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 77964310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov ThreadDetach(thr, pc, tid); 7807ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 7817ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 7827ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 7837ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 7847ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_mutex_init, void *m, void *a) { 7857ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_mutex_init, m, a); 7867ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_mutex_init)(m, a); 7877ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 7887ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany bool recursive = false; 7897ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (a) { 7907ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int type = 0; 7917ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (pthread_mutexattr_gettype(a, &type) == 0) 7927ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany recursive = (type == PTHREAD_MUTEX_RECURSIVE 7937ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany || type == PTHREAD_MUTEX_RECURSIVE_NP); 7947ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 795c20e9ba760a93706c9160133cdcce62194f9694fDmitry Vyukov MutexCreate(thr, pc, (uptr)m, false, recursive, false); 7967ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 7977ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 7987ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 7997ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 8007ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_mutex_destroy, void *m) { 8017ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_mutex_destroy, m); 8027ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_mutex_destroy)(m); 8037ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0 || res == EBUSY) { 80464310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexDestroy(thr, pc, (uptr)m); 8057ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 8067ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 8077ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 8087ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 8097ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_mutex_lock, void *m) { 8107ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_mutex_lock, m); 8117ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_mutex_lock)(m); 8127ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 81364310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexLock(thr, pc, (uptr)m); 8147ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 8157ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 8167ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 8177ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 8187ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_mutex_trylock, void *m) { 8197ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_mutex_trylock, m); 8207ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_mutex_trylock)(m); 8217ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 82264310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexLock(thr, pc, (uptr)m); 8237ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 8247ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 8257ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 8267ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 8277ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_mutex_timedlock, void *m, void *abstime) { 8287ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_mutex_timedlock, m, abstime); 8297ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_mutex_timedlock)(m, abstime); 8307ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 83164310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexLock(thr, pc, (uptr)m); 8327ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 8337ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 8347ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 8357ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 8367ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_mutex_unlock, void *m) { 8377ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_mutex_unlock, m); 83864310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexUnlock(thr, pc, (uptr)m); 8397ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_mutex_unlock)(m); 8407ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 8417ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 8427ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 8437ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_spin_init, void *m, int pshared) { 8447ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_spin_init, m, pshared); 8457ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_spin_init)(m, pshared); 8467ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 847c20e9ba760a93706c9160133cdcce62194f9694fDmitry Vyukov MutexCreate(thr, pc, (uptr)m, false, false, false); 8487ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 8497ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 8507ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 8517ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 8527ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_spin_destroy, void *m) { 8537ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_spin_destroy, m); 8547ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_spin_destroy)(m); 8557ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 85664310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexDestroy(thr, pc, (uptr)m); 8577ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 8587ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 8597ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 8607ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 8617ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_spin_lock, void *m) { 8627ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_spin_lock, m); 8637ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_spin_lock)(m); 8647ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 86564310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexLock(thr, pc, (uptr)m); 8667ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 8677ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 8687ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 8697ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 8707ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_spin_trylock, void *m) { 8717ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_spin_trylock, m); 8727ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_spin_trylock)(m); 8737ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 87464310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexLock(thr, pc, (uptr)m); 8757ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 8767ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 8777ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 8787ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 8797ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_spin_unlock, void *m) { 8807ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_spin_unlock, m); 88164310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexUnlock(thr, pc, (uptr)m); 8827ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_spin_unlock)(m); 8837ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 8847ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 8857ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 8867ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_rwlock_init, void *m, void *a) { 8877ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_init, m, a); 8887ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_rwlock_init)(m, a); 8897ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 890c20e9ba760a93706c9160133cdcce62194f9694fDmitry Vyukov MutexCreate(thr, pc, (uptr)m, true, false, false); 8917ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 8927ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 8937ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 8947ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 8957ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_rwlock_destroy, void *m) { 8967ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_destroy, m); 8977ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_rwlock_destroy)(m); 8987ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 89964310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexDestroy(thr, pc, (uptr)m); 9007ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 9017ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 9027ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 9037ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 9047ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_rwlock_rdlock, void *m) { 9057ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_rdlock, m); 9067ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_rwlock_rdlock)(m); 9077ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 90864310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexReadLock(thr, pc, (uptr)m); 9097ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 9107ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 9117ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 9127ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 9137ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_rwlock_tryrdlock, void *m) { 9147ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_tryrdlock, m); 9157ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_rwlock_tryrdlock)(m); 9167ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 91764310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexReadLock(thr, pc, (uptr)m); 9187ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 9197ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 9207ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 9217ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 9227ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_rwlock_timedrdlock, void *m, void *abstime) { 9237ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_timedrdlock, m, abstime); 9247ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_rwlock_timedrdlock)(m, abstime); 9257ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 92664310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexReadLock(thr, pc, (uptr)m); 9277ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 9287ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 9297ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 9307ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 9317ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_rwlock_wrlock, void *m) { 9327ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_wrlock, m); 9337ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_rwlock_wrlock)(m); 9347ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 93564310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexLock(thr, pc, (uptr)m); 9367ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 9377ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 9387ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 9397ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 9407ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_rwlock_trywrlock, void *m) { 9417ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_trywrlock, m); 9427ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_rwlock_trywrlock)(m); 9437ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 94464310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexLock(thr, pc, (uptr)m); 9457ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 9467ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 9477ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 9487ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 9497ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_rwlock_timedwrlock, void *m, void *abstime) { 9507ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_timedwrlock, m, abstime); 9517ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_rwlock_timedwrlock)(m, abstime); 9527ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 95364310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexLock(thr, pc, (uptr)m); 9547ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 9557ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 9567ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 9577ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 9587ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_rwlock_unlock, void *m) { 9597ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_rwlock_unlock, m); 96064310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexReadOrWriteUnlock(thr, pc, (uptr)m); 9617ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_rwlock_unlock)(m); 9627ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 9637ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 9647ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 965703e4e4a133aa6585361a2c6130cfc2874efff75Dmitry Vyukov// libpthread.so contains several versions of pthread_cond_init symbol. 966703e4e4a133aa6585361a2c6130cfc2874efff75Dmitry Vyukov// When we just dlsym() it, we get the wrong (old) version. 967c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov/* 9687ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_cond_init, void *c, void *a) { 9697ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_cond_init, c, a); 9707ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_cond_init)(c, a); 9717ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 9727ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 973c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov*/ 9747ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 9757ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_cond_destroy, void *c) { 9767ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_cond_destroy, c); 9777ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_cond_destroy)(c); 9787ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 9797ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 9807ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 9817ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_cond_signal, void *c) { 9827ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_cond_signal, c); 9837ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_cond_signal)(c); 9847ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 9857ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 9867ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 9877ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_cond_broadcast, void *c) { 9887ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_cond_broadcast, c); 9897ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_cond_broadcast)(c); 9907ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 9917ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 9927ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 9937ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_cond_wait, void *c, void *m) { 9947ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_cond_wait, c, m); 99564310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexUnlock(thr, pc, (uptr)m); 9967ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_cond_wait)(c, m); 99764310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexLock(thr, pc, (uptr)m); 9987ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 9997ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 10007ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 10017ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_cond_timedwait, void *c, void *m, void *abstime) { 10027ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_cond_timedwait, c, m, abstime); 100364310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexUnlock(thr, pc, (uptr)m); 10047ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_cond_timedwait)(c, m, abstime); 100564310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov MutexLock(thr, pc, (uptr)m); 10067ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 10077ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 10087ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 10097ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_barrier_init, void *b, void *a, unsigned count) { 10107ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_barrier_init, b, a, count); 1011334553ec45d8982df45a6f5e656e068142ecde3fDmitry Vyukov MemoryWrite(thr, pc, (uptr)b, kSizeLog1); 10127ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_barrier_init)(b, a, count); 10137ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 10147ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 10157ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 10167ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_barrier_destroy, void *b) { 10177ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_barrier_destroy, b); 1018334553ec45d8982df45a6f5e656e068142ecde3fDmitry Vyukov MemoryWrite(thr, pc, (uptr)b, kSizeLog1); 10197ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_barrier_destroy)(b); 10207ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 10217ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 10227ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 10237ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_barrier_wait, void *b) { 10247ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_barrier_wait, b); 102564310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov Release(thr, pc, (uptr)b); 1026334553ec45d8982df45a6f5e656e068142ecde3fDmitry Vyukov MemoryRead(thr, pc, (uptr)b, kSizeLog1); 10277ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pthread_barrier_wait)(b); 1028334553ec45d8982df45a6f5e656e068142ecde3fDmitry Vyukov MemoryRead(thr, pc, (uptr)b, kSizeLog1); 10297ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0 || res == PTHREAD_BARRIER_SERIAL_THREAD) { 103064310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov Acquire(thr, pc, (uptr)b); 10317ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 10327ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 10337ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 10347ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 10357ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, pthread_once, void *o, void (*f)()) { 10367ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pthread_once, o, f); 10377ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (o == 0 || f == 0) 10387ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return EINVAL; 10397ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany atomic_uint32_t *a = static_cast<atomic_uint32_t*>(o); 10407ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany u32 v = atomic_load(a, memory_order_acquire); 10417ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (v == 0 && atomic_compare_exchange_strong(a, &v, 1, 10427ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany memory_order_relaxed)) { 10437ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany const int old_in_rtl = thr->in_rtl; 10447ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany thr->in_rtl = 0; 10457ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany (*f)(); 10467ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany CHECK_EQ(thr->in_rtl, 0); 10477ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany thr->in_rtl = old_in_rtl; 104864310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov Release(thr, pc, (uptr)o); 10497ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany atomic_store(a, 2, memory_order_release); 10507ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } else { 10517ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany while (v != 2) { 10527ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany pthread_yield(); 10537ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany v = atomic_load(a, memory_order_acquire); 10547ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 105564310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov Acquire(thr, pc, (uptr)o); 10567ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 10577ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return 0; 10587ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 10597ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 10607ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, sem_init, void *s, int pshared, unsigned value) { 10617ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(sem_init, s, pshared, value); 10627ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(sem_init)(s, pshared, value); 10637ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 10647ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 10657ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 10667ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, sem_destroy, void *s) { 10677ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(sem_destroy, s); 10687ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(sem_destroy)(s); 10697ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 10707ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 10717ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 10727ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, sem_wait, void *s) { 10737ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(sem_wait, s); 1074ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov int res = BLOCK_REAL(sem_wait)(s); 10757ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 107664310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov Acquire(thr, pc, (uptr)s); 10777ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 10787ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 10797ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 10807ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 10817ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, sem_trywait, void *s) { 10827ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(sem_trywait, s); 1083ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov int res = BLOCK_REAL(sem_trywait)(s); 10847ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 108564310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov Acquire(thr, pc, (uptr)s); 10867ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 10877ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 10887ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 10897ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 10907ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, sem_timedwait, void *s, void *abstime) { 10917ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(sem_timedwait, s, abstime); 1092ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov int res = BLOCK_REAL(sem_timedwait)(s, abstime); 10937ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 109464310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov Acquire(thr, pc, (uptr)s); 10957ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 10967ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 10977ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 10987ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 10997ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, sem_post, void *s) { 11007ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(sem_post, s); 110164310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov Release(thr, pc, (uptr)s); 11027ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(sem_post)(s); 11037ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 11047ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 11057ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 11067ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, sem_getvalue, void *s, int *sval) { 11077ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(sem_getvalue, s, sval); 11087ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(sem_getvalue)(s, sval); 11097ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (res == 0) { 111064310b28c4e418573ddfda2dbedd702ccf20a051Dmitry Vyukov Acquire(thr, pc, (uptr)s); 11117ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 11127ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 11137ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 11147ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 111561ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry VyukovTSAN_INTERCEPTOR(int, __xstat, int version, const char *path, void *buf) { 111661ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(__xstat, version, path, buf); 111761ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov return REAL(__xstat)(version, path, buf); 111861ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov} 111961ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov 112061ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry VyukovTSAN_INTERCEPTOR(int, stat, const char *path, void *buf) { 112161ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(__xstat, 0, path, buf); 112261ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov return REAL(__xstat)(0, path, buf); 112361ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov} 112461ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov 112561ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry VyukovTSAN_INTERCEPTOR(int, __xstat64, int version, const char *path, void *buf) { 112661ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(__xstat64, version, path, buf); 112761ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov return REAL(__xstat64)(version, path, buf); 112861ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov} 112961ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov 113061ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry VyukovTSAN_INTERCEPTOR(int, stat64, const char *path, void *buf) { 113161ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(__xstat64, 0, path, buf); 113261ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov return REAL(__xstat64)(0, path, buf); 113361ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov} 113461ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov 113561ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry VyukovTSAN_INTERCEPTOR(int, __lxstat, int version, const char *path, void *buf) { 113661ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(__lxstat, version, path, buf); 113761ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov return REAL(__lxstat)(version, path, buf); 113861ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov} 113961ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov 114061ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry VyukovTSAN_INTERCEPTOR(int, lstat, const char *path, void *buf) { 114161ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(__lxstat, 0, path, buf); 114261ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov return REAL(__lxstat)(0, path, buf); 114361ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov} 114461ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov 114561ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry VyukovTSAN_INTERCEPTOR(int, __lxstat64, int version, const char *path, void *buf) { 114661ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(__lxstat64, version, path, buf); 114761ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov return REAL(__lxstat64)(version, path, buf); 114861ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov} 114961ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov 115061ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry VyukovTSAN_INTERCEPTOR(int, lstat64, const char *path, void *buf) { 115161ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(__lxstat64, 0, path, buf); 115261ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov return REAL(__lxstat64)(0, path, buf); 115361ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov} 115461ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov 115561ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry VyukovTSAN_INTERCEPTOR(int, __fxstat, int version, int fd, void *buf) { 115661ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(__fxstat, version, fd, buf); 1157c05cbca0988c296068e0da1556bd6af7edd43c69Dmitry Vyukov if (fd > 0) 1158c05cbca0988c296068e0da1556bd6af7edd43c69Dmitry Vyukov FdAccess(thr, pc, fd); 115961ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov return REAL(__fxstat)(version, fd, buf); 116061ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov} 116161ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov 116261ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry VyukovTSAN_INTERCEPTOR(int, fstat, int fd, void *buf) { 116361ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(__fxstat, 0, fd, buf); 1164c05cbca0988c296068e0da1556bd6af7edd43c69Dmitry Vyukov if (fd > 0) 1165c05cbca0988c296068e0da1556bd6af7edd43c69Dmitry Vyukov FdAccess(thr, pc, fd); 116661ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov return REAL(__fxstat)(0, fd, buf); 116761ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov} 116861ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov 116961ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry VyukovTSAN_INTERCEPTOR(int, __fxstat64, int version, int fd, void *buf) { 117061ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(__fxstat64, version, fd, buf); 1171c05cbca0988c296068e0da1556bd6af7edd43c69Dmitry Vyukov if (fd > 0) 1172c05cbca0988c296068e0da1556bd6af7edd43c69Dmitry Vyukov FdAccess(thr, pc, fd); 117361ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov return REAL(__fxstat64)(version, fd, buf); 117461ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov} 117561ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov 117661ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry VyukovTSAN_INTERCEPTOR(int, fstat64, int fd, void *buf) { 117761ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(__fxstat64, 0, fd, buf); 1178c05cbca0988c296068e0da1556bd6af7edd43c69Dmitry Vyukov if (fd > 0) 1179c05cbca0988c296068e0da1556bd6af7edd43c69Dmitry Vyukov FdAccess(thr, pc, fd); 118061ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov return REAL(__fxstat64)(0, fd, buf); 118161ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov} 118261ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov 1183ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry VyukovTSAN_INTERCEPTOR(int, open, const char *name, int flags, int mode) { 1184ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(open, name, flags, mode); 1185ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov int fd = REAL(open)(name, flags, mode); 1186ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov if (fd >= 0) 118768230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov FdFileCreate(thr, pc, fd); 1188ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov return fd; 1189ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov} 1190ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov 1191c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry VyukovTSAN_INTERCEPTOR(int, open64, const char *name, int flags, int mode) { 1192c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov SCOPED_TSAN_INTERCEPTOR(open64, name, flags, mode); 1193c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov int fd = REAL(open64)(name, flags, mode); 1194c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov if (fd >= 0) 1195c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov FdFileCreate(thr, pc, fd); 1196c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov return fd; 1197c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov} 1198c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov 1199ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry VyukovTSAN_INTERCEPTOR(int, creat, const char *name, int mode) { 1200ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(creat, name, mode); 1201ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov int fd = REAL(creat)(name, mode); 1202ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov if (fd >= 0) 120368230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov FdFileCreate(thr, pc, fd); 1204ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov return fd; 1205ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov} 1206ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov 1207c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry VyukovTSAN_INTERCEPTOR(int, creat64, const char *name, int mode) { 1208c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov SCOPED_TSAN_INTERCEPTOR(creat64, name, mode); 1209c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov int fd = REAL(creat64)(name, mode); 1210c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov if (fd >= 0) 1211c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov FdFileCreate(thr, pc, fd); 1212c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov return fd; 1213c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov} 1214c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov 1215ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry VyukovTSAN_INTERCEPTOR(int, dup, int oldfd) { 1216ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(dup, oldfd); 1217ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov int newfd = REAL(dup)(oldfd); 1218b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (oldfd >= 0 && newfd >= 0 && newfd != oldfd) 1219ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov FdDup(thr, pc, oldfd, newfd); 1220ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov return newfd; 1221ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov} 1222ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov 1223ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry VyukovTSAN_INTERCEPTOR(int, dup2, int oldfd, int newfd) { 1224ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(dup2, oldfd, newfd); 1225ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov int newfd2 = REAL(dup2)(oldfd, newfd); 1226b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (oldfd >= 0 && newfd2 >= 0 && newfd2 != oldfd) 1227ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov FdDup(thr, pc, oldfd, newfd2); 1228ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov return newfd2; 1229ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov} 1230ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov 1231ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry VyukovTSAN_INTERCEPTOR(int, dup3, int oldfd, int newfd, int flags) { 1232ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(dup3, oldfd, newfd, flags); 1233ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov int newfd2 = REAL(dup3)(oldfd, newfd, flags); 1234b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (oldfd >= 0 && newfd2 >= 0 && newfd2 != oldfd) 1235ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov FdDup(thr, pc, oldfd, newfd2); 1236ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov return newfd2; 1237ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov} 1238ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov 123968230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry VyukovTSAN_INTERCEPTOR(int, eventfd, unsigned initval, int flags) { 124068230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(eventfd, initval, flags); 124168230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov int fd = REAL(eventfd)(initval, flags); 124268230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov if (fd >= 0) 124368230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov FdEventCreate(thr, pc, fd); 124468230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov return fd; 124568230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov} 124668230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov 124745d4324bf5b0ec282f0a8f96312233e09a882502Dmitry VyukovTSAN_INTERCEPTOR(int, signalfd, int fd, void *mask, int flags) { 124845d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(signalfd, fd, mask, flags); 1249b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (fd >= 0) 1250b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov FdClose(thr, pc, fd); 125145d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov fd = REAL(signalfd)(fd, mask, flags); 125245d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov if (fd >= 0) 125345d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov FdSignalCreate(thr, pc, fd); 125445d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov return fd; 125545d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov} 125645d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov 1257b75c67b495ca13801cc629b2c2c9dd0010e54739Dmitry VyukovTSAN_INTERCEPTOR(int, inotify_init, int fake) { 1258b75c67b495ca13801cc629b2c2c9dd0010e54739Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(inotify_init, fake); 1259b75c67b495ca13801cc629b2c2c9dd0010e54739Dmitry Vyukov int fd = REAL(inotify_init)(fake); 126045d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov if (fd >= 0) 126145d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov FdInotifyCreate(thr, pc, fd); 126245d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov return fd; 126345d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov} 126445d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov 126545d4324bf5b0ec282f0a8f96312233e09a882502Dmitry VyukovTSAN_INTERCEPTOR(int, inotify_init1, int flags) { 126645d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(inotify_init1, flags); 126745d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov int fd = REAL(inotify_init1)(flags); 126845d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov if (fd >= 0) 126945d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov FdInotifyCreate(thr, pc, fd); 127045d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov return fd; 127145d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov} 127245d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov 127368230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry VyukovTSAN_INTERCEPTOR(int, socket, int domain, int type, int protocol) { 127468230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(socket, domain, type, protocol); 127568230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov int fd = REAL(socket)(domain, type, protocol); 127668230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov if (fd >= 0) 127768230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov FdSocketCreate(thr, pc, fd); 127868230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov return fd; 127968230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov} 128068230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov 1281983518e360a179d92bdbddebe05a87db3c6cc3c0Dmitry VyukovTSAN_INTERCEPTOR(int, socketpair, int domain, int type, int protocol, int *fd) { 1282983518e360a179d92bdbddebe05a87db3c6cc3c0Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(socketpair, domain, type, protocol, fd); 1283983518e360a179d92bdbddebe05a87db3c6cc3c0Dmitry Vyukov int res = REAL(socketpair)(domain, type, protocol, fd); 1284983518e360a179d92bdbddebe05a87db3c6cc3c0Dmitry Vyukov if (res == 0 && fd[0] >= 0 && fd[1] >= 0) 1285983518e360a179d92bdbddebe05a87db3c6cc3c0Dmitry Vyukov FdPipeCreate(thr, pc, fd[0], fd[1]); 1286983518e360a179d92bdbddebe05a87db3c6cc3c0Dmitry Vyukov return res; 1287983518e360a179d92bdbddebe05a87db3c6cc3c0Dmitry Vyukov} 1288983518e360a179d92bdbddebe05a87db3c6cc3c0Dmitry Vyukov 128968230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry VyukovTSAN_INTERCEPTOR(int, connect, int fd, void *addr, unsigned addrlen) { 129068230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(connect, fd, addr, addrlen); 1291ed513f69b8017a69214509105e7ec59fec77b468Dmitry Vyukov FdSocketConnecting(thr, pc, fd); 129268230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov int res = REAL(connect)(fd, addr, addrlen); 1293b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (res == 0 && fd >= 0) 129468230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov FdSocketConnect(thr, pc, fd); 129568230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov return res; 129668230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov} 129768230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov 129852c70e5818727521b89f7fc95a2a383df8985ca6Dmitry VyukovTSAN_INTERCEPTOR(int, bind, int fd, void *addr, unsigned addrlen) { 129952c70e5818727521b89f7fc95a2a383df8985ca6Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(bind, fd, addr, addrlen); 130052c70e5818727521b89f7fc95a2a383df8985ca6Dmitry Vyukov int res = REAL(bind)(fd, addr, addrlen); 130152c70e5818727521b89f7fc95a2a383df8985ca6Dmitry Vyukov if (fd > 0 && res == 0) 130252c70e5818727521b89f7fc95a2a383df8985ca6Dmitry Vyukov FdAccess(thr, pc, fd); 130352c70e5818727521b89f7fc95a2a383df8985ca6Dmitry Vyukov return res; 130452c70e5818727521b89f7fc95a2a383df8985ca6Dmitry Vyukov} 130552c70e5818727521b89f7fc95a2a383df8985ca6Dmitry Vyukov 130652c70e5818727521b89f7fc95a2a383df8985ca6Dmitry VyukovTSAN_INTERCEPTOR(int, listen, int fd, int backlog) { 130752c70e5818727521b89f7fc95a2a383df8985ca6Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(listen, fd, backlog); 130852c70e5818727521b89f7fc95a2a383df8985ca6Dmitry Vyukov int res = REAL(listen)(fd, backlog); 130952c70e5818727521b89f7fc95a2a383df8985ca6Dmitry Vyukov if (fd > 0 && res == 0) 131052c70e5818727521b89f7fc95a2a383df8985ca6Dmitry Vyukov FdAccess(thr, pc, fd); 131152c70e5818727521b89f7fc95a2a383df8985ca6Dmitry Vyukov return res; 131252c70e5818727521b89f7fc95a2a383df8985ca6Dmitry Vyukov} 131352c70e5818727521b89f7fc95a2a383df8985ca6Dmitry Vyukov 131468230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry VyukovTSAN_INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) { 131568230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(accept, fd, addr, addrlen); 131668230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov int fd2 = REAL(accept)(fd, addr, addrlen); 1317b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (fd >= 0 && fd2 >= 0) 131868230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov FdSocketAccept(thr, pc, fd, fd2); 131968230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov return fd2; 132068230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov} 132168230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov 132268230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry VyukovTSAN_INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) { 132368230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(accept4, fd, addr, addrlen, f); 132468230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov int fd2 = REAL(accept4)(fd, addr, addrlen, f); 1325b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (fd >= 0 && fd2 >= 0) 132668230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov FdSocketAccept(thr, pc, fd, fd2); 132768230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov return fd2; 132868230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov} 132968230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov 133068230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry VyukovTSAN_INTERCEPTOR(int, epoll_create, int size) { 133168230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(epoll_create, size); 133268230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov int fd = REAL(epoll_create)(size); 133368230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov if (fd >= 0) 133468230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov FdPollCreate(thr, pc, fd); 133568230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov return fd; 133668230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov} 133768230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov 133868230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry VyukovTSAN_INTERCEPTOR(int, epoll_create1, int flags) { 133968230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(epoll_create1, flags); 134068230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov int fd = REAL(epoll_create1)(flags); 134168230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov if (fd >= 0) 134268230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov FdPollCreate(thr, pc, fd); 134368230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov return fd; 134468230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov} 134568230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov 1346ddeb2c354235818494d86827e88a0c2fa44bebccDmitry VyukovTSAN_INTERCEPTOR(int, close, int fd) { 1347ddeb2c354235818494d86827e88a0c2fa44bebccDmitry Vyukov SCOPED_TSAN_INTERCEPTOR(close, fd); 1348c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov if (fd >= 0) 1349c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov FdClose(thr, pc, fd); 1350ddeb2c354235818494d86827e88a0c2fa44bebccDmitry Vyukov return REAL(close)(fd); 1351ddeb2c354235818494d86827e88a0c2fa44bebccDmitry Vyukov} 1352ddeb2c354235818494d86827e88a0c2fa44bebccDmitry Vyukov 1353c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry VyukovTSAN_INTERCEPTOR(int, __close, int fd) { 1354c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov SCOPED_TSAN_INTERCEPTOR(__close, fd); 1355c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov if (fd >= 0) 1356c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov FdClose(thr, pc, fd); 1357c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov return REAL(__close)(fd); 1358c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov} 1359c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov 136003f224835f46801a0e22cc2951d21b67304e0457Dmitry Vyukov// glibc guts 136103f224835f46801a0e22cc2951d21b67304e0457Dmitry VyukovTSAN_INTERCEPTOR(void, __res_iclose, void *state, bool free_addr) { 136203f224835f46801a0e22cc2951d21b67304e0457Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(__res_iclose, state, free_addr); 136303f224835f46801a0e22cc2951d21b67304e0457Dmitry Vyukov int fds[64]; 136403f224835f46801a0e22cc2951d21b67304e0457Dmitry Vyukov int cnt = ExtractResolvFDs(state, fds, ARRAY_SIZE(fds)); 136503f224835f46801a0e22cc2951d21b67304e0457Dmitry Vyukov for (int i = 0; i < cnt; i++) { 136603f224835f46801a0e22cc2951d21b67304e0457Dmitry Vyukov if (fds[i] > 0) 136703f224835f46801a0e22cc2951d21b67304e0457Dmitry Vyukov FdClose(thr, pc, fds[i]); 136803f224835f46801a0e22cc2951d21b67304e0457Dmitry Vyukov } 136903f224835f46801a0e22cc2951d21b67304e0457Dmitry Vyukov REAL(__res_iclose)(state, free_addr); 137003f224835f46801a0e22cc2951d21b67304e0457Dmitry Vyukov} 137103f224835f46801a0e22cc2951d21b67304e0457Dmitry Vyukov 137201e96987f557524a351b9f2229e7c920cdb96aadDmitry VyukovTSAN_INTERCEPTOR(int, pipe, int *pipefd) { 1373ddeb2c354235818494d86827e88a0c2fa44bebccDmitry Vyukov SCOPED_TSAN_INTERCEPTOR(pipe, pipefd); 1374ddeb2c354235818494d86827e88a0c2fa44bebccDmitry Vyukov int res = REAL(pipe)(pipefd); 1375b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (res == 0 && pipefd[0] >= 0 && pipefd[1] >= 0) 137668230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov FdPipeCreate(thr, pc, pipefd[0], pipefd[1]); 137701e96987f557524a351b9f2229e7c920cdb96aadDmitry Vyukov return res; 1378ddeb2c354235818494d86827e88a0c2fa44bebccDmitry Vyukov} 1379ddeb2c354235818494d86827e88a0c2fa44bebccDmitry Vyukov 138001e96987f557524a351b9f2229e7c920cdb96aadDmitry VyukovTSAN_INTERCEPTOR(int, pipe2, int *pipefd, int flags) { 1381ddeb2c354235818494d86827e88a0c2fa44bebccDmitry Vyukov SCOPED_TSAN_INTERCEPTOR(pipe2, pipefd, flags); 1382ddeb2c354235818494d86827e88a0c2fa44bebccDmitry Vyukov int res = REAL(pipe2)(pipefd, flags); 1383b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (res == 0 && pipefd[0] >= 0 && pipefd[1] >= 0) 138468230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov FdPipeCreate(thr, pc, pipefd[0], pipefd[1]); 1385ddeb2c354235818494d86827e88a0c2fa44bebccDmitry Vyukov return res; 1386ddeb2c354235818494d86827e88a0c2fa44bebccDmitry Vyukov} 1387ddeb2c354235818494d86827e88a0c2fa44bebccDmitry Vyukov 13887ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(long_t, readv, int fd, void *vec, int cnt) { 13897ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(readv, fd, vec, cnt); 13907ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(readv)(fd, vec, cnt); 1391b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (res >= 0 && fd >= 0) { 13923f4e6d9b75fb3f7f2674a31008738cfda9cda9edDmitry Vyukov FdAcquire(thr, pc, fd); 13937ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 13947ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 13957ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 13967ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 13977ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(long_t, preadv64, int fd, void *vec, int cnt, u64 off) { 13987ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(preadv64, fd, vec, cnt, off); 13997ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(preadv64)(fd, vec, cnt, off); 1400b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (res >= 0 && fd >= 0) { 14013f4e6d9b75fb3f7f2674a31008738cfda9cda9edDmitry Vyukov FdAcquire(thr, pc, fd); 14027ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 14037ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 14047ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 14057ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 14067ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(long_t, writev, int fd, void *vec, int cnt) { 14077ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(writev, fd, vec, cnt); 1408b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (fd >= 0) 1409b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov FdRelease(thr, pc, fd); 14107ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(writev)(fd, vec, cnt); 14117ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 14127ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 14137ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 14147ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(long_t, pwritev64, int fd, void *vec, int cnt, u64 off) { 14157ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(pwritev64, fd, vec, cnt, off); 1416b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (fd >= 0) 1417b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov FdRelease(thr, pc, fd); 14187ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(pwritev64)(fd, vec, cnt, off); 14197ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 14207ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 14217ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 14227ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(long_t, send, int fd, void *buf, long_t len, int flags) { 14237ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(send, fd, buf, len, flags); 1424b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (fd >= 0) 1425b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov FdRelease(thr, pc, fd); 14267ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(send)(fd, buf, len, flags); 14277ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 14287ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 14297ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 14307ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(long_t, sendmsg, int fd, void *msg, int flags) { 14317ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(sendmsg, fd, msg, flags); 1432b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (fd >= 0) 1433b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov FdRelease(thr, pc, fd); 14347ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(sendmsg)(fd, msg, flags); 14357ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 14367ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 14377ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 14387ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(long_t, recv, int fd, void *buf, long_t len, int flags) { 14397ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(recv, fd, buf, len, flags); 14407ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(recv)(fd, buf, len, flags); 1441b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (res >= 0 && fd >= 0) { 14423f4e6d9b75fb3f7f2674a31008738cfda9cda9edDmitry Vyukov FdAcquire(thr, pc, fd); 14437ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 14447ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 14457ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 14467ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 14477ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(long_t, recvmsg, int fd, void *msg, int flags) { 14487ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(recvmsg, fd, msg, flags); 14497ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(recvmsg)(fd, msg, flags); 1450b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (res >= 0 && fd >= 0) { 14513f4e6d9b75fb3f7f2674a31008738cfda9cda9edDmitry Vyukov FdAcquire(thr, pc, fd); 14527ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 14537ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 14547ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 14557ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 14567ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, unlink, char *path) { 14577ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(unlink, path); 1458c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov Release(thr, pc, File2addr(path)); 14597ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(unlink)(path); 14607ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 14617ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 14627ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 14637ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(void*, fopen, char *path, char *mode) { 14647ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(fopen, path, mode); 14657ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany void *res = REAL(fopen)(path, mode); 1466c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov Acquire(thr, pc, File2addr(path)); 1467c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov if (res) { 1468f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov int fd = fileno_unlocked(res); 1469c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov if (fd >= 0) 1470c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov FdFileCreate(thr, pc, fd); 1471c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov } 1472c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov return res; 1473c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov} 1474c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov 1475c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry VyukovTSAN_INTERCEPTOR(void*, freopen, char *path, char *mode, void *stream) { 1476c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov SCOPED_TSAN_INTERCEPTOR(freopen, path, mode, stream); 1477c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov if (stream) { 1478f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov int fd = fileno_unlocked(stream); 1479c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov if (fd >= 0) 1480c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov FdClose(thr, pc, fd); 1481c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov } 1482c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov void *res = REAL(freopen)(path, mode, stream); 1483c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov Acquire(thr, pc, File2addr(path)); 1484c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov if (res) { 1485f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov int fd = fileno_unlocked(res); 1486c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov if (fd >= 0) 1487c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov FdFileCreate(thr, pc, fd); 1488c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov } 1489c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov return res; 1490c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov} 1491c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov 1492c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry VyukovTSAN_INTERCEPTOR(int, fclose, void *stream) { 1493f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov { 1494f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(fclose, stream); 1495f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov if (stream) { 1496f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov int fd = fileno_unlocked(stream); 1497f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov if (fd >= 0) 1498f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov FdClose(thr, pc, fd); 1499f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov } 1500c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov } 1501f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov return REAL(fclose)(stream); 15027ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 15037ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 15047ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(uptr, fread, void *ptr, uptr size, uptr nmemb, void *f) { 1505f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov { 1506f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(fread, ptr, size, nmemb, f); 1507f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov MemoryAccessRange(thr, pc, (uptr)ptr, size * nmemb, true); 1508f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov } 15097ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return REAL(fread)(ptr, size, nmemb, f); 15107ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 15117ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 15127ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(uptr, fwrite, const void *p, uptr size, uptr nmemb, void *f) { 1513f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov { 1514f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(fwrite, p, size, nmemb, f); 1515f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov MemoryAccessRange(thr, pc, (uptr)p, size * nmemb, false); 1516f17b3822b22751f09549ab563cc5ca61d072b2e8Dmitry Vyukov } 15177ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return REAL(fwrite)(p, size, nmemb, f); 15187ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 15197ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 15207ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, puts, const char *s) { 15217ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(puts, s); 1522d51a1a10cba87be50e9ada9fa21337c387edb237Dmitry Vyukov MemoryAccessRange(thr, pc, (uptr)s, internal_strlen(s), false); 15237ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return REAL(puts)(s); 15247ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 15257ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 15267ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, rmdir, char *path) { 15277ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(rmdir, path); 1528c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov Release(thr, pc, Dir2addr(path)); 15297ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(rmdir)(path); 15307ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 15317ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 15327ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 15337ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(void*, opendir, char *path) { 15347ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(opendir, path); 15357ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany void *res = REAL(opendir)(path); 1536c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov if (res != 0) 1537c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov Acquire(thr, pc, Dir2addr(path)); 15387ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 15397ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 15407ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 15417ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, epoll_ctl, int epfd, int op, int fd, void *ev) { 15427ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(epoll_ctl, epfd, op, fd, ev); 1543b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (op == EPOLL_CTL_ADD && epfd >= 0) { 15443f4e6d9b75fb3f7f2674a31008738cfda9cda9edDmitry Vyukov FdRelease(thr, pc, epfd); 15457ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 15467ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany int res = REAL(epoll_ctl)(epfd, op, fd, ev); 1547f5d4273457ca3d26e6cf658b266cd61062a65101Dmitry Vyukov if (fd >= 0) 1548f5d4273457ca3d26e6cf658b266cd61062a65101Dmitry Vyukov FdAccess(thr, pc, fd); 15497ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 15507ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 15517ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 15527ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, epoll_wait, int epfd, void *ev, int cnt, int timeout) { 15537ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(epoll_wait, epfd, ev, cnt, timeout); 1554ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov int res = BLOCK_REAL(epoll_wait)(epfd, ev, cnt, timeout); 1555b843c1fcc203accc4f37a784cb067904b3e79abeDmitry Vyukov if (res > 0 && epfd >= 0) { 15563f4e6d9b75fb3f7f2674a31008738cfda9cda9edDmitry Vyukov FdAcquire(thr, pc, epfd); 15577ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 15587ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 15597ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 15607ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 1561ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry VyukovTSAN_INTERCEPTOR(int, poll, void *fds, long_t nfds, int timeout) { 1562ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(poll, fds, nfds, timeout); 1563ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov int res = BLOCK_REAL(poll)(fds, nfds, timeout); 1564ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov return res; 1565ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov} 1566ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov 1567d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukovstatic void ALWAYS_INLINE rtl_generic_sighandler(bool sigact, int sig, 1568d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov my_siginfo_t *info, void *ctx) { 15697ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany ThreadState *thr = cur_thread(); 1570e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov SignalContext *sctx = SigCtx(thr); 1571d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov // Don't mess with synchronous signals. 15721fc03d50a87302689482efa24b045a393097b6c3Dmitry Vyukov if (sig == SIGSEGV || sig == SIGBUS || sig == SIGILL || 15731fc03d50a87302689482efa24b045a393097b6c3Dmitry Vyukov sig == SIGABRT || sig == SIGFPE || sig == SIGPIPE || 1574ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov // If we are sending signal to ourselves, we must process it now. 1575ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov (sctx && sig == sctx->int_signal_send) || 15760bf04eab1910cc8bf622c20ba08c339dc25e297eDmitry Vyukov // If we are in blocking function, we can safely process it now 15770bf04eab1910cc8bf622c20ba08c339dc25e297eDmitry Vyukov // (but check if we are in a recursive interceptor, 15780bf04eab1910cc8bf622c20ba08c339dc25e297eDmitry Vyukov // i.e. pthread_join()->munmap()). 157980d46a2fbc0ae5086511a91119a6e28883b9f880Dmitry Vyukov (sctx && sctx->in_blocking_func == 1 && thr->in_rtl == 1)) { 1580d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov CHECK(thr->in_rtl == 0 || thr->in_rtl == 1); 1581d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov int in_rtl = thr->in_rtl; 1582d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov thr->in_rtl = 0; 1583d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov CHECK_EQ(thr->in_signal_handler, false); 1584d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov thr->in_signal_handler = true; 1585d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov if (sigact) 1586d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov sigactions[sig].sa_sigaction(sig, info, ctx); 1587d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov else 1588d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov sigactions[sig].sa_handler(sig); 1589d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov CHECK_EQ(thr->in_signal_handler, true); 1590d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov thr->in_signal_handler = false; 1591d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov thr->in_rtl = in_rtl; 1592d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov return; 1593d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov } 1594d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov 15951fc03d50a87302689482efa24b045a393097b6c3Dmitry Vyukov if (sctx == 0) 15961fc03d50a87302689482efa24b045a393097b6c3Dmitry Vyukov return; 1597e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov SignalDesc *signal = &sctx->pending_signals[sig]; 15987ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (signal->armed == false) { 15997ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany signal->armed = true; 1600d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov signal->sigaction = sigact; 1601d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov if (info) 16026e4815579e5b48b48de092afcc3b092dfb97df5cDmitry Vyukov internal_memcpy(&signal->siginfo, info, sizeof(*info)); 1603a5562db12c5331433407ac21602086f34561c25cDmitry Vyukov if (ctx) 16046e4815579e5b48b48de092afcc3b092dfb97df5cDmitry Vyukov internal_memcpy(&signal->ctx, ctx, sizeof(signal->ctx)); 1605e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov sctx->pending_signal_count++; 16067ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 16077ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 16087ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 1609d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukovstatic void rtl_sighandler(int sig) { 1610d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov rtl_generic_sighandler(false, sig, 0, 0); 1611d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov} 1612d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov 16137ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanystatic void rtl_sigaction(int sig, my_siginfo_t *info, void *ctx) { 1614d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov rtl_generic_sighandler(true, sig, info, ctx); 16157ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 16167ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 16177ac41484ea322e0ea5774df681660269f5dc321eKostya SerebryanyTSAN_INTERCEPTOR(int, sigaction, int sig, sigaction_t *act, sigaction_t *old) { 16187ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany SCOPED_TSAN_INTERCEPTOR(sigaction, sig, act, old); 1619d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov if (old) 16206e4815579e5b48b48de092afcc3b092dfb97df5cDmitry Vyukov internal_memcpy(old, &sigactions[sig], sizeof(*old)); 1621d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov if (act == 0) 1622d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov return 0; 16236e4815579e5b48b48de092afcc3b092dfb97df5cDmitry Vyukov internal_memcpy(&sigactions[sig], act, sizeof(*act)); 16246e4815579e5b48b48de092afcc3b092dfb97df5cDmitry Vyukov sigaction_t newact; 16256e4815579e5b48b48de092afcc3b092dfb97df5cDmitry Vyukov internal_memcpy(&newact, act, sizeof(newact)); 1626b4b9fa707324095e3590a57963fd754d7a4dd40eDmitry Vyukov sigfillset(&newact.sa_mask); 1627d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov if (act->sa_handler != SIG_IGN && act->sa_handler != SIG_DFL) { 16287ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (newact.sa_flags & SA_SIGINFO) 16297ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany newact.sa_sigaction = rtl_sigaction; 16307ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany else 16317ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany newact.sa_handler = rtl_sighandler; 1632d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov } 1633d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov int res = REAL(sigaction)(sig, &newact, 0); 1634d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov return res; 1635d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov} 1636d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov 1637d91d06794506f10fb7599a2b835222fba29394e0Dmitry VyukovTSAN_INTERCEPTOR(sighandler_t, signal, int sig, sighandler_t h) { 16382135d8a7f4ba30fe35ed02d5e6ffd59a95b26219Alexey Samsonov sigaction_t act; 1639d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov act.sa_handler = h; 164088207ab15125e2f1e9b3d541b735b2b8aba9b6d9Alexey Samsonov REAL(memset)(&act.sa_mask, -1, sizeof(act.sa_mask)); 1641d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov act.sa_flags = 0; 16422135d8a7f4ba30fe35ed02d5e6ffd59a95b26219Alexey Samsonov sigaction_t old; 1643d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov int res = sigaction(sig, &act, &old); 1644d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov if (res) 1645d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov return SIG_ERR; 1646d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov return old.sa_handler; 1647d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov} 1648d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov 1649d91d06794506f10fb7599a2b835222fba29394e0Dmitry VyukovTSAN_INTERCEPTOR(int, raise, int sig) { 1650d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(raise, sig); 1651e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov SignalContext *sctx = SigCtx(thr); 16521fc03d50a87302689482efa24b045a393097b6c3Dmitry Vyukov CHECK_NE(sctx, 0); 1653e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov int prev = sctx->int_signal_send; 1654e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov sctx->int_signal_send = sig; 1655d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov int res = REAL(raise)(sig); 1656e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov CHECK_EQ(sctx->int_signal_send, sig); 1657e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov sctx->int_signal_send = prev; 1658d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov return res; 1659d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov} 1660d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov 1661d91d06794506f10fb7599a2b835222fba29394e0Dmitry VyukovTSAN_INTERCEPTOR(int, kill, int pid, int sig) { 1662d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(kill, pid, sig); 1663e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov SignalContext *sctx = SigCtx(thr); 16641fc03d50a87302689482efa24b045a393097b6c3Dmitry Vyukov CHECK_NE(sctx, 0); 1665e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov int prev = sctx->int_signal_send; 1666d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov if (pid == GetPid()) { 1667e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov sctx->int_signal_send = sig; 1668d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov } 1669d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov int res = REAL(kill)(pid, sig); 1670d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov if (pid == GetPid()) { 1671e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov CHECK_EQ(sctx->int_signal_send, sig); 1672e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov sctx->int_signal_send = prev; 1673d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov } 1674d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov return res; 1675d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov} 1676d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov 1677d91d06794506f10fb7599a2b835222fba29394e0Dmitry VyukovTSAN_INTERCEPTOR(int, pthread_kill, void *tid, int sig) { 1678d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(pthread_kill, tid, sig); 1679e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov SignalContext *sctx = SigCtx(thr); 16801fc03d50a87302689482efa24b045a393097b6c3Dmitry Vyukov CHECK_NE(sctx, 0); 1681e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov int prev = sctx->int_signal_send; 1682d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov if (tid == pthread_self()) { 1683e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov sctx->int_signal_send = sig; 1684d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov } 1685d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov int res = REAL(pthread_kill)(tid, sig); 1686d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov if (tid == pthread_self()) { 1687e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov CHECK_EQ(sctx->int_signal_send, sig); 1688e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov sctx->int_signal_send = prev; 16897ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 16907ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return res; 16917ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 16927ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 1693ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry VyukovTSAN_INTERCEPTOR(int, gettimeofday, void *tv, void *tz) { 1694ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(gettimeofday, tv, tz); 1695ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov // It's intercepted merely to process pending signals. 1696ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov return REAL(gettimeofday)(tv, tz); 1697ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov} 1698ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov 169992733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov// Linux kernel has a bug that leads to kernel deadlock if a process 170092733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov// maps TBs of memory and then calls mlock(). 170192733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukovstatic void MlockIsUnsupported() { 170292733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov static atomic_uint8_t printed; 170392733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov if (atomic_exchange(&printed, 1, memory_order_relaxed)) 170492733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov return; 170592733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov Printf("INFO: ThreadSanitizer ignores mlock/mlockall/munlock/munlockall\n"); 170692733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov} 170792733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov 170892733f94292cd36795238e1a6ed0a99a1dc0454dDmitry VyukovTSAN_INTERCEPTOR(int, mlock, const void *addr, uptr len) { 170992733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov MlockIsUnsupported(); 171092733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov return 0; 171192733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov} 171292733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov 171392733f94292cd36795238e1a6ed0a99a1dc0454dDmitry VyukovTSAN_INTERCEPTOR(int, munlock, const void *addr, uptr len) { 171492733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov MlockIsUnsupported(); 171592733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov return 0; 171692733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov} 171792733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov 171892733f94292cd36795238e1a6ed0a99a1dc0454dDmitry VyukovTSAN_INTERCEPTOR(int, mlockall, int flags) { 171992733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov MlockIsUnsupported(); 172092733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov return 0; 172192733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov} 172292733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov 172392733f94292cd36795238e1a6ed0a99a1dc0454dDmitry VyukovTSAN_INTERCEPTOR(int, munlockall, void) { 172492733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov MlockIsUnsupported(); 172592733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov return 0; 172692733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov} 172792733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov 1728b75c67b495ca13801cc629b2c2c9dd0010e54739Dmitry VyukovTSAN_INTERCEPTOR(int, fork, int fake) { 1729b75c67b495ca13801cc629b2c2c9dd0010e54739Dmitry Vyukov SCOPED_TSAN_INTERCEPTOR(fork, fake); 17304554b7a7b345cd50ff8138b3cda8dd1135b965faDmitry Vyukov // It's intercepted merely to process pending signals. 1731b75c67b495ca13801cc629b2c2c9dd0010e54739Dmitry Vyukov int pid = REAL(fork)(fake); 17324554b7a7b345cd50ff8138b3cda8dd1135b965faDmitry Vyukov if (pid == 0) { 17334554b7a7b345cd50ff8138b3cda8dd1135b965faDmitry Vyukov // child 17344554b7a7b345cd50ff8138b3cda8dd1135b965faDmitry Vyukov FdOnFork(thr, pc); 17354554b7a7b345cd50ff8138b3cda8dd1135b965faDmitry Vyukov } else if (pid > 0) { 17364554b7a7b345cd50ff8138b3cda8dd1135b965faDmitry Vyukov // parent 17374554b7a7b345cd50ff8138b3cda8dd1135b965faDmitry Vyukov } 17384554b7a7b345cd50ff8138b3cda8dd1135b965faDmitry Vyukov return pid; 17394554b7a7b345cd50ff8138b3cda8dd1135b965faDmitry Vyukov} 17404554b7a7b345cd50ff8138b3cda8dd1135b965faDmitry Vyukov 1741996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanovstruct TsanInterceptorContext { 1742996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov ThreadState *thr; 1743996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov const uptr caller_pc; 1744996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov const uptr pc; 1745996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov}; 1746996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov 1747996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \ 1748996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov MemoryAccessRange(((TsanInterceptorContext*)ctx)->thr, \ 1749996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov ((TsanInterceptorContext*)ctx)->pc, \ 1750996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov (uptr)ptr, size, true) 1751996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \ 1752996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov MemoryAccessRange(((TsanInterceptorContext*)ctx)->thr, \ 1753996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov ((TsanInterceptorContext*)ctx)->pc, \ 1754996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov (uptr)ptr, size, false) 1755996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \ 1756996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov SCOPED_TSAN_INTERCEPTOR(func, __VA_ARGS__) \ 1757996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov TsanInterceptorContext _ctx = {thr, caller_pc, pc}; \ 175882a9080eaff95d69b270cd863e9df63e3b4e59adEvgeniy Stepanov ctx = (void*)&_ctx; \ 175982a9080eaff95d69b270cd863e9df63e3b4e59adEvgeniy Stepanov (void)ctx; 1760996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \ 1761996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov FdAcquire(((TsanInterceptorContext*)ctx)->thr, pc, fd) 1762996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \ 1763996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov FdRelease(((TsanInterceptorContext*)ctx)->thr, pc, fd) 1764996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov#define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) \ 1765996c4f2fa53cce8f9d7b517073f38569460de505Evgeniy Stepanov ThreadSetName(((TsanInterceptorContext*)ctx)->thr, name) 17664f32c0beaa83ffbb84db23d2e6205bee57c39ce1Evgeniy Stepanov#include "sanitizer_common/sanitizer_common_interceptors.inc" 1767c8033193376c3326478a345c4ae6633d4d2862c6Kostya Serebryany 1768ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukovnamespace __tsan { 1769ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov 1770ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukovvoid ProcessPendingSignals(ThreadState *thr) { 17717ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany CHECK_EQ(thr->in_rtl, 0); 1772e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov SignalContext *sctx = SigCtx(thr); 17731fc03d50a87302689482efa24b045a393097b6c3Dmitry Vyukov if (sctx == 0 || sctx->pending_signal_count == 0 || thr->in_signal_handler) 17747ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany return; 1775158c6ac3bb46753db217f9c2c73485811a3a1890Dmitry Vyukov Context *ctx = CTX(); 17767ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany thr->in_signal_handler = true; 1777e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov sctx->pending_signal_count = 0; 17787ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany // These are too big for stack. 17797ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany static THREADLOCAL sigset_t emptyset, oldset; 17807ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany sigfillset(&emptyset); 17817ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany pthread_sigmask(SIG_SETMASK, &emptyset, &oldset); 17827ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany for (int sig = 0; sig < kSigCount; sig++) { 1783e96366613372e616fc6f2209b81b776f931a2c58Dmitry Vyukov SignalDesc *signal = &sctx->pending_signals[sig]; 17847ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (signal->armed) { 17857ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany signal->armed = false; 1786d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov if (sigactions[sig].sa_handler != SIG_DFL 1787d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov && sigactions[sig].sa_handler != SIG_IGN) { 17887a72b4a0f04f7f043ab86396b0faa552f55aa857Dmitry Vyukov // Insure that the handler does not spoil errno. 17897a72b4a0f04f7f043ab86396b0faa552f55aa857Dmitry Vyukov const int saved_errno = errno; 17907a72b4a0f04f7f043ab86396b0faa552f55aa857Dmitry Vyukov errno = 0; 1791d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov if (signal->sigaction) 1792a5562db12c5331433407ac21602086f34561c25cDmitry Vyukov sigactions[sig].sa_sigaction(sig, &signal->siginfo, &signal->ctx); 1793d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov else 1794d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov sigactions[sig].sa_handler(sig); 17958a326776e41dc68c810ba3719a24328de517d8f9Dmitry Vyukov if (flags()->report_bugs && errno != 0) { 17967a72b4a0f04f7f043ab86396b0faa552f55aa857Dmitry Vyukov ScopedInRtl in_rtl; 17974f0ea398bdc99a4a32402057c23bbcc6d19a8eb4Alexey Samsonov __tsan::StackTrace stack; 17987a72b4a0f04f7f043ab86396b0faa552f55aa857Dmitry Vyukov uptr pc = signal->sigaction ? 17997a72b4a0f04f7f043ab86396b0faa552f55aa857Dmitry Vyukov (uptr)sigactions[sig].sa_sigaction : 18007a72b4a0f04f7f043ab86396b0faa552f55aa857Dmitry Vyukov (uptr)sigactions[sig].sa_handler; 18017a72b4a0f04f7f043ab86396b0faa552f55aa857Dmitry Vyukov stack.Init(&pc, 1); 1802fb917e9069ea44f7103f50c658be84a8f66de56cDmitry Vyukov Lock l(&ctx->thread_mtx); 18037a72b4a0f04f7f043ab86396b0faa552f55aa857Dmitry Vyukov ScopedReport rep(ReportTypeErrnoInSignal); 1804158c6ac3bb46753db217f9c2c73485811a3a1890Dmitry Vyukov if (!IsFiredSuppression(ctx, rep, stack)) { 1805158c6ac3bb46753db217f9c2c73485811a3a1890Dmitry Vyukov rep.AddStack(&stack); 1806158c6ac3bb46753db217f9c2c73485811a3a1890Dmitry Vyukov OutputReport(ctx, rep, rep.GetReport()->stacks[0]); 1807158c6ac3bb46753db217f9c2c73485811a3a1890Dmitry Vyukov } 18087a72b4a0f04f7f043ab86396b0faa552f55aa857Dmitry Vyukov } 18097a72b4a0f04f7f043ab86396b0faa552f55aa857Dmitry Vyukov errno = saved_errno; 1810d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov } 18117ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 18127ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 18137ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany pthread_sigmask(SIG_SETMASK, &oldset, 0); 18147ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany CHECK_EQ(thr->in_signal_handler, true); 18157ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany thr->in_signal_handler = false; 18167ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 18177ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 181891ac008b435b879bb366bcf9516c53f2d07c30b1Dmitry Vyukovstatic void unreachable() { 181991ac008b435b879bb366bcf9516c53f2d07c30b1Dmitry Vyukov Printf("FATAL: ThreadSanitizer: unreachable called\n"); 182091ac008b435b879bb366bcf9516c53f2d07c30b1Dmitry Vyukov Die(); 182191ac008b435b879bb366bcf9516c53f2d07c30b1Dmitry Vyukov} 182291ac008b435b879bb366bcf9516c53f2d07c30b1Dmitry Vyukov 18237ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryanyvoid InitializeInterceptors() { 18247ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany CHECK_GT(cur_thread()->in_rtl, 0); 18257ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 18267ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany // We need to setup it early, because functions like dlsym() can call it. 1827065c4ac846589d04436cb7f19f938ff42035313eDmitry Vyukov REAL(memset) = internal_memset; 1828065c4ac846589d04436cb7f19f938ff42035313eDmitry Vyukov REAL(memcpy) = internal_memcpy; 1829065c4ac846589d04436cb7f19f938ff42035313eDmitry Vyukov REAL(memcmp) = internal_memcmp; 18307ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 1831c8033193376c3326478a345c4ae6633d4d2862c6Kostya Serebryany SANITIZER_COMMON_INTERCEPTORS_INIT; 1832c8033193376c3326478a345c4ae6633d4d2862c6Kostya Serebryany 1833f037f565b2e02878ceb6e7b49647e814e2990ef5Dmitry Vyukov TSAN_INTERCEPT(longjmp); 1834f037f565b2e02878ceb6e7b49647e814e2990ef5Dmitry Vyukov TSAN_INTERCEPT(siglongjmp); 1835f037f565b2e02878ceb6e7b49647e814e2990ef5Dmitry Vyukov 18367ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(malloc); 183707ba8ef44deb54baa9307298fbffe25ddb30c362Dmitry Vyukov TSAN_INTERCEPT(__libc_memalign); 18387ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(calloc); 18397ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(realloc); 18407ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(free); 18417ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(cfree); 18427ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(mmap); 18437ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(mmap64); 18447ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(munmap); 18457ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(memalign); 18467ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(valloc); 18477ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pvalloc); 18487ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(posix_memalign); 18497ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 18507ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(strlen); 18517ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(memset); 18527ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(memcpy); 18537ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(strcmp); 18547ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(memchr); 18557ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(memrchr); 18567ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(memmove); 18577ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(memcmp); 18587ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(strchr); 18597ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(strchrnul); 18607ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(strrchr); 18617ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(strncmp); 18627ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(strcpy); // NOLINT 18637ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(strncpy); 18647ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(strstr); 18657ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 18667ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_create); 18677ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_join); 18687ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_detach); 18697ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 18707ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_mutex_init); 18717ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_mutex_destroy); 18727ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_mutex_lock); 18737ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_mutex_trylock); 18747ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_mutex_timedlock); 18757ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_mutex_unlock); 18767ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 18777ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_spin_init); 18787ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_spin_destroy); 18797ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_spin_lock); 18807ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_spin_trylock); 18817ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_spin_unlock); 18827ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 18837ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_rwlock_init); 18847ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_rwlock_destroy); 18857ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_rwlock_rdlock); 18867ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_rwlock_tryrdlock); 18877ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_rwlock_timedrdlock); 18887ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_rwlock_wrlock); 18897ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_rwlock_trywrlock); 18907ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_rwlock_timedwrlock); 18917ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_rwlock_unlock); 18927ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 1893c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov // TSAN_INTERCEPT(pthread_cond_init); 18947ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_cond_destroy); 18957ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_cond_signal); 18967ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_cond_broadcast); 18977ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_cond_wait); 18987ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_cond_timedwait); 18997ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 19007ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_barrier_init); 19017ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_barrier_destroy); 19027ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_barrier_wait); 19037ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 19047ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pthread_once); 19057ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 19067ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(sem_init); 19077ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(sem_destroy); 19087ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(sem_wait); 19097ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(sem_trywait); 19107ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(sem_timedwait); 19117ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(sem_post); 19127ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(sem_getvalue); 19137ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 191461ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov TSAN_INTERCEPT(stat); 191561ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov TSAN_INTERCEPT(__xstat); 191661ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov TSAN_INTERCEPT(stat64); 191761ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov TSAN_INTERCEPT(__xstat64); 191861ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov TSAN_INTERCEPT(lstat); 191961ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov TSAN_INTERCEPT(__lxstat); 192061ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov TSAN_INTERCEPT(lstat64); 192161ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov TSAN_INTERCEPT(__lxstat64); 192261ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov TSAN_INTERCEPT(fstat); 192361ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov TSAN_INTERCEPT(__fxstat); 192461ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov TSAN_INTERCEPT(fstat64); 192561ba1b5df34614e0647f5f80d462f6485e817fa5Dmitry Vyukov TSAN_INTERCEPT(__fxstat64); 1926ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov TSAN_INTERCEPT(open); 1927c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov TSAN_INTERCEPT(open64); 1928ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov TSAN_INTERCEPT(creat); 1929c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov TSAN_INTERCEPT(creat64); 1930ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov TSAN_INTERCEPT(dup); 1931ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov TSAN_INTERCEPT(dup2); 1932ba3ae356e0827bfdb17feaff53e17c3934470404Dmitry Vyukov TSAN_INTERCEPT(dup3); 193368230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov TSAN_INTERCEPT(eventfd); 193445d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov TSAN_INTERCEPT(signalfd); 193545d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov TSAN_INTERCEPT(inotify_init); 193645d4324bf5b0ec282f0a8f96312233e09a882502Dmitry Vyukov TSAN_INTERCEPT(inotify_init1); 193768230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov TSAN_INTERCEPT(socket); 1938983518e360a179d92bdbddebe05a87db3c6cc3c0Dmitry Vyukov TSAN_INTERCEPT(socketpair); 193968230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov TSAN_INTERCEPT(connect); 194052c70e5818727521b89f7fc95a2a383df8985ca6Dmitry Vyukov TSAN_INTERCEPT(bind); 194152c70e5818727521b89f7fc95a2a383df8985ca6Dmitry Vyukov TSAN_INTERCEPT(listen); 194268230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov TSAN_INTERCEPT(accept); 194368230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov TSAN_INTERCEPT(accept4); 194468230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov TSAN_INTERCEPT(epoll_create); 194568230a12bbd22c9402dd8f9af027fcb2e119f978Dmitry Vyukov TSAN_INTERCEPT(epoll_create1); 1946ddeb2c354235818494d86827e88a0c2fa44bebccDmitry Vyukov TSAN_INTERCEPT(close); 194703f224835f46801a0e22cc2951d21b67304e0457Dmitry Vyukov TSAN_INTERCEPT(__close); 194803f224835f46801a0e22cc2951d21b67304e0457Dmitry Vyukov TSAN_INTERCEPT(__res_iclose); 1949ddeb2c354235818494d86827e88a0c2fa44bebccDmitry Vyukov TSAN_INTERCEPT(pipe); 1950ddeb2c354235818494d86827e88a0c2fa44bebccDmitry Vyukov TSAN_INTERCEPT(pipe2); 1951ddeb2c354235818494d86827e88a0c2fa44bebccDmitry Vyukov 19527ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(readv); 19537ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(preadv64); 19547ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(writev); 19557ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(pwritev64); 19567ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(send); 19577ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(sendmsg); 19587ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(recv); 19597ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(recvmsg); 19607ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 19617ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(unlink); 19627ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(fopen); 1963c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov TSAN_INTERCEPT(freopen); 1964c78839f0288e5af16101b5fd3b455e1a88cc1c5eDmitry Vyukov TSAN_INTERCEPT(fclose); 19657ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(fread); 19667ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(fwrite); 19677ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(puts); 19687ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(rmdir); 19697ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(opendir); 19707ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 19717ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(epoll_ctl); 19727ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(epoll_wait); 1973ee8ee2437b28ab8bf6f48af15b8b446fb5d55e90Dmitry Vyukov TSAN_INTERCEPT(poll); 19747ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 19757ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany TSAN_INTERCEPT(sigaction); 1976d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov TSAN_INTERCEPT(signal); 1977d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov TSAN_INTERCEPT(raise); 1978d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov TSAN_INTERCEPT(kill); 1979d91d06794506f10fb7599a2b835222fba29394e0Dmitry Vyukov TSAN_INTERCEPT(pthread_kill); 1980848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov TSAN_INTERCEPT(sleep); 1981848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov TSAN_INTERCEPT(usleep); 1982848531192777acecf79747dc7c1ffeedf5c1da9fDmitry Vyukov TSAN_INTERCEPT(nanosleep); 1983aad173b2f1dae9f88bbffd217ebd46ed1f020bcbDmitry Vyukov TSAN_INTERCEPT(gettimeofday); 19847ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 198592733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov TSAN_INTERCEPT(mlock); 198692733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov TSAN_INTERCEPT(munlock); 198792733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov TSAN_INTERCEPT(mlockall); 198892733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov TSAN_INTERCEPT(munlockall); 198992733f94292cd36795238e1a6ed0a99a1dc0454dDmitry Vyukov 19904554b7a7b345cd50ff8138b3cda8dd1135b965faDmitry Vyukov TSAN_INTERCEPT(fork); 199131c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov TSAN_INTERCEPT(on_exit); 199231c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov TSAN_INTERCEPT(__cxa_atexit); 19934554b7a7b345cd50ff8138b3cda8dd1135b965faDmitry Vyukov 199491ac008b435b879bb366bcf9516c53f2d07c30b1Dmitry Vyukov // Need to setup it, because interceptors check that the function is resolved. 199591ac008b435b879bb366bcf9516c53f2d07c30b1Dmitry Vyukov // But atexit is emitted directly into the module, so can't be resolved. 199691ac008b435b879bb366bcf9516c53f2d07c30b1Dmitry Vyukov REAL(atexit) = (int(*)(void(*)()))unreachable; 19977ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany atexit_ctx = new(internal_alloc(MBlockAtExit, sizeof(AtExitContext))) 19987ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany AtExitContext(); 19997ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 200031c05ea4d508a476403ba30c1f60ef6190eb46b6Dmitry Vyukov if (REAL(__cxa_atexit)(&finalize, 0, 0)) { 2001b1fe3021eca0843e37878d224ee7f32e32f40d99Alexey Samsonov Printf("ThreadSanitizer: failed to setup atexit callback\n"); 20027ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany Die(); 20037ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 20047ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 20057ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany if (pthread_key_create(&g_thread_finalize_key, &thread_finalize)) { 2006b1fe3021eca0843e37878d224ee7f32e32f40d99Alexey Samsonov Printf("ThreadSanitizer: failed to create thread key\n"); 20077ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany Die(); 20087ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany } 20093f4e6d9b75fb3f7f2674a31008738cfda9cda9edDmitry Vyukov 20103f4e6d9b75fb3f7f2674a31008738cfda9cda9edDmitry Vyukov FdInit(); 20117ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} 20127ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany 201326127735454fddae3495794f38189d57dde6510fDmitry Vyukovvoid internal_start_thread(void(*func)(void *arg), void *arg) { 201426127735454fddae3495794f38189d57dde6510fDmitry Vyukov void *th; 201526127735454fddae3495794f38189d57dde6510fDmitry Vyukov REAL(pthread_create)(&th, 0, (void*(*)(void *arg))func, arg); 201626127735454fddae3495794f38189d57dde6510fDmitry Vyukov REAL(pthread_detach)(th); 201726127735454fddae3495794f38189d57dde6510fDmitry Vyukov} 201826127735454fddae3495794f38189d57dde6510fDmitry Vyukov 20197ac41484ea322e0ea5774df681660269f5dc321eKostya Serebryany} // namespace __tsan 2020