[compiler-rt] r307212 - [tsan] Use pthread_sigmask instead of sigprocmask to block signals in a thread on Darwin
Kuba Mracek via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 5 15:17:44 PDT 2017
Author: kuba.brecka
Date: Wed Jul 5 15:17:44 2017
New Revision: 307212
URL: http://llvm.org/viewvc/llvm-project?rev=307212&view=rev
Log:
[tsan] Use pthread_sigmask instead of sigprocmask to block signals in a thread on Darwin
On Darwin, sigprocmask changes the signal mask for the entire process. This has some unwanted consequences, because e.g. internal_start_thread wants to disable signals only in the current thread (to make the new thread inherit the signal mask), which is currently broken on Darwin. This patch switches to pthread_sigmask.
Differential Revision: https://reviews.llvm.org/D35016
Added:
compiler-rt/trunk/test/tsan/Darwin/signals-blocked.cc
Modified:
compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc?rev=307212&r1=307211&r2=307212&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc Wed Jul 5 15:17:44 2017
@@ -191,7 +191,8 @@ void internal_sigfillset(__sanitizer_sig
uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set,
__sanitizer_sigset_t *oldset) {
- return sigprocmask(how, set, oldset);
+ // Don't use sigprocmask here, because it affects all threads.
+ return pthread_sigmask(how, set, oldset);
}
// Doesn't call pthread_atfork() handlers (but not available on 10.6).
Added: compiler-rt/trunk/test/tsan/Darwin/signals-blocked.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/tsan/Darwin/signals-blocked.cc?rev=307212&view=auto
==============================================================================
--- compiler-rt/trunk/test/tsan/Darwin/signals-blocked.cc (added)
+++ compiler-rt/trunk/test/tsan/Darwin/signals-blocked.cc Wed Jul 5 15:17:44 2017
@@ -0,0 +1,75 @@
+// RUN: %clangxx_tsan %s -o %t && %run %t 2>&1 | FileCheck %s
+
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <errno.h>
+
+volatile bool signal_delivered;
+
+static void handler(int sig) {
+ if (sig == SIGALRM)
+ signal_delivered = true;
+}
+
+static void* thr(void *p) {
+ sigset_t sigset;
+ sigemptyset(&sigset);
+ sigaddset(&sigset, SIGALRM);
+ int ret = pthread_sigmask(SIG_UNBLOCK, &sigset, NULL);
+ if (ret) abort();
+
+ struct sigaction act = {};
+ act.sa_handler = &handler;
+ if (sigaction(SIGALRM, &act, 0)) {
+ perror("sigaction");
+ exit(1);
+ }
+
+ itimerval t;
+ t.it_value.tv_sec = 0;
+ t.it_value.tv_usec = 10000;
+ t.it_interval = t.it_value;
+ if (setitimer(ITIMER_REAL, &t, 0)) {
+ perror("setitimer");
+ exit(1);
+ }
+
+ while (!signal_delivered) {
+ usleep(1000);
+ }
+
+ t.it_value.tv_usec = 0;
+ if (setitimer(ITIMER_REAL, &t, 0)) {
+ perror("setitimer");
+ exit(1);
+ }
+
+ fprintf(stderr, "SIGNAL DELIVERED\n");
+
+ return 0;
+}
+
+int main() {
+ sigset_t sigset;
+ sigemptyset(&sigset);
+ sigaddset(&sigset, SIGALRM);
+ int ret = pthread_sigmask(SIG_BLOCK, &sigset, NULL);
+ if (ret) abort();
+
+ pthread_t th;
+ pthread_create(&th, 0, thr, 0);
+ pthread_join(th, 0);
+
+ fprintf(stderr, "DONE\n");
+ return 0;
+}
+
+// CHECK-NOT: WARNING: ThreadSanitizer:
+// CHECK: SIGNAL DELIVERED
+// CHECK: DONE
+// CHECK-NOT: WARNING: ThreadSanitizer:
More information about the llvm-commits
mailing list