summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2012-12-07 15:32:56 +0000
committerDmitry Vyukov <dvyukov@google.com>2012-12-07 15:32:56 +0000
commit4e7c0f95fb8a27d6113590329df06ea2dc0505fb (patch)
tree176e0649dc3feb97fcd9dd192aa05df5c6fb503d
parente7108227ca3a7a2d98f07c34c263725674b83a5f (diff)
downloadbcm5719-llvm-4e7c0f95fb8a27d6113590329df06ea2dc0505fb.tar.gz
bcm5719-llvm-4e7c0f95fb8a27d6113590329df06ea2dc0505fb.zip
tsan: add pipe interceptors
llvm-svn: 169602
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_interceptors.cc81
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_stat.cc3
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_stat.h3
3 files changed, 79 insertions, 8 deletions
diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc
index 7fc1f79872c..7aad966215d 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc
+++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc
@@ -309,8 +309,8 @@ TSAN_INTERCEPTOR(void, siglongjmp, void *env, int val) {
}
enum FdType {
- FdOther, // Something we don't know about, global sync.
FdNone, // Does not require any sync.
+ FdGlobal, // Something we don't know about, global sync.
FdFile,
FdSock,
FdPipe,
@@ -327,7 +327,7 @@ struct FdContext {
static const int kMaxFds = 10 * 1024; // Everything else is synced globally.
FdDesc desc[kMaxFds];
// Addresses used for synchronization.
- u64 fdother;
+ u64 fdglobal;
u64 fdfile;
u64 fdsock;
u64 fdpipe;
@@ -338,19 +338,16 @@ struct FdContext {
static FdContext fdctx;
static void FdInit() {
- fdctx.desc[0].type = FdNone;
- fdctx.desc[1].type = FdNone;
- fdctx.desc[2].type = FdNone;
}
static void *FdAddr(int fd) {
if (fd >= FdContext::kMaxFds)
- return &fdctx.fdother;
+ return &fdctx.fdglobal;
FdDesc *desc = &fdctx.desc[fd];
- if (desc->type == FdOther)
- return &fdctx.fdother;
if (desc->type == FdNone)
return 0;
+ if (desc->type == FdGlobal)
+ return &fdctx.fdglobal;
if (desc->type == FdFile)
return &fdctx.fdfile;
if (desc->type == FdSock)
@@ -377,6 +374,48 @@ static void FdRelease(ThreadState *thr, uptr pc, int fd) {
Acquire(thr, pc, (uptr)addr);
}
+static void FdClose(ThreadState *thr, uptr pc, int fd) {
+ if (fd >= FdContext::kMaxFds)
+ return;
+ void *addr = FdAddr(fd);
+ if (addr) {
+ // To catch races between fd usage and close.
+ MemoryWrite1Byte(thr, pc, (uptr)addr);
+ SyncVar *s = CTX()->synctab.GetAndRemove(thr, pc, (uptr)addr);
+ if (s)
+ DestroyAndFree(s);
+ }
+ FdDesc *desc = &fdctx.desc[fd];
+ desc->type = FdNone;
+}
+
+static void FdCreatePipe(ThreadState *thr, uptr pc, int rfd, int wfd) {
+ if (rfd >= FdContext::kMaxFds || rfd >= FdContext::kMaxFds) {
+ if (rfd < FdContext::kMaxFds) {
+ FdDesc *rdesc = &fdctx.desc[rfd];
+ rdesc->type = FdGlobal;
+ }
+ if (wfd < FdContext::kMaxFds) {
+ FdDesc *wdesc = &fdctx.desc[wfd];
+ wdesc->type = FdGlobal;
+ }
+ }
+ FdDesc *rdesc = &fdctx.desc[rfd];
+ rdesc->type = FdPipe;
+ void *raddr = FdAddr(rfd);
+ if (raddr) {
+ // To catch races between fd usage and close.
+ MemoryWrite1Byte(thr, pc, (uptr)raddr);
+ }
+ FdDesc *wdesc = &fdctx.desc[wfd];
+ wdesc->type = FdPipe;
+ void *waddr = FdAddr(wfd);
+ if (waddr) {
+ // To catch races between fd usage and close.
+ MemoryWrite1Byte(thr, pc, (uptr)waddr);
+ }
+}
+
static uptr file2addr(char *path) {
(void)path;
static u64 addr;
@@ -1139,6 +1178,28 @@ TSAN_INTERCEPTOR(int, sem_getvalue, void *s, int *sval) {
return res;
}
+TSAN_INTERCEPTOR(int, close, int fd) {
+ SCOPED_TSAN_INTERCEPTOR(close, fd);
+ FdClose(thr, pc, fd);
+ return REAL(close)(fd);
+}
+
+TSAN_INTERCEPTOR(int, pipe, int pipefd[2]) {
+ SCOPED_TSAN_INTERCEPTOR(pipe, pipefd);
+ int res = REAL(pipe)(pipefd);
+ if (res == 0)
+ FdCreatePipe(thr, pc, pipefd[0], pipefd[1]);
+ return res;
+}
+
+TSAN_INTERCEPTOR(int, pipe2, int pipefd[2], int flags) {
+ SCOPED_TSAN_INTERCEPTOR(pipe2, pipefd, flags);
+ int res = REAL(pipe2)(pipefd, flags);
+ if (res == 0)
+ FdCreatePipe(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);
@@ -1625,6 +1686,10 @@ void InitializeInterceptors() {
TSAN_INTERCEPT(sem_post);
TSAN_INTERCEPT(sem_getvalue);
+ TSAN_INTERCEPT(close);
+ TSAN_INTERCEPT(pipe);
+ TSAN_INTERCEPT(pipe2);
+
TSAN_INTERCEPT(read);
TSAN_INTERCEPT(pread);
TSAN_INTERCEPT(pread64);
diff --git a/compiler-rt/lib/tsan/rtl/tsan_stat.cc b/compiler-rt/lib/tsan/rtl/tsan_stat.cc
index c16819f8c34..fb40f595ae2 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_stat.cc
+++ b/compiler-rt/lib/tsan/rtl/tsan_stat.cc
@@ -181,6 +181,9 @@ void StatOutput(u64 *stat) {
name[StatInt_sem_timedwait] = " sem_timedwait ";
name[StatInt_sem_post] = " sem_post ";
name[StatInt_sem_getvalue] = " sem_getvalue ";
+ name[StatInt_close] = " close ";
+ name[StatInt_pipe] = " pipe ";
+ name[StatInt_pipe2] = " pipe2 ";
name[StatInt_read] = " read ";
name[StatInt_pread] = " pread ";
name[StatInt_pread64] = " pread64 ";
diff --git a/compiler-rt/lib/tsan/rtl/tsan_stat.h b/compiler-rt/lib/tsan/rtl/tsan_stat.h
index d10580e7e92..70bed1105ad 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_stat.h
+++ b/compiler-rt/lib/tsan/rtl/tsan_stat.h
@@ -176,6 +176,9 @@ enum StatType {
StatInt_sem_timedwait,
StatInt_sem_post,
StatInt_sem_getvalue,
+ StatInt_close,
+ StatInt_pipe,
+ StatInt_pipe2,
StatInt_read,
StatInt_pread,
StatInt_pread64,
OpenPOWER on IntegriCloud