brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.3 KiB · 41b8f05 Raw
98 lines · c
1// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t > %t.out2// RUN: FileCheck %s --check-prefixes=CHECK,PARENT --input-file %t.out3// RUN: FileCheck %s --check-prefixes=CHECK,CHILD --input-file %t.out4// Regression test for5// https://groups.google.com/g/thread-sanitizer/c/TQrr4-9PRYo/m/HFR4FMi6AQAJ6#include "test.h"7#include <errno.h>8#include <signal.h>9#include <string.h>10#include <sys/types.h>11#include <sys/wait.h>12 13long glob = 0;14 15void *worker(void *main) {16  glob++;17  // synchronize with main18  barrier_wait(&barrier);19  // synchronize with atfork20  barrier_wait(&barrier);21  pthread_kill((pthread_t)main, SIGPROF);22  barrier_wait(&barrier);23  // synchronize with afterfork24  barrier_wait(&barrier);25  pthread_kill((pthread_t)main, SIGPROF);26  barrier_wait(&barrier);27  return NULL;28}29 30void atfork() {31  write(2, "in atfork\n", strlen("in atfork\n"));32  barrier_wait(&barrier);33  barrier_wait(&barrier);34  static volatile long a;35  __atomic_fetch_add(&a, 1, __ATOMIC_RELEASE);36}37 38void afterfork() {39  write(2, "in afterfork\n", strlen("in afterfork\n"));40  barrier_wait(&barrier);41  barrier_wait(&barrier);42  static volatile long a;43  __atomic_fetch_add(&a, 1, __ATOMIC_RELEASE);44}45 46void afterfork_child() {47  write(2, "in afterfork_child\n", strlen("in afterfork_child\n"));48  glob++;49}50 51void handler(int sig) {52  write(2, "in handler\n", strlen("in handler\n"));53  glob++;54}55 56int main() {57  barrier_init(&barrier, 2);58  struct sigaction act = {};59  act.sa_handler = &handler;60  if (sigaction(SIGPROF, &act, 0)) {61    perror("sigaction");62    exit(1);63  }64  pthread_atfork(atfork, afterfork, afterfork_child);65  pthread_t t;66  pthread_create(&t, NULL, worker, (void *)pthread_self());67  barrier_wait(&barrier);68  pid_t pid = fork();69  if (pid < 0) {70    fprintf(stderr, "fork failed: %d\n", errno);71    return 1;72  }73  if (pid == 0) {74    fprintf(stderr, "CHILD\n");75    return 0;76  }77  if (pid != waitpid(pid, NULL, 0)) {78    fprintf(stderr, "waitpid failed: %d\n", errno);79    return 1;80  }81  pthread_join(t, NULL);82  fprintf(stderr, "PARENT\n");83  return 0;84}85 86// CHECK: in atfork87// CHECK: in handler88// CHECK: ThreadSanitizer: data race89// CHECK:   Write of size 890// CHECK:     #0 handler91// CHECK:   Previous write of size 892// CHECK:     #0 worker93// PARENT: afterfork94// PARENT: in handler95// CHILD: afterfork_child96// CHILD: CHILD97// CHECK: PARENT98