[compiler-rt] a83eb04 - [lsan] Add interceptor for pthread_detach.

Marco Vanotti via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 25 14:22:55 PDT 2020


Author: Marco Vanotti
Date: 2020-09-25T14:22:45-07:00
New Revision: a83eb048cb9a75da7a07a9d5318bbdbf54885c87

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

LOG: [lsan] Add interceptor for pthread_detach.

This commit adds an interceptor for the pthread_detach function,
calling into ThreadRegistry::DetachThread, allowing for thread contexts
to be reused.

Without this change, programs may fail when they create more than 8K
threads.

Fixes: https://bugs.llvm.org/show_bug.cgi?id=47389

Reviewed By: vitalybuka

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

Added: 
    compiler-rt/test/lsan/TestCases/many_threads_detach.cpp

Modified: 
    compiler-rt/lib/lsan/lsan_interceptors.cpp
    compiler-rt/lib/lsan/lsan_thread.cpp
    compiler-rt/lib/lsan/lsan_thread.h

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/lsan/lsan_interceptors.cpp b/compiler-rt/lib/lsan/lsan_interceptors.cpp
index 9ce9b78c5a5f..39d075ddec09 100644
--- a/compiler-rt/lib/lsan/lsan_interceptors.cpp
+++ b/compiler-rt/lib/lsan/lsan_interceptors.cpp
@@ -476,6 +476,15 @@ INTERCEPTOR(int, pthread_join, void *th, void **ret) {
   return res;
 }
 
+INTERCEPTOR(int, pthread_detach, void *th) {
+  ENSURE_LSAN_INITED;
+  int tid = ThreadTid((uptr)th);
+  int res = REAL(pthread_detach)(th);
+  if (res == 0)
+    ThreadDetach(tid);
+  return res;
+}
+
 INTERCEPTOR(void, _exit, int status) {
   if (status == 0 && HasReportedLeaks()) status = common_flags()->exitcode;
   REAL(_exit)(status);
@@ -508,6 +517,7 @@ void InitializeInterceptors() {
   LSAN_MAYBE_INTERCEPT_MALLINFO;
   LSAN_MAYBE_INTERCEPT_MALLOPT;
   INTERCEPT_FUNCTION(pthread_create);
+  INTERCEPT_FUNCTION(pthread_detach);
   INTERCEPT_FUNCTION(pthread_join);
   INTERCEPT_FUNCTION(_exit);
 

diff  --git a/compiler-rt/lib/lsan/lsan_thread.cpp b/compiler-rt/lib/lsan/lsan_thread.cpp
index 40bdc254bb62..371a1f29dfe0 100644
--- a/compiler-rt/lib/lsan/lsan_thread.cpp
+++ b/compiler-rt/lib/lsan/lsan_thread.cpp
@@ -83,6 +83,11 @@ u32 ThreadTid(uptr uid) {
   return thread_registry->FindThread(FindThreadByUid, (void *)uid);
 }
 
+void ThreadDetach(u32 tid) {
+  CHECK_NE(tid, kInvalidTid);
+  thread_registry->DetachThread(tid, /* arg */ nullptr);
+}
+
 void ThreadJoin(u32 tid) {
   CHECK_NE(tid, kInvalidTid);
   thread_registry->JoinThread(tid, /* arg */ nullptr);

diff  --git a/compiler-rt/lib/lsan/lsan_thread.h b/compiler-rt/lib/lsan/lsan_thread.h
index 0ab1582de662..e876f9ff9cff 100644
--- a/compiler-rt/lib/lsan/lsan_thread.h
+++ b/compiler-rt/lib/lsan/lsan_thread.h
@@ -46,6 +46,7 @@ void InitializeMainThread();
 
 u32 ThreadCreate(u32 tid, uptr uid, bool detached, void *arg = nullptr);
 void ThreadFinish();
+void ThreadDetach(u32 tid);
 void ThreadJoin(u32 tid);
 u32 ThreadTid(uptr uid);
 

diff  --git a/compiler-rt/test/lsan/TestCases/many_threads_detach.cpp b/compiler-rt/test/lsan/TestCases/many_threads_detach.cpp
new file mode 100644
index 000000000000..1f85bcf1825a
--- /dev/null
+++ b/compiler-rt/test/lsan/TestCases/many_threads_detach.cpp
@@ -0,0 +1,23 @@
+// Test that threads are reused.
+// RUN: %clangxx_lsan %s -o %t -lpthread && %run %t
+
+#include <pthread.h>
+#include <stdlib.h>
+
+// Number of threads to create. This value is greater than kMaxThreads in
+// lsan_thread.cpp so that we can test that thread contexts are not being
+// reused.
+static const size_t kTestThreads = 10000;
+
+void *null_func(void *args) {
+  return NULL;
+}
+
+int main(void) {
+  for (size_t i = 0; i < kTestThreads; i++) {
+    pthread_t thread;
+    pthread_create(&thread, NULL, null_func, NULL);
+    pthread_detach(thread);
+  }
+  return 0;
+}


        


More information about the llvm-commits mailing list