[PATCH] asan/tsan/msan: common interceptors for linux aio

Dmitry Vyukov dvyukov at google.com
Tue Nov 26 05:48:25 PST 2013


  remove debug printf

Hi eugenis,

http://llvm-reviews.chandlerc.com/D2269

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D2269?vs=5774&id=5775#toc

Files:
  tsan/rtl/tsan_interceptors.cc
  sanitizer_common/sanitizer_common_syscalls.inc
  msan/lit_tests/Linux/syscalls.cc

Index: tsan/rtl/tsan_interceptors.cc
===================================================================
--- tsan/rtl/tsan_interceptors.cc
+++ tsan/rtl/tsan_interceptors.cc
@@ -1929,8 +1929,17 @@
 
 static void syscall_fd_close(uptr pc, int fd) {
   TSAN_SYSCALL();
-  if (fd >= 0)
-    FdClose(thr, pc, fd);
+  FdClose(thr, pc, fd);
+}
+
+static void syscall_fd_acquire(uptr pc, int fd) {
+  TSAN_SYSCALL();
+  FdAcquire(thr, pc, fd);
+}
+
+static void syscall_fd_release(uptr pc, int fd) {
+  TSAN_SYSCALL();
+  FdRelease(thr, pc, fd);
 }
 
 static void syscall_pre_fork(uptr pc) {
@@ -1949,23 +1958,34 @@
 
 #define COMMON_SYSCALL_PRE_READ_RANGE(p, s) \
   syscall_access_range(GET_CALLER_PC(), (uptr)(p), (uptr)(s), false)
+
 #define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) \
   syscall_access_range(GET_CALLER_PC(), (uptr)(p), (uptr)(s), true)
+
 #define COMMON_SYSCALL_POST_READ_RANGE(p, s) \
   do {                                       \
     (void)(p);                               \
     (void)(s);                               \
   } while (false)
+
 #define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) \
   do {                                        \
     (void)(p);                                \
     (void)(s);                                \
   } while (false)
+
 #define COMMON_SYSCALL_FD_CLOSE(fd) syscall_fd_close(GET_CALLER_PC(), fd)
+
+#define COMMON_SYSCALL_FD_ACQUIRE(fd) syscall_fd_acquire(GET_CALLER_PC(), fd)
+
+#define COMMON_SYSCALL_FD_RELEASE(fd) syscall_fd_release(GET_CALLER_PC(), fd)
+
 #define COMMON_SYSCALL_PRE_FORK() \
   syscall_pre_fork(GET_CALLER_PC())
+
 #define COMMON_SYSCALL_POST_FORK(res) \
   syscall_post_fork(GET_CALLER_PC(), res)
+
 #include "sanitizer_common/sanitizer_common_syscalls.inc"
 
 namespace __tsan {
Index: sanitizer_common/sanitizer_common_syscalls.inc
===================================================================
--- sanitizer_common/sanitizer_common_syscalls.inc
+++ sanitizer_common/sanitizer_common_syscalls.inc
@@ -27,6 +27,10 @@
 //          and are now initialized.
 //   COMMON_SYSCALL_FD_CLOSE(fd)
 //          Called before closing file descriptor fd.
+//   COMMON_SYSCALL_FD_ACQUIRE(fd)
+//          Acquire memory visibility from fd.
+//   COMMON_SYSCALL_FD_RELEASE(fd)
+//          Release memory visibility to fd.
 //   COMMON_SYSCALL_PRE_FORK()
 //          Called before fork syscall.
 //   COMMON_SYSCALL_POST_FORK(long res)
@@ -49,15 +53,23 @@
 #define POST_WRITE(p, s) COMMON_SYSCALL_POST_WRITE_RANGE(p, s)
 
 #ifndef COMMON_SYSCALL_FD_CLOSE
-# define COMMON_SYSCALL_FD_CLOSE(fd)
+# define COMMON_SYSCALL_FD_CLOSE(fd) ((void)(fd))
+#endif
+
+#ifndef COMMON_SYSCALL_FD_ACQUIRE
+# define COMMON_SYSCALL_FD_ACQUIRE(fd) ((void)(fd))
+#endif
+
+#ifndef COMMON_SYSCALL_FD_RELEASE
+# define COMMON_SYSCALL_FD_RELEASE(fd) ((void)(fd))
 #endif
 
 #ifndef COMMON_SYSCALL_PRE_FORK
-# define COMMON_SYSCALL_PRE_FORK()
+# define COMMON_SYSCALL_PRE_FORK() {}
 #endif
 
 #ifndef COMMON_SYSCALL_POST_FORK
-# define COMMON_SYSCALL_POST_FORK(res)
+# define COMMON_SYSCALL_POST_FORK(res) {}
 #endif
 
 // FIXME: do some kind of PRE_READ for all syscall arguments (int(s) and such).
@@ -1263,43 +1275,53 @@
 
 POST_SYSCALL(io_destroy)(long res, long ctx) {}
 
-PRE_SYSCALL(io_getevents)(long ctx_id, long min_nr, long nr, void *events,
-                          void *timeout) {
+PRE_SYSCALL(io_getevents)(long ctx_id, long min_nr, long nr,
+                          __sanitizer_iocb **iocbpp, void *timeout) {
   if (timeout) PRE_READ(timeout, struct_timespec_sz);
 }
 
 POST_SYSCALL(io_getevents)(long res, long ctx_id, long min_nr, long nr,
-                           void *events, void *timeout) {
+                           __sanitizer_iocb **iocbpp, void *timeout) {
   if (res >= 0) {
-    if (events) POST_WRITE(events, res * struct_io_event_sz);
+    if (iocbpp) POST_WRITE(iocbpp, res * struct_io_event_sz);
     if (timeout) POST_WRITE(timeout, struct_timespec_sz);
   }
+  for (long i = 0; i < res; i++) {
+    if (iocbpp[i]->aio_lio_opcode == iocb_cmd_pwrite ||
+        iocbpp[i]->aio_lio_opcode == iocb_cmd_pread)
+      COMMON_SYSCALL_FD_ACQUIRE(iocbpp[i]->aio_fildes);
+  }
 }
 
 PRE_SYSCALL(io_submit)(long ctx_id, long nr, __sanitizer_iocb **iocbpp) {
   for (long i = 0; i < nr; ++i) {
-    if (iocbpp[i]->aio_lio_opcode == iocb_cmd_pwrite && iocbpp[i]->aio_buf &&
-        iocbpp[i]->aio_nbytes)
-      PRE_READ((void *)iocbpp[i]->aio_buf, iocbpp[i]->aio_nbytes);
+    uptr op = iocbpp[i]->aio_lio_opcode;
+    int fd = iocbpp[i]->aio_fildes;
+    void *buf = (void*)iocbpp[i]->aio_buf;
+    uptr len = (uptr)iocbpp[i]->aio_nbytes;
+    if (buf && len) {
+      if (op == iocb_cmd_pwrite)
+        PRE_READ(buf, len);
+      if (op == iocb_cmd_pread)
+        POST_WRITE(buf, len);
+    }
+    if (op == iocb_cmd_pwrite || op == iocb_cmd_pread)
+      COMMON_SYSCALL_FD_RELEASE(fd);
   }
 }
 
 POST_SYSCALL(io_submit)(long res, long ctx_id, long nr,
-                        __sanitizer_iocb **iocbpp) {
-  if (res > 0 && iocbpp) {
-    for (long i = 0; i < res; ++i) {
-      if (iocbpp[i]->aio_lio_opcode == iocb_cmd_pread && iocbpp[i]->aio_buf &&
-          iocbpp[i]->aio_nbytes)
-        POST_WRITE((void *)iocbpp[i]->aio_buf, iocbpp[i]->aio_nbytes);
-    }
-  }
-}
+    __sanitizer_iocb **iocbpp) {}
 
-PRE_SYSCALL(io_cancel)(long ctx_id, void *iocb, void *result) {}
+PRE_SYSCALL(io_cancel)(long ctx_id, __sanitizer_iocb *iocb, void *result) {}
 
-POST_SYSCALL(io_cancel)(long res, long ctx_id, void *iocb, void *result) {
-  if (res >= 0) {
-    if (iocb) POST_WRITE(iocb, sizeof(__sanitizer_iocb));
+POST_SYSCALL(io_cancel)(long res, long ctx_id, __sanitizer_iocb *iocb,
+    void *result) {
+  if (res == 0) {
+    if (iocb) {
+      COMMON_SYSCALL_FD_ACQUIRE(iocb->aio_fildes);
+      POST_WRITE(iocb, sizeof(__sanitizer_iocb));
+    }
     if (result) POST_WRITE(result, struct_io_event_sz);
   }
 }
Index: msan/lit_tests/Linux/syscalls.cc
===================================================================
--- msan/lit_tests/Linux/syscalls.cc
+++ msan/lit_tests/Linux/syscalls.cc
@@ -93,8 +93,8 @@
   iocb[1].aio_lio_opcode = IOCB_CMD_PREAD;
   iocb[1].aio_buf = (__u64)(&buf[kFortyTwo]);
   iocb[1].aio_nbytes = kFortyTwo;
-  __sanitizer_syscall_post_io_submit(1, 0, 2, &iocbp);
-  assert(__msan_test_shadow(buf, sizeof(buf)) == kFortyTwo);
+  __sanitizer_syscall_pre_io_submit(0, 2, &iocbp);
+  assert(__msan_test_shadow(buf, sizeof(buf)) == 2 * kFortyTwo);
 
   __msan_poison(buf, sizeof(buf));
   char *p = buf;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2269.3.patch
Type: text/x-patch
Size: 6522 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131126/0a9f9b97/attachment.bin>


More information about the llvm-commits mailing list