1 // Test interaction of Asan recovery mode with asynch signals.
3 // RUN: %clang_asan -fsanitize-recover=address -pthread %s -o %t
6 // RUN: %env_asan_opts=halt_on_error=false:suppress_equal_pcs=false %run %t 100 >%t.log 2>&1 || true
7 // Collision will almost always get triggered but we still need to check the unlikely case:
8 // RUN: FileCheck --check-prefix=CHECK-COLLISION %s < %t.log || FileCheck --check-prefix=CHECK-NO-COLLISION %s < %t.log
10 #define _SVID_SOURCE 1 // SA_NODEFER
19 #include <sanitizer/asan_interface.h>
21 void random_delay(unsigned *seed) {
22 *seed = 1664525 * *seed + 1013904223;
23 struct timespec delay = { 0, (*seed % 1000) * 1000 };
27 volatile char bad[2] = {1, };
30 // CHECK-COLLISION: AddressSanitizer: nested bug in the same thread, aborting
31 // CHECK-NO-COLLISION: AddressSanitizer: use-after-poison
36 #define CHECK_CALL(e, msg) do { \
38 fprintf(stderr, "Failed to " msg "\n"); \
44 pthread_t sender_tid, receiver_tid;
46 pthread_mutex_t keep_alive_mu = PTHREAD_MUTEX_INITIALIZER;
48 void *sender(void *arg) {
50 for (size_t i = 0; i < niter; ++i) {
52 CHECK_CALL(pthread_kill(receiver_tid, SIGUSR1), "send signal");
57 void handler(int sig) {
58 // Expect error collisions here
62 void *receiver(void *arg) {
64 for (size_t i = 0; i < niter; ++i) {
69 // Parent will release this when it's ok to terminate
70 CHECK_CALL(pthread_mutex_lock(&keep_alive_mu), "unlock mutex");
74 int main(int argc, char **argv) {
76 fprintf(stderr, "Syntax: %s niter\n", argv[0]);
80 niter = (size_t)strtoul(argv[1], 0, 0);
83 memset(&sa, 0, sizeof(sa));
84 sa.sa_handler = handler;
85 sa.sa_flags = SA_NODEFER; // Enable nested handlers to add more stress
86 CHECK_CALL(sigaction(SIGUSR1, &sa, 0), "set sighandler");
88 __asan_poison_memory_region(&bad, sizeof(bad));
90 CHECK_CALL(pthread_mutex_lock(&keep_alive_mu), "lock mutex");
91 CHECK_CALL(pthread_create(&receiver_tid, 0, receiver, 0), "start thread");
92 CHECK_CALL(pthread_create(&sender_tid, 0, sender, 0), "start thread");
93 CHECK_CALL(pthread_join(sender_tid, 0), "join thread");
94 // Now allow receiver to die
95 CHECK_CALL(pthread_mutex_unlock(&keep_alive_mu), "unlock mutex");
96 CHECK_CALL(pthread_join(receiver_tid, 0), "join thread");
98 // CHECK-NO-COLLISION: All threads terminated
99 printf("All threads terminated\n");