From 84c8627aa10bc7192a88ca0a7543e51f62370e84 Mon Sep 17 00:00:00 2001 From: Julian Lettner Date: Fri, 17 May 2024 11:15:26 -0700 Subject: [PATCH] Fix flaky test: signal_in_mutex_lock.cpp Fix flaky test: the spawned thread keeps spinning on `sampler_mutex` which may be released before the thread is terminated based on termination ordering. My understanding of C++ semantics are that the program here is invalid: the destructors of global variables are invoked at the time of program termination, and it is the responsibility of the program to ensure that invoking those destructors is safe. rdar://126768628 --- .../test/tsan/signal_in_mutex_lock.cpp | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/compiler-rt/test/tsan/signal_in_mutex_lock.cpp b/compiler-rt/test/tsan/signal_in_mutex_lock.cpp index ec99e23198400..49b8536539389 100644 --- a/compiler-rt/test/tsan/signal_in_mutex_lock.cpp +++ b/compiler-rt/test/tsan/signal_in_mutex_lock.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -13,9 +14,10 @@ std::mutex sampler_mutex; //dummy mutex to lock in the thread we spawn. std::mutex done_mutex; // guards the cv and done variables. std::condition_variable cv; bool done = false; +std::atomic spin = true; void *ThreadFunc(void *x) { - while (true) { + while (spin) { // Lock the mutex std::lock_guard guard(sampler_mutex); // Mutex is released at the end @@ -51,20 +53,26 @@ int main() { pthread_t thread; pthread_create(&thread, NULL, ThreadFunc, NULL); - // Lock the mutex before sending the signal - std::lock_guard guard(sampler_mutex); - // From now on thread 1 will be waiting for the lock + { + // Lock the mutex before sending the signal + std::lock_guard guard(sampler_mutex); + // From now on thread 1 will be waiting for the lock - // Send the SIGPROF signal to thread. - int r = pthread_kill(thread, SIGPROF); - assert(r == 0); + // Send the SIGPROF signal to thread. + int r = pthread_kill(thread, SIGPROF); + assert(r == 0); - // Wait until signal handler sends the data. - std::unique_lock lk(done_mutex); - cv.wait(lk, [] { return done; }); + // Wait until signal handler sends the data. + std::unique_lock lk(done_mutex); + cv.wait(lk, [] { return done; }); + + // We got the done variable from the signal handler. Exiting successfully. + fprintf(stderr, "PASS\n"); + } - // We got the done variable from the signal handler. Exiting successfully. - fprintf(stderr, "PASS\n"); + // Wait for thread to prevent it from spinning on a released mutex. + spin = false; + pthread_join(thread, nullptr); } // CHECK-NOT: WARNING: ThreadSanitizer: