[compiler-rt] 2d9bdd9 - Fix a deadlock in __cxa_guard_abort in tsan
Dmitry Vyukov via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 15 01:39:13 PST 2021
Author: Matt Kulukundis
Date: 2021-11-15T10:39:08+01:00
New Revision: 2d9bdd9dba05f01941f97a2ccc911212139142d0
URL: https://github.com/llvm/llvm-project/commit/2d9bdd9dba05f01941f97a2ccc911212139142d0
DIFF: https://github.com/llvm/llvm-project/commit/2d9bdd9dba05f01941f97a2ccc911212139142d0.diff
LOG: Fix a deadlock in __cxa_guard_abort in tsan
hat tip: @The_Whole_Daisy for helping to isolate
Reviewed By: dvyukov, fowles
Differential Revision: https://reviews.llvm.org/D113713
Added:
compiler-rt/test/tsan/static_init7.cpp
Modified:
compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
Removed:
################################################################################
diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
index 9a85ee00d2d71..9b62b2084ddd3 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
@@ -880,10 +880,11 @@ static int guard_acquire(ThreadState *thr, uptr pc, atomic_uint32_t *g,
}
}
-static void guard_release(ThreadState *thr, uptr pc, atomic_uint32_t *g) {
+static void guard_release(ThreadState *thr, uptr pc, atomic_uint32_t *g,
+ u32 v) {
if (!thr->in_ignored_lib)
Release(thr, pc, (uptr)g);
- u32 old = atomic_exchange(g, kGuardDone, memory_order_release);
+ u32 old = atomic_exchange(g, v, memory_order_release);
if (old & kGuardWaiter)
FutexWake(g, 1 << 30);
}
@@ -913,12 +914,12 @@ STDCXX_INTERCEPTOR(int, __cxa_guard_acquire, atomic_uint32_t *g) {
STDCXX_INTERCEPTOR(void, __cxa_guard_release, atomic_uint32_t *g) {
SCOPED_INTERCEPTOR_RAW(__cxa_guard_release, g);
- guard_release(thr, pc, g);
+ guard_release(thr, pc, g, kGuardDone);
}
STDCXX_INTERCEPTOR(void, __cxa_guard_abort, atomic_uint32_t *g) {
SCOPED_INTERCEPTOR_RAW(__cxa_guard_abort, g);
- atomic_store(g, kGuardInit, memory_order_relaxed);
+ guard_release(thr, pc, g, kGuardInit);
}
namespace __tsan {
@@ -1515,7 +1516,7 @@ TSAN_INTERCEPTOR(int, pthread_once, void *o, void (*f)()) {
// result in crashes due to too little stack space.
if (guard_acquire(thr, pc, a, !SANITIZER_MAC)) {
(*f)();
- guard_release(thr, pc, a);
+ guard_release(thr, pc, a, kGuardDone);
}
return 0;
}
diff --git a/compiler-rt/test/tsan/static_init7.cpp b/compiler-rt/test/tsan/static_init7.cpp
new file mode 100644
index 0000000000000..7d48302170fd7
--- /dev/null
+++ b/compiler-rt/test/tsan/static_init7.cpp
@@ -0,0 +1,39 @@
+// RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+struct P {
+ int x;
+ int y;
+};
+
+int Helper() {
+ try {
+ static int i = []() {
+ throw P{};
+ return 1;
+ }();
+ return i;
+ } catch (P) {
+ return 0;
+ }
+}
+
+void *Thread(void *x) {
+ for (int i = 0; i < 1000; ++i) {
+ Helper();
+ }
+ return 0;
+}
+
+int main() {
+ pthread_t t[2];
+ pthread_create(&t[0], 0, Thread, 0);
+ pthread_create(&t[1], 0, Thread, 0);
+ pthread_join(t[0], 0);
+ pthread_join(t[1], 0);
+ fprintf(stderr, "PASS\n");
+}
+
+// CHECK-NOT: WARNING: ThreadSanitizer: data race
More information about the llvm-commits
mailing list