summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKamil Rytarowski <n54@gmx.com>2017-11-03 20:48:19 +0000
committerKamil Rytarowski <n54@gmx.com>2017-11-03 20:48:19 +0000
commit55435b74271433e1767bb4f6d192f273862ff698 (patch)
tree87171fb7b655ddc002fdbfd4f4cb5bf156abb2be
parent0c99007db1b31d5d00c449ad2af2dd9bda051844 (diff)
downloadbcm5719-llvm-55435b74271433e1767bb4f6d192f273862ff698.tar.gz
bcm5719-llvm-55435b74271433e1767bb4f6d192f273862ff698.zip
Correct detection of a thread termination
Summary: Stop using the Linux solution with pthread_key_create(3). This approach does not work on NetBSD, because calling the thread destructor is not the latest operation on a POSIX thread entity. NetBSD's libpthread still calls at least pthread_mutex_lock and pthread_mutex_unlock. Detect _lwp_exit(2) call as it is really the latest operation called from a detaching POSIX thread. This resolves one set of crashes observed in the Thread Sanitizer execution. Sponsored by <The NetBSD Foundation> Reviewers: joerg, kcc, vitalybuka, dvyukov, eugenis Reviewed By: vitalybuka Subscribers: llvm-commits, kubamracek, #sanitizers Tags: #sanitizers Differential Revision: https://reviews.llvm.org/D39618 llvm-svn: 317363
-rw-r--r--compiler-rt/lib/tsan/rtl/tsan_interceptors.cc21
1 files changed, 17 insertions, 4 deletions
diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc
index 9fbfef52cdc..db92f7528a0 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc
+++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc
@@ -265,7 +265,7 @@ static ThreadSignalContext *SigCtx(ThreadState *thr) {
return ctx;
}
-#if !SANITIZER_MAC
+#if !SANITIZER_MAC && !SANITIZER_NETBSD
static unsigned g_thread_finalize_key;
#endif
@@ -869,7 +869,7 @@ void DestroyThreadState() {
}
} // namespace __tsan
-#if !SANITIZER_MAC
+#if !SANITIZER_MAC && !SANITIZER_NETBSD
static void thread_finalize(void *v) {
uptr iter = (uptr)v;
if (iter > 1) {
@@ -899,7 +899,7 @@ extern "C" void *__tsan_thread_start_func(void *arg) {
ThreadState *thr = cur_thread();
// Thread-local state is not initialized yet.
ScopedIgnoreInterceptors ignore;
-#if !SANITIZER_MAC
+#if !SANITIZER_MAC && !SANITIZER_NETBSD
ThreadIgnoreBegin(thr, 0);
if (pthread_setspecific(g_thread_finalize_key,
(void *)GetPthreadDestructorIterations())) {
@@ -2448,6 +2448,17 @@ TSAN_INTERCEPTOR(void *, __tls_get_addr, void *arg) {
}
#endif
+#if SANITIZER_NETBSD
+TSAN_INTERCEPTOR(void, _lwp_exit) {
+ SCOPED_TSAN_INTERCEPTOR(_lwp_exit);
+ REAL(_lwp_exit)();
+ DestroyThreadState();
+}
+#define TSAN_MAYBE_INTERCEPT__LWP_EXIT TSAN_INTERCEPT(_lwp_exit)
+#else
+#define TSAN_MAYBE_INTERCEPT__LWP_EXIT
+#endif
+
namespace __tsan {
static void finalize(void *arg) {
@@ -2616,6 +2627,8 @@ void InitializeInterceptors() {
TSAN_INTERCEPT(__tls_get_addr);
#endif
+ TSAN_MAYBE_INTERCEPT__LWP_EXIT;
+
#if !SANITIZER_MAC && !SANITIZER_ANDROID
// Need to setup it, because interceptors check that the function is resolved.
// But atexit is emitted directly into the module, so can't be resolved.
@@ -2627,7 +2640,7 @@ void InitializeInterceptors() {
Die();
}
-#if !SANITIZER_MAC
+#if !SANITIZER_MAC && !SANITIZER_NETBSD
if (pthread_key_create(&g_thread_finalize_key, &thread_finalize)) {
Printf("ThreadSanitizer: failed to create thread key\n");
Die();
OpenPOWER on IntegriCloud