[compiler-rt] d848186 - [tsan] Keep thread/stack for closed FD

Vitaly Buka via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 22 12:01:11 PDT 2022


Author: Vitaly Buka
Date: 2022-08-22T12:00:52-07:00
New Revision: d848186a3beed36b0bd6842b3cbdb3e7809b2848

URL: https://github.com/llvm/llvm-project/commit/d848186a3beed36b0bd6842b3cbdb3e7809b2848
DIFF: https://github.com/llvm/llvm-project/commit/d848186a3beed36b0bd6842b3cbdb3e7809b2848.diff

LOG: [tsan] Keep thread/stack for closed FD

Fixes b/242869837

Reviewed By: dvyukov

Differential Revision: https://reviews.llvm.org/D132068

Added: 
    compiler-rt/test/tsan/fd_location_closed.cpp

Modified: 
    compiler-rt/lib/tsan/rtl/tsan_fd.cpp
    compiler-rt/lib/tsan/rtl/tsan_fd.h
    compiler-rt/lib/tsan/rtl/tsan_report.cpp
    compiler-rt/lib/tsan/rtl/tsan_report.h
    compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/tsan/rtl/tsan_fd.cpp b/compiler-rt/lib/tsan/rtl/tsan_fd.cpp
index cf8f491fdbf09..ab295a69dce17 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_fd.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_fd.cpp
@@ -34,6 +34,7 @@ struct FdDesc {
   atomic_uintptr_t aux_sync;  // FdSync*
   Tid creation_tid;
   StackID creation_stack;
+  bool closed;
 };
 
 struct FdContext {
@@ -120,6 +121,7 @@ static void init(ThreadState *thr, uptr pc, int fd, FdSync *s,
   }
   d->creation_tid = thr->tid;
   d->creation_stack = CurrentStackId(thr, pc);
+  d->closed = false;
   // This prevents false positives on fd_close_norace3.cpp test.
   // The mechanics of the false positive are not completely clear,
   // but it happens only if global reset is enabled (flush_memory_ms=1)
@@ -155,7 +157,7 @@ void FdOnFork(ThreadState *thr, uptr pc) {
   }
 }
 
-bool FdLocation(uptr addr, int *fd, Tid *tid, StackID *stack) {
+bool FdLocation(uptr addr, int *fd, Tid *tid, StackID *stack, bool *closed) {
   for (int l1 = 0; l1 < kTableSizeL1; l1++) {
     FdDesc *tab = (FdDesc*)atomic_load(&fdctx.tab[l1], memory_order_relaxed);
     if (tab == 0)
@@ -166,6 +168,7 @@ bool FdLocation(uptr addr, int *fd, Tid *tid, StackID *stack) {
       *fd = l1 * kTableSizeL1 + l2;
       *tid = d->creation_tid;
       *stack = d->creation_stack;
+      *closed = d->closed;
       return true;
     }
   }
@@ -242,8 +245,9 @@ void FdClose(ThreadState *thr, uptr pc, int fd, bool write) {
         reinterpret_cast<FdSync *>(
             atomic_load(&d->aux_sync, memory_order_relaxed)));
   atomic_store(&d->aux_sync, 0, memory_order_relaxed);
-  d->creation_tid = kInvalidTid;
-  d->creation_stack = kInvalidStackID;
+  d->closed = true;
+  d->creation_tid = thr->tid;
+  d->creation_stack = CurrentStackId(thr, pc);
 }
 
 void FdFileCreate(ThreadState *thr, uptr pc, int fd) {

diff  --git a/compiler-rt/lib/tsan/rtl/tsan_fd.h b/compiler-rt/lib/tsan/rtl/tsan_fd.h
index 92625dc4b4a19..dddc1d2ab24b0 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_fd.h
+++ b/compiler-rt/lib/tsan/rtl/tsan_fd.h
@@ -54,7 +54,7 @@ void FdSocketCreate(ThreadState *thr, uptr pc, int fd);
 void FdSocketAccept(ThreadState *thr, uptr pc, int fd, int newfd);
 void FdSocketConnecting(ThreadState *thr, uptr pc, int fd);
 void FdSocketConnect(ThreadState *thr, uptr pc, int fd);
-bool FdLocation(uptr addr, int *fd, Tid *tid, StackID *stack);
+bool FdLocation(uptr addr, int *fd, Tid *tid, StackID *stack, bool *closed);
 void FdOnFork(ThreadState *thr, uptr pc);
 
 uptr File2addr(const char *path);

diff  --git a/compiler-rt/lib/tsan/rtl/tsan_report.cpp b/compiler-rt/lib/tsan/rtl/tsan_report.cpp
index 3b0bddc33a434..9b03adc16b996 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_report.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_report.cpp
@@ -200,8 +200,9 @@ static void PrintLocation(const ReportLocation *loc) {
   } else if (loc->type == ReportLocationTLS) {
     Printf("  Location is TLS of %s.\n\n", thread_name(thrbuf, loc->tid));
   } else if (loc->type == ReportLocationFD) {
-    Printf("  Location is file descriptor %d created by %s at:\n",
-        loc->fd, thread_name(thrbuf, loc->tid));
+    Printf("  Location is file descriptor %d %s by %s at:\n", loc->fd,
+           loc->fd_closed ? "destroyed" : "created",
+           thread_name(thrbuf, loc->tid));
     print_stack = true;
   }
   Printf("%s", d.Default());

diff  --git a/compiler-rt/lib/tsan/rtl/tsan_report.h b/compiler-rt/lib/tsan/rtl/tsan_report.h
index 718eacde7ec4c..3c88864af1477 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_report.h
+++ b/compiler-rt/lib/tsan/rtl/tsan_report.h
@@ -76,6 +76,7 @@ struct ReportLocation {
   uptr external_tag = 0;
   Tid tid = kInvalidTid;
   int fd = 0;
+  bool fd_closed = false;
   bool suppressable = false;
   ReportStack *stack = nullptr;
 };

diff  --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp
index 713acb0fe41de..c2cff60e2da2e 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp
@@ -281,9 +281,11 @@ void ScopedReportBase::AddLocation(uptr addr, uptr size) {
   int fd = -1;
   Tid creat_tid = kInvalidTid;
   StackID creat_stack = 0;
-  if (FdLocation(addr, &fd, &creat_tid, &creat_stack)) {
+  bool closed = false;
+  if (FdLocation(addr, &fd, &creat_tid, &creat_stack, &closed)) {
     auto *loc = New<ReportLocation>();
     loc->type = ReportLocationFD;
+    loc->fd_closed = closed;
     loc->fd = fd;
     loc->tid = creat_tid;
     loc->stack = SymbolizeStackId(creat_stack);

diff  --git a/compiler-rt/test/tsan/fd_location_closed.cpp b/compiler-rt/test/tsan/fd_location_closed.cpp
new file mode 100644
index 0000000000000..3b14821814c67
--- /dev/null
+++ b/compiler-rt/test/tsan/fd_location_closed.cpp
@@ -0,0 +1,29 @@
+// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t |& FileCheck %s
+#include "test.h"
+
+#include <fcntl.h>
+
+void *Thread(void *x) {
+  int fd = (long)x;
+  char buf;
+  read(fd, &buf, 1);
+  barrier_wait(&barrier);
+  close(fd);
+  return NULL;
+}
+
+int main() {
+  barrier_init(&barrier, 2);
+  int fd = open("/dev/random", O_RDONLY);
+  pthread_t t[2];
+  pthread_create(&t[0], NULL, Thread, (void *)(long)fd);
+  pthread_create(&t[1], NULL, Thread, (void *)(long)fd);
+
+  pthread_join(t[0], NULL);
+  pthread_join(t[1], NULL);
+}
+
+// CHECK: WARNING: ThreadSanitizer: data race
+// CHECK:   Location is file descriptor {{[0-9]+}} {{(destroyed by thread|created by main)}} 
+// CHECK:     #0 {{close|open}}
+// CHECK:     #1 {{Thread|main}}


        


More information about the llvm-commits mailing list