diff options
Diffstat (limited to 'libsanitizer/tsan/tsan_interceptors.cc')
-rw-r--r-- | libsanitizer/tsan/tsan_interceptors.cc | 376 |
1 files changed, 311 insertions, 65 deletions
diff --git a/libsanitizer/tsan/tsan_interceptors.cc b/libsanitizer/tsan/tsan_interceptors.cc index dea64150786..88acebf8e81 100644 --- a/libsanitizer/tsan/tsan_interceptors.cc +++ b/libsanitizer/tsan/tsan_interceptors.cc @@ -7,6 +7,8 @@ // // This file is a part of ThreadSanitizer (TSan), a race detector. // +// FIXME: move as many interceptors as possible into +// sanitizer_common/sanitizer_common_interceptors.h //===----------------------------------------------------------------------===// #include "sanitizer_common/sanitizer_atomic.h" @@ -18,6 +20,7 @@ #include "tsan_platform.h" #include "tsan_rtl.h" #include "tsan_mman.h" +#include "tsan_fd.h" using namespace __tsan; // NOLINT @@ -50,6 +53,7 @@ extern "C" void *pthread_self(); extern "C" void _exit(int status); extern "C" int __cxa_atexit(void (*func)(void *arg), void *arg, void *dso); extern "C" int *__errno_location(); +extern "C" int fileno_unlocked(void *stream); const int PTHREAD_MUTEX_RECURSIVE = 1; const int PTHREAD_MUTEX_RECURSIVE_NP = 1; const int kPthreadAttrSize = 56; @@ -124,10 +128,8 @@ static SignalContext *SigCtx(ThreadState *thr) { SignalContext *ctx = (SignalContext*)thr->signal_ctx; if (ctx == 0 && thr->is_alive) { ScopedInRtl in_rtl; - ctx = (SignalContext*)internal_alloc( - MBlockSignal, sizeof(*ctx)); - MemoryResetRange(thr, 0, (uptr)ctx, sizeof(*ctx)); - internal_memset(ctx, 0, sizeof(*ctx)); + ctx = (SignalContext*)MmapOrDie(sizeof(*ctx), "SignalContext"); + MemoryResetRange(thr, (uptr)&SigCtx, (uptr)ctx, sizeof(*ctx)); thr->signal_ctx = ctx; } return ctx; @@ -173,8 +175,8 @@ ScopedInterceptor::~ScopedInterceptor() { StatInc(thr, StatInt_##func); \ const uptr caller_pc = GET_CALLER_PC(); \ ScopedInterceptor si(thr, #func, caller_pc); \ - /* Subtract one from pc as we need current instruction address */ \ - const uptr pc = __sanitizer::StackTrace::GetCurrentPc() - 1; \ + const uptr pc = __sanitizer::StackTrace::GetPreviousInstructionPc( \ + __sanitizer::StackTrace::GetCurrentPc()); \ (void)pc; \ /**/ @@ -306,30 +308,6 @@ TSAN_INTERCEPTOR(void, siglongjmp, void *env, int val) { Die(); } -static uptr fd2addr(int fd) { - (void)fd; - static u64 addr; - return (uptr)&addr; -} - -static uptr epollfd2addr(int fd) { - (void)fd; - static u64 addr; - return (uptr)&addr; -} - -static uptr file2addr(char *path) { - (void)path; - static u64 addr; - return (uptr)&addr; -} - -static uptr dir2addr(char *path) { - (void)path; - static u64 addr; - return (uptr)&addr; -} - TSAN_INTERCEPTOR(void*, malloc, uptr size) { void *p = 0; { @@ -660,7 +638,7 @@ static void thread_finalize(void *v) { SignalContext *sctx = thr->signal_ctx; if (sctx) { thr->signal_ctx = 0; - internal_free(sctx); + UnmapOrDie(sctx, sizeof(*sctx)); } } } @@ -934,11 +912,15 @@ TSAN_INTERCEPTOR(int, pthread_rwlock_unlock, void *m) { return res; } +// libpthread.so contains several versions of pthread_cond_init symbol. +// When we just dlsym() it, we get the wrong (old) version. +/* TSAN_INTERCEPTOR(int, pthread_cond_init, void *c, void *a) { SCOPED_TSAN_INTERCEPTOR(pthread_cond_init, c, a); int res = REAL(pthread_cond_init)(c, a); return res; } +*/ TSAN_INTERCEPTOR(int, pthread_cond_destroy, void *c) { SCOPED_TSAN_INTERCEPTOR(pthread_cond_destroy, c); @@ -1080,11 +1062,188 @@ TSAN_INTERCEPTOR(int, sem_getvalue, void *s, int *sval) { return res; } +TSAN_INTERCEPTOR(int, open, const char *name, int flags, int mode) { + SCOPED_TSAN_INTERCEPTOR(open, name, flags, mode); + int fd = REAL(open)(name, flags, mode); + if (fd >= 0) + FdFileCreate(thr, pc, fd); + return fd; +} + +TSAN_INTERCEPTOR(int, open64, const char *name, int flags, int mode) { + SCOPED_TSAN_INTERCEPTOR(open64, name, flags, mode); + int fd = REAL(open64)(name, flags, mode); + if (fd >= 0) + FdFileCreate(thr, pc, fd); + return fd; +} + +TSAN_INTERCEPTOR(int, creat, const char *name, int mode) { + SCOPED_TSAN_INTERCEPTOR(creat, name, mode); + int fd = REAL(creat)(name, mode); + if (fd >= 0) + FdFileCreate(thr, pc, fd); + return fd; +} + +TSAN_INTERCEPTOR(int, creat64, const char *name, int mode) { + SCOPED_TSAN_INTERCEPTOR(creat64, name, mode); + int fd = REAL(creat64)(name, mode); + if (fd >= 0) + FdFileCreate(thr, pc, fd); + return fd; +} + +TSAN_INTERCEPTOR(int, dup, int oldfd) { + SCOPED_TSAN_INTERCEPTOR(dup, oldfd); + int newfd = REAL(dup)(oldfd); + if (oldfd >= 0 && newfd >= 0 && newfd != oldfd) + FdDup(thr, pc, oldfd, newfd); + return newfd; +} + +TSAN_INTERCEPTOR(int, dup2, int oldfd, int newfd) { + SCOPED_TSAN_INTERCEPTOR(dup2, oldfd, newfd); + int newfd2 = REAL(dup2)(oldfd, newfd); + if (oldfd >= 0 && newfd2 >= 0 && newfd2 != oldfd) + FdDup(thr, pc, oldfd, newfd2); + return newfd2; +} + +TSAN_INTERCEPTOR(int, dup3, int oldfd, int newfd, int flags) { + SCOPED_TSAN_INTERCEPTOR(dup3, oldfd, newfd, flags); + int newfd2 = REAL(dup3)(oldfd, newfd, flags); + if (oldfd >= 0 && newfd2 >= 0 && newfd2 != oldfd) + FdDup(thr, pc, oldfd, newfd2); + return newfd2; +} + +TSAN_INTERCEPTOR(int, eventfd, unsigned initval, int flags) { + SCOPED_TSAN_INTERCEPTOR(eventfd, initval, flags); + int fd = REAL(eventfd)(initval, flags); + if (fd >= 0) + FdEventCreate(thr, pc, fd); + return fd; +} + +TSAN_INTERCEPTOR(int, signalfd, int fd, void *mask, int flags) { + SCOPED_TSAN_INTERCEPTOR(signalfd, fd, mask, flags); + if (fd >= 0) + FdClose(thr, pc, fd); + fd = REAL(signalfd)(fd, mask, flags); + if (fd >= 0) + FdSignalCreate(thr, pc, fd); + return fd; +} + +TSAN_INTERCEPTOR(int, inotify_init, int fake) { + SCOPED_TSAN_INTERCEPTOR(inotify_init, fake); + int fd = REAL(inotify_init)(fake); + if (fd >= 0) + FdInotifyCreate(thr, pc, fd); + return fd; +} + +TSAN_INTERCEPTOR(int, inotify_init1, int flags) { + SCOPED_TSAN_INTERCEPTOR(inotify_init1, flags); + int fd = REAL(inotify_init1)(flags); + if (fd >= 0) + FdInotifyCreate(thr, pc, fd); + return fd; +} + +TSAN_INTERCEPTOR(int, socket, int domain, int type, int protocol) { + SCOPED_TSAN_INTERCEPTOR(socket, domain, type, protocol); + int fd = REAL(socket)(domain, type, protocol); + if (fd >= 0) + FdSocketCreate(thr, pc, fd); + return fd; +} + +TSAN_INTERCEPTOR(int, socketpair, int domain, int type, int protocol, int *fd) { + SCOPED_TSAN_INTERCEPTOR(socketpair, domain, type, protocol, fd); + int res = REAL(socketpair)(domain, type, protocol, fd); + if (res == 0 && fd[0] >= 0 && fd[1] >= 0) + FdPipeCreate(thr, pc, fd[0], fd[1]); + return res; +} + +TSAN_INTERCEPTOR(int, connect, int fd, void *addr, unsigned addrlen) { + SCOPED_TSAN_INTERCEPTOR(connect, fd, addr, addrlen); + FdSocketConnecting(thr, pc, fd); + int res = REAL(connect)(fd, addr, addrlen); + if (res == 0 && fd >= 0) + FdSocketConnect(thr, pc, fd); + return res; +} + +TSAN_INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) { + SCOPED_TSAN_INTERCEPTOR(accept, fd, addr, addrlen); + int fd2 = REAL(accept)(fd, addr, addrlen); + if (fd >= 0 && fd2 >= 0) + FdSocketAccept(thr, pc, fd, fd2); + return fd2; +} + +TSAN_INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) { + SCOPED_TSAN_INTERCEPTOR(accept4, fd, addr, addrlen, f); + int fd2 = REAL(accept4)(fd, addr, addrlen, f); + if (fd >= 0 && fd2 >= 0) + FdSocketAccept(thr, pc, fd, fd2); + return fd2; +} + +TSAN_INTERCEPTOR(int, epoll_create, int size) { + SCOPED_TSAN_INTERCEPTOR(epoll_create, size); + int fd = REAL(epoll_create)(size); + if (fd >= 0) + FdPollCreate(thr, pc, fd); + return fd; +} + +TSAN_INTERCEPTOR(int, epoll_create1, int flags) { + SCOPED_TSAN_INTERCEPTOR(epoll_create1, flags); + int fd = REAL(epoll_create1)(flags); + if (fd >= 0) + FdPollCreate(thr, pc, fd); + return fd; +} + +TSAN_INTERCEPTOR(int, close, int fd) { + SCOPED_TSAN_INTERCEPTOR(close, fd); + if (fd >= 0) + FdClose(thr, pc, fd); + return REAL(close)(fd); +} + +TSAN_INTERCEPTOR(int, __close, int fd) { + SCOPED_TSAN_INTERCEPTOR(__close, fd); + if (fd >= 0) + FdClose(thr, pc, fd); + return REAL(__close)(fd); +} + +TSAN_INTERCEPTOR(int, pipe, int *pipefd) { + SCOPED_TSAN_INTERCEPTOR(pipe, pipefd); + int res = REAL(pipe)(pipefd); + if (res == 0 && pipefd[0] >= 0 && pipefd[1] >= 0) + FdPipeCreate(thr, pc, pipefd[0], pipefd[1]); + return res; +} + +TSAN_INTERCEPTOR(int, pipe2, int *pipefd, int flags) { + SCOPED_TSAN_INTERCEPTOR(pipe2, pipefd, flags); + int res = REAL(pipe2)(pipefd, flags); + if (res == 0 && pipefd[0] >= 0 && pipefd[1] >= 0) + FdPipeCreate(thr, pc, pipefd[0], pipefd[1]); + return res; +} + TSAN_INTERCEPTOR(long_t, read, int fd, void *buf, long_t sz) { SCOPED_TSAN_INTERCEPTOR(read, fd, buf, sz); int res = REAL(read)(fd, buf, sz); - if (res >= 0) { - Acquire(thr, pc, fd2addr(fd)); + if (res >= 0 && fd >= 0) { + FdAcquire(thr, pc, fd); } return res; } @@ -1092,8 +1251,8 @@ TSAN_INTERCEPTOR(long_t, read, int fd, void *buf, long_t sz) { TSAN_INTERCEPTOR(long_t, pread, int fd, void *buf, long_t sz, unsigned off) { SCOPED_TSAN_INTERCEPTOR(pread, fd, buf, sz, off); int res = REAL(pread)(fd, buf, sz, off); - if (res >= 0) { - Acquire(thr, pc, fd2addr(fd)); + if (res >= 0 && fd >= 0) { + FdAcquire(thr, pc, fd); } return res; } @@ -1101,8 +1260,8 @@ TSAN_INTERCEPTOR(long_t, pread, int fd, void *buf, long_t sz, unsigned off) { TSAN_INTERCEPTOR(long_t, pread64, int fd, void *buf, long_t sz, u64 off) { SCOPED_TSAN_INTERCEPTOR(pread64, fd, buf, sz, off); int res = REAL(pread64)(fd, buf, sz, off); - if (res >= 0) { - Acquire(thr, pc, fd2addr(fd)); + if (res >= 0 && fd >= 0) { + FdAcquire(thr, pc, fd); } return res; } @@ -1110,8 +1269,8 @@ TSAN_INTERCEPTOR(long_t, pread64, int fd, void *buf, long_t sz, u64 off) { TSAN_INTERCEPTOR(long_t, readv, int fd, void *vec, int cnt) { SCOPED_TSAN_INTERCEPTOR(readv, fd, vec, cnt); int res = REAL(readv)(fd, vec, cnt); - if (res >= 0) { - Acquire(thr, pc, fd2addr(fd)); + if (res >= 0 && fd >= 0) { + FdAcquire(thr, pc, fd); } return res; } @@ -1119,57 +1278,64 @@ TSAN_INTERCEPTOR(long_t, readv, int fd, void *vec, int cnt) { TSAN_INTERCEPTOR(long_t, preadv64, int fd, void *vec, int cnt, u64 off) { SCOPED_TSAN_INTERCEPTOR(preadv64, fd, vec, cnt, off); int res = REAL(preadv64)(fd, vec, cnt, off); - if (res >= 0) { - Acquire(thr, pc, fd2addr(fd)); + if (res >= 0 && fd >= 0) { + FdAcquire(thr, pc, fd); } return res; } TSAN_INTERCEPTOR(long_t, write, int fd, void *buf, long_t sz) { SCOPED_TSAN_INTERCEPTOR(write, fd, buf, sz); - Release(thr, pc, fd2addr(fd)); + if (fd >= 0) + FdRelease(thr, pc, fd); int res = REAL(write)(fd, buf, sz); return res; } TSAN_INTERCEPTOR(long_t, pwrite, int fd, void *buf, long_t sz, unsigned off) { SCOPED_TSAN_INTERCEPTOR(pwrite, fd, buf, sz, off); - Release(thr, pc, fd2addr(fd)); + if (fd >= 0) + FdRelease(thr, pc, fd); int res = REAL(pwrite)(fd, buf, sz, off); return res; } TSAN_INTERCEPTOR(long_t, pwrite64, int fd, void *buf, long_t sz, u64 off) { SCOPED_TSAN_INTERCEPTOR(pwrite64, fd, buf, sz, off); - Release(thr, pc, fd2addr(fd)); + if (fd >= 0) + FdRelease(thr, pc, fd); int res = REAL(pwrite64)(fd, buf, sz, off); return res; } TSAN_INTERCEPTOR(long_t, writev, int fd, void *vec, int cnt) { SCOPED_TSAN_INTERCEPTOR(writev, fd, vec, cnt); - Release(thr, pc, fd2addr(fd)); + if (fd >= 0) + FdRelease(thr, pc, fd); int res = REAL(writev)(fd, vec, cnt); return res; } TSAN_INTERCEPTOR(long_t, pwritev64, int fd, void *vec, int cnt, u64 off) { SCOPED_TSAN_INTERCEPTOR(pwritev64, fd, vec, cnt, off); - Release(thr, pc, fd2addr(fd)); + if (fd >= 0) + FdRelease(thr, pc, fd); int res = REAL(pwritev64)(fd, vec, cnt, off); return res; } TSAN_INTERCEPTOR(long_t, send, int fd, void *buf, long_t len, int flags) { SCOPED_TSAN_INTERCEPTOR(send, fd, buf, len, flags); - Release(thr, pc, fd2addr(fd)); + if (fd >= 0) + FdRelease(thr, pc, fd); int res = REAL(send)(fd, buf, len, flags); return res; } TSAN_INTERCEPTOR(long_t, sendmsg, int fd, void *msg, int flags) { SCOPED_TSAN_INTERCEPTOR(sendmsg, fd, msg, flags); - Release(thr, pc, fd2addr(fd)); + if (fd >= 0) + FdRelease(thr, pc, fd); int res = REAL(sendmsg)(fd, msg, flags); return res; } @@ -1177,8 +1343,8 @@ TSAN_INTERCEPTOR(long_t, sendmsg, int fd, void *msg, int flags) { TSAN_INTERCEPTOR(long_t, recv, int fd, void *buf, long_t len, int flags) { SCOPED_TSAN_INTERCEPTOR(recv, fd, buf, len, flags); int res = REAL(recv)(fd, buf, len, flags); - if (res >= 0) { - Acquire(thr, pc, fd2addr(fd)); + if (res >= 0 && fd >= 0) { + FdAcquire(thr, pc, fd); } return res; } @@ -1186,15 +1352,15 @@ TSAN_INTERCEPTOR(long_t, recv, int fd, void *buf, long_t len, int flags) { TSAN_INTERCEPTOR(long_t, recvmsg, int fd, void *msg, int flags) { SCOPED_TSAN_INTERCEPTOR(recvmsg, fd, msg, flags); int res = REAL(recvmsg)(fd, msg, flags); - if (res >= 0) { - Acquire(thr, pc, fd2addr(fd)); + if (res >= 0 && fd >= 0) { + FdAcquire(thr, pc, fd); } return res; } TSAN_INTERCEPTOR(int, unlink, char *path) { SCOPED_TSAN_INTERCEPTOR(unlink, path); - Release(thr, pc, file2addr(path)); + Release(thr, pc, File2addr(path)); int res = REAL(unlink)(path); return res; } @@ -1202,19 +1368,57 @@ TSAN_INTERCEPTOR(int, unlink, char *path) { TSAN_INTERCEPTOR(void*, fopen, char *path, char *mode) { SCOPED_TSAN_INTERCEPTOR(fopen, path, mode); void *res = REAL(fopen)(path, mode); - Acquire(thr, pc, file2addr(path)); + Acquire(thr, pc, File2addr(path)); + if (res) { + int fd = fileno_unlocked(res); + if (fd >= 0) + FdFileCreate(thr, pc, fd); + } return res; } +TSAN_INTERCEPTOR(void*, freopen, char *path, char *mode, void *stream) { + SCOPED_TSAN_INTERCEPTOR(freopen, path, mode, stream); + if (stream) { + int fd = fileno_unlocked(stream); + if (fd >= 0) + FdClose(thr, pc, fd); + } + void *res = REAL(freopen)(path, mode, stream); + Acquire(thr, pc, File2addr(path)); + if (res) { + int fd = fileno_unlocked(res); + if (fd >= 0) + FdFileCreate(thr, pc, fd); + } + return res; +} + +TSAN_INTERCEPTOR(int, fclose, void *stream) { + { + SCOPED_TSAN_INTERCEPTOR(fclose, stream); + if (stream) { + int fd = fileno_unlocked(stream); + if (fd >= 0) + FdClose(thr, pc, fd); + } + } + return REAL(fclose)(stream); +} + TSAN_INTERCEPTOR(uptr, fread, void *ptr, uptr size, uptr nmemb, void *f) { - SCOPED_TSAN_INTERCEPTOR(fread, ptr, size, nmemb, f); - MemoryAccessRange(thr, pc, (uptr)ptr, size * nmemb, true); + { + SCOPED_TSAN_INTERCEPTOR(fread, ptr, size, nmemb, f); + MemoryAccessRange(thr, pc, (uptr)ptr, size * nmemb, true); + } return REAL(fread)(ptr, size, nmemb, f); } TSAN_INTERCEPTOR(uptr, fwrite, const void *p, uptr size, uptr nmemb, void *f) { - SCOPED_TSAN_INTERCEPTOR(fwrite, p, size, nmemb, f); - MemoryAccessRange(thr, pc, (uptr)p, size * nmemb, false); + { + SCOPED_TSAN_INTERCEPTOR(fwrite, p, size, nmemb, f); + MemoryAccessRange(thr, pc, (uptr)p, size * nmemb, false); + } return REAL(fwrite)(p, size, nmemb, f); } @@ -1226,7 +1430,7 @@ TSAN_INTERCEPTOR(int, puts, const char *s) { TSAN_INTERCEPTOR(int, rmdir, char *path) { SCOPED_TSAN_INTERCEPTOR(rmdir, path); - Release(thr, pc, dir2addr(path)); + Release(thr, pc, Dir2addr(path)); int res = REAL(rmdir)(path); return res; } @@ -1234,14 +1438,15 @@ TSAN_INTERCEPTOR(int, rmdir, char *path) { TSAN_INTERCEPTOR(void*, opendir, char *path) { SCOPED_TSAN_INTERCEPTOR(opendir, path); void *res = REAL(opendir)(path); - Acquire(thr, pc, dir2addr(path)); + if (res != 0) + Acquire(thr, pc, Dir2addr(path)); return res; } TSAN_INTERCEPTOR(int, epoll_ctl, int epfd, int op, int fd, void *ev) { SCOPED_TSAN_INTERCEPTOR(epoll_ctl, epfd, op, fd, ev); - if (op == EPOLL_CTL_ADD) { - Release(thr, pc, epollfd2addr(epfd)); + if (op == EPOLL_CTL_ADD && epfd >= 0) { + FdRelease(thr, pc, epfd); } int res = REAL(epoll_ctl)(epfd, op, fd, ev); return res; @@ -1250,8 +1455,8 @@ TSAN_INTERCEPTOR(int, epoll_ctl, int epfd, int op, int fd, void *ev) { TSAN_INTERCEPTOR(int, epoll_wait, int epfd, void *ev, int cnt, int timeout) { SCOPED_TSAN_INTERCEPTOR(epoll_wait, epfd, ev, cnt, timeout); int res = BLOCK_REAL(epoll_wait)(epfd, ev, cnt, timeout); - if (res > 0) { - Acquire(thr, pc, epollfd2addr(epfd)); + if (res > 0 && epfd >= 0) { + FdAcquire(thr, pc, epfd); } return res; } @@ -1423,6 +1628,19 @@ TSAN_INTERCEPTOR(int, munlockall, void) { return 0; } +TSAN_INTERCEPTOR(int, fork, int fake) { + SCOPED_TSAN_INTERCEPTOR(fork, fake); + // It's intercepted merely to process pending signals. + int pid = REAL(fork)(fake); + if (pid == 0) { + // child + FdOnFork(thr, pc); + } else if (pid > 0) { + // parent + } + return pid; +} + namespace __tsan { void ProcessPendingSignals(ThreadState *thr) { @@ -1545,7 +1763,7 @@ void InitializeInterceptors() { TSAN_INTERCEPT(pthread_rwlock_timedwrlock); TSAN_INTERCEPT(pthread_rwlock_unlock); - TSAN_INTERCEPT(pthread_cond_init); + // TSAN_INTERCEPT(pthread_cond_init); TSAN_INTERCEPT(pthread_cond_destroy); TSAN_INTERCEPT(pthread_cond_signal); TSAN_INTERCEPT(pthread_cond_broadcast); @@ -1566,6 +1784,28 @@ void InitializeInterceptors() { TSAN_INTERCEPT(sem_post); TSAN_INTERCEPT(sem_getvalue); + TSAN_INTERCEPT(open); + TSAN_INTERCEPT(open64); + TSAN_INTERCEPT(creat); + TSAN_INTERCEPT(creat64); + TSAN_INTERCEPT(dup); + TSAN_INTERCEPT(dup2); + TSAN_INTERCEPT(dup3); + TSAN_INTERCEPT(eventfd); + TSAN_INTERCEPT(signalfd); + TSAN_INTERCEPT(inotify_init); + TSAN_INTERCEPT(inotify_init1); + TSAN_INTERCEPT(socket); + TSAN_INTERCEPT(socketpair); + TSAN_INTERCEPT(connect); + TSAN_INTERCEPT(accept); + TSAN_INTERCEPT(accept4); + TSAN_INTERCEPT(epoll_create); + TSAN_INTERCEPT(epoll_create1); + TSAN_INTERCEPT(close); + TSAN_INTERCEPT(pipe); + TSAN_INTERCEPT(pipe2); + TSAN_INTERCEPT(read); TSAN_INTERCEPT(pread); TSAN_INTERCEPT(pread64); @@ -1583,6 +1823,8 @@ void InitializeInterceptors() { TSAN_INTERCEPT(unlink); TSAN_INTERCEPT(fopen); + TSAN_INTERCEPT(freopen); + TSAN_INTERCEPT(fclose); TSAN_INTERCEPT(fread); TSAN_INTERCEPT(fwrite); TSAN_INTERCEPT(puts); @@ -1608,6 +1850,8 @@ void InitializeInterceptors() { TSAN_INTERCEPT(mlockall); TSAN_INTERCEPT(munlockall); + TSAN_INTERCEPT(fork); + // Need to setup it, because interceptors check that the function is resolved. // But atexit is emitted directly into the module, so can't be resolved. REAL(atexit) = (int(*)(void(*)()))unreachable; @@ -1623,6 +1867,8 @@ void InitializeInterceptors() { Printf("ThreadSanitizer: failed to create thread key\n"); Die(); } + + FdInit(); } void internal_start_thread(void(*func)(void *arg), void *arg) { |