[compiler-rt] [sanitizer] Fix asserts in asan and tsan in pthread interceptors. (PR #75394)

via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 13 14:23:22 PST 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-compiler-rt-sanitizer

Author: None (goussepi)

<details>
<summary>Changes</summary>

Calling one of pthread join/detach interceptor on an already joined/detached thread causes asserts such as:

AddressSanitizer: CHECK failed: sanitizer_thread_arg_retval.cpp:56 "((t)) != (0)" (0x0, 0x0) (tid=1236094)
    #<!-- -->0 0x555555634f8b in __asan::CheckUnwind() compiler-rt/lib/asan/asan_rtl.cpp:69:3
    #<!-- -->1 0x55555564e06e in __sanitizer::CheckFailed(char const*, int, char const*, unsigned long long, unsigned long long) compiler-rt/lib/sanitizer_common/sanitizer_termination.cpp:86:24
    #<!-- -->2 0x5555556491df in __sanitizer::ThreadArgRetval::BeforeJoin(unsigned long) const compiler-rt/lib/sanitizer_common/sanitizer_thread_arg_retval.cpp:56:3
    #<!-- -->3 0x5555556198ed in Join<___interceptor_pthread_tryjoin_np(void*, void**)::<lambda()> > compiler-rt/lib/asan/../sanitizer_common/sanitizer_thread_arg_retval.h:74:26
    #<!-- -->4 0x5555556198ed in pthread_tryjoin_np compiler-rt/lib/asan/asan_interceptors.cpp:311:29

The assert are replaced by error codes.

---
Full diff: https://github.com/llvm/llvm-project/pull/75394.diff


4 Files Affected:

- (modified) compiler-rt/lib/sanitizer_common/sanitizer_thread_arg_retval.cpp (+2-1) 
- (modified) compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.cpp (+2-1) 
- (modified) compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp (+2-2) 
- (modified) compiler-rt/test/sanitizer_common/TestCases/Linux/pthread_join.cpp (+9) 


``````````diff
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_thread_arg_retval.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_thread_arg_retval.cpp
index bddb2852140854..5edf6f1764f966 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_thread_arg_retval.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_thread_arg_retval.cpp
@@ -53,7 +53,8 @@ void ThreadArgRetval::Finish(uptr thread, void* retval) {
 u32 ThreadArgRetval::BeforeJoin(uptr thread) const {
   __sanitizer::Lock lock(&mtx_);
   auto t = data_.find(thread);
-  CHECK(t);
+  if (!t)
+    return 0;
   CHECK(!t->second.detached);
   return t->second.gen;
 }
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.cpp
index 741e0731c41559..12d36277589626 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.cpp
@@ -345,7 +345,8 @@ u32 ThreadRegistry::ConsumeThreadUserId(uptr user_id) {
   ThreadRegistryLock l(this);
   u32 tid;
   auto *t = live_.find(user_id);
-  CHECK(t);
+  if (!t)
+    return kInvalidTid;
   tid = t->second;
   live_.erase(t);
   auto *tctx = threads_[tid];
diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
index 80f86ca98ed9cd..bef0aa373119fa 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
@@ -1118,7 +1118,7 @@ TSAN_INTERCEPTOR(int, pthread_tryjoin_np, void *th, void **ret) {
   ThreadIgnoreEnd(thr);
   if (res == 0)
     ThreadJoin(thr, pc, tid);
-  else
+  else if (tid != kInvalidTid)
     ThreadNotJoined(thr, pc, tid, (uptr)th);
   return res;
 }
@@ -1132,7 +1132,7 @@ TSAN_INTERCEPTOR(int, pthread_timedjoin_np, void *th, void **ret,
   ThreadIgnoreEnd(thr);
   if (res == 0)
     ThreadJoin(thr, pc, tid);
-  else
+  else if (tid != kInvalidTid)
     ThreadNotJoined(thr, pc, tid, (uptr)th);
   return res;
 }
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/pthread_join.cpp b/compiler-rt/test/sanitizer_common/TestCases/Linux/pthread_join.cpp
index 212a28dd3985bb..dd70f12fbbef6c 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Linux/pthread_join.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/pthread_join.cpp
@@ -4,6 +4,10 @@
 // FIXME: Crashes on some bots in pthread_exit.
 // RUN: %run %t %if tsan %{ 0 %} %else %{ 1 %}
 
+// Check interceptors' return codes are the same without sanitizers.
+// RUN: %clangxx -pthread -fno-sanitize=all %s -o %t
+// RUN: %run %t 0
+
 // REQUIRES: glibc
 
 #include <assert.h>
@@ -12,6 +16,7 @@
 #include <stdint.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <errno.h>
 
 bool use_exit;
 static void *fn(void *args) {
@@ -36,12 +41,14 @@ int main(int argc, char **argv) {
   assert(!pthread_attr_destroy(&attr));
 
   assert(!pthread_detach(thread[0]));
+  assert(pthread_detach(thread[0]) == EINVAL);
 
   {
     void *res;
     while (pthread_tryjoin_np(thread[1], &res))
       sleep(1);
     assert(~(uintptr_t)res == 1001);
+    assert(pthread_tryjoin_np(thread[1], &res) == EBUSY);
   }
 
   {
@@ -50,12 +57,14 @@ int main(int argc, char **argv) {
     while (pthread_timedjoin_np(thread[2], &res, &tm))
       sleep(1);
     assert(~(uintptr_t)res == 1002);
+    assert(pthread_timedjoin_np(thread[2], &res, &tm) == ESRCH);
   }
 
   {
     void *res;
     assert(!pthread_join(thread[3], &res));
     assert(~(uintptr_t)res == 1003);
+    assert(pthread_join(thread[3], &res) == ESRCH);
   }
 
   return 0;

``````````

</details>


https://github.com/llvm/llvm-project/pull/75394


More information about the llvm-commits mailing list