summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.h46
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h21
-rw-r--r--compiler-rt/lib/tsan/lit_tests/race_on_write.cc39
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_interceptors.cc27
4 files changed, 98 insertions, 35 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.h
index 0381216bde4..ad3590becc2 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.h
@@ -70,6 +70,51 @@ INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) {
# define INIT_PREAD64
#endif
+#if SANITIZER_INTERCEPT_WRITE
+INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) {
+ COMMON_INTERCEPTOR_ENTER(read, fd, ptr, count);
+ if (fd >= 0)
+ COMMON_INTERCEPTOR_FD_RELEASE(fd);
+ SSIZE_T res = REAL(write)(fd, ptr, count);
+ if (res > 0)
+ COMMON_INTERCEPTOR_READ_RANGE(ptr, res);
+ return res;
+}
+# define INIT_WRITE INTERCEPT_FUNCTION(write)
+#else
+# define INIT_WRITE
+#endif
+
+#if SANITIZER_INTERCEPT_PWRITE
+INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count) {
+ COMMON_INTERCEPTOR_ENTER(read, fd, ptr, count);
+ if (fd >= 0)
+ COMMON_INTERCEPTOR_FD_RELEASE(fd);
+ SSIZE_T res = REAL(pwrite)(fd, ptr, count);
+ if (res > 0)
+ COMMON_INTERCEPTOR_READ_RANGE(ptr, res);
+ return res;
+}
+# define INIT_PWRITE INTERCEPT_FUNCTION(pwrite)
+#else
+# define INIT_PWRITE
+#endif
+
+#if SANITIZER_INTERCEPT_PWRITE64
+INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count) {
+ COMMON_INTERCEPTOR_ENTER(read, fd, ptr, count);
+ if (fd >= 0)
+ COMMON_INTERCEPTOR_FD_RELEASE(fd);
+ SSIZE_T res = REAL(pwrite64)(fd, ptr, count);
+ if (res > 0)
+ COMMON_INTERCEPTOR_READ_RANGE(ptr, res);
+ return res;
+}
+# define INIT_PWRITE64 INTERCEPT_FUNCTION(pwrite64)
+#else
+# define INIT_PWRITE64
+#endif
+
#if SANITIZER_INTERCEPT_PRCTL
INTERCEPTOR(int, prctl, int option,
unsigned long arg2, unsigned long arg3, // NOLINT
@@ -95,5 +140,6 @@ INTERCEPTOR(int, prctl, int option,
INIT_PREAD; \
INIT_PREAD64; \
INIT_PRCTL; \
+ INIT_WRITE; \
#endif // SANITIZER_COMMON_INTERCEPTORS_H
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
index 1402060a1ae..86251d3d5af 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h
@@ -15,19 +15,24 @@
#include "sanitizer_internal_defs.h"
#if !defined(_WIN32)
-# define SANITIZER_INTERCEPT_READ 1
-# define SANITIZER_INTERCEPT_PREAD 1
+# define SI_NOT_WINDOWS 1
#else
-# define SANITIZER_INTERCEPT_READ 0
-# define SANITIZER_INTERCEPT_PREAD 0
+# define SI_NOT_WINDOWS 0
#endif
#if defined(__linux__) && !defined(ANDROID)
-# define SANITIZER_INTERCEPT_PREAD64 1
-# define SANITIZER_INTERCEPT_PRCTL 1
+# define SI_LINUX_NOT_ANDROID 1
#else
-# define SANITIZER_INTERCEPT_PRCTL 0
-# define SANITIZER_INTERCEPT_PREAD64 0
+# define SI_LINUX_NOT_ANDROID 0
#endif
+# define SANITIZER_INTERCEPT_READ SI_NOT_WINDOWS
+# define SANITIZER_INTERCEPT_PREAD SI_NOT_WINDOWS
+# define SANITIZER_INTERCEPT_WRITE SI_NOT_WINDOWS
+# define SANITIZER_INTERCEPT_PWRITE SI_NOT_WINDOWS
+
+# define SANITIZER_INTERCEPT_PREAD64 SI_LINUX_NOT_ANDROID
+# define SANITIZER_INTERCEPT_PWRITE64 SI_LINUX_NOT_ANDROID
+# define SANITIZER_INTERCEPT_PRCTL SI_LINUX_NOT_ANDROID
+
diff --git a/compiler-rt/lib/tsan/lit_tests/race_on_write.cc b/compiler-rt/lib/tsan/lit_tests/race_on_write.cc
new file mode 100644
index 00000000000..f1b0bb1cbd6
--- /dev/null
+++ b/compiler-rt/lib/tsan/lit_tests/race_on_write.cc
@@ -0,0 +1,39 @@
+// RUN: %clangxx_tsan -O1 %s -o %t && %t 2>&1 | FileCheck %s
+#include <pthread.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+int fd;
+char buf;
+
+void *Thread1(void *x) {
+ buf = 1;
+ sleep(1);
+ return NULL;
+}
+
+void *Thread2(void *x) {
+ write(fd, &buf, 1);
+ return NULL;
+}
+
+int main() {
+ fd = open("/dev/null", O_WRONLY);
+ if (fd < 0) return 1;
+ pthread_t t[2];
+ pthread_create(&t[0], NULL, Thread1, NULL);
+ sleep(1);
+ pthread_create(&t[1], NULL, Thread2, NULL);
+ pthread_join(t[0], NULL);
+ pthread_join(t[1], NULL);
+ close(fd);
+}
+
+// CHECK: WARNING: ThreadSanitizer: data race
+// CHECK: Read of size 1
+// CHECK: #0 write
+// CHECK: Previous write of size 1
+// CHECK: #0 Thread1
diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc
index 7dc295d4093..5d94e4200eb 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc
+++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc
@@ -1259,30 +1259,6 @@ TSAN_INTERCEPTOR(long_t, preadv64, int fd, void *vec, int cnt, u64 off) {
return res;
}
-TSAN_INTERCEPTOR(long_t, write, int fd, void *buf, long_t sz) {
- SCOPED_TSAN_INTERCEPTOR(write, fd, buf, sz);
- 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);
- 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);
- 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);
if (fd >= 0)
@@ -1799,9 +1775,6 @@ void InitializeInterceptors() {
TSAN_INTERCEPT(readv);
TSAN_INTERCEPT(preadv64);
- TSAN_INTERCEPT(write);
- TSAN_INTERCEPT(pwrite);
- TSAN_INTERCEPT(pwrite64);
TSAN_INTERCEPT(writev);
TSAN_INTERCEPT(pwritev64);
TSAN_INTERCEPT(send);
OpenPOWER on IntegriCloud