[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