[compiler-rt] [sanitizer] Fix asserts in asan and tsan in pthread interceptors. (PR #75394)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 14 06:17:26 PST 2023
https://github.com/goussepi updated https://github.com/llvm/llvm-project/pull/75394
>From b96c62b6f6ac3b55b28c4eb59f2ce49e60e6b4a4 Mon Sep 17 00:00:00 2001
From: Pierre Gousseau <pierre.gousseau at sony.com>
Date: Wed, 13 Dec 2023 16:32:54 +0000
Subject: [PATCH 1/3] [sanitizer] Fix asserts in asan and tsan in pthread
interceptors.
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.
---
.../lib/sanitizer_common/sanitizer_thread_arg_retval.cpp | 3 ++-
.../lib/sanitizer_common/sanitizer_thread_registry.cpp | 3 ++-
compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp | 4 ++--
.../sanitizer_common/TestCases/Linux/pthread_join.cpp | 9 +++++++++
4 files changed, 15 insertions(+), 4 deletions(-)
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;
>From af0f4cf0cf2232b76ddd00bd3503ef8114d51367 Mon Sep 17 00:00:00 2001
From: Pierre Gousseau <pierre.gousseau at sony.com>
Date: Thu, 14 Dec 2023 14:12:48 +0000
Subject: [PATCH 2/3] Review comments: Remove pthread_detach check and test
join apis if not tsan.
---
.../lib/sanitizer_common/sanitizer_thread_registry.cpp | 3 +--
compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp | 4 ++--
.../sanitizer_common/TestCases/Linux/pthread_join.cpp | 8 ++++----
3 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.cpp
index 12d36277589626..741e0731c41559 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.cpp
@@ -345,8 +345,7 @@ u32 ThreadRegistry::ConsumeThreadUserId(uptr user_id) {
ThreadRegistryLock l(this);
u32 tid;
auto *t = live_.find(user_id);
- if (!t)
- return kInvalidTid;
+ CHECK(t);
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 bef0aa373119fa..80f86ca98ed9cd 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 if (tid != kInvalidTid)
+ else
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 if (tid != kInvalidTid)
+ else
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 dd70f12fbbef6c..0fe2cf26be5714 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Linux/pthread_join.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/pthread_join.cpp
@@ -29,6 +29,7 @@ static void *fn(void *args) {
int main(int argc, char **argv) {
use_exit = atoi(argv[1]);
+ bool is_tsan = !use_exit;
pthread_t thread[5];
assert(!pthread_create(&thread[0], nullptr, fn, (void *)1000));
assert(!pthread_create(&thread[1], nullptr, fn, (void *)1001));
@@ -41,14 +42,13 @@ 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);
+ assert(is_tsan || (pthread_tryjoin_np(thread[1], &res) == EBUSY));
}
{
@@ -57,14 +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);
+ assert(is_tsan || (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);
+ assert(is_tsan || (pthread_join(thread[3], &res) == ESRCH));
}
return 0;
>From e8e9362e557b59919ec9c93da223ddb2457434c5 Mon Sep 17 00:00:00 2001
From: Pierre Gousseau <pierre.gousseau at sony.com>
Date: Thu, 14 Dec 2023 14:15:47 +0000
Subject: [PATCH 3/3] clang-format
---
.../test/sanitizer_common/TestCases/Linux/pthread_join.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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 0fe2cf26be5714..371ccee4516d17 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Linux/pthread_join.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/pthread_join.cpp
@@ -12,11 +12,11 @@
#include <assert.h>
#include <ctime>
+#include <errno.h>
#include <pthread.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
-#include <errno.h>
bool use_exit;
static void *fn(void *args) {
More information about the llvm-commits
mailing list