16d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// Test that chained origins are fork-safe.
26d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// Run a number of threads that create new chained origins, then fork
36d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// and verify that origin reads do not deadlock in the child process.
46d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
57c9150579ed0278492f51cc8434b1d63a44b9bd1Pirama Arumuga Nainar// RUN: %clangxx_msan -std=c++11 -fsanitize-memory-track-origins=2 -g -O3 %s -o %t
66d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// RUN: MSAN_OPTIONS=store_context_size=1000,origin_history_size=0,origin_history_per_stack_limit=0 %run %t |& FileCheck %s
76d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
86d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// Fun fact: if test output is redirected to a file (as opposed to
96d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// being piped directly to FileCheck), we may lose some "done"s due to
106d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// a kernel bug:
116d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// https://lkml.org/lkml/2014/2/17/324
126d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
136d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
146d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#include <pthread.h>
156d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#include <unistd.h>
166d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#include <stdio.h>
176d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#include <stdlib.h>
186d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#include <sys/types.h>
196d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#include <sys/wait.h>
206d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#include <sys/time.h>
216d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#include <signal.h>
226d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#include <errno.h>
236d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
246d1862363c88c183b0ed7740fca876342cf0474bStephen Hines#include <sanitizer/msan_interface.h>
256d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
266d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesint done;
276d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
286d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid copy_uninit_thread2() {
296d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  volatile int x;
306d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  volatile int v;
316d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  while (true) {
326d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    v = x;
336d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    x = v;
346d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    if (__atomic_load_n(&done, __ATOMIC_RELAXED))
356d1862363c88c183b0ed7740fca876342cf0474bStephen Hines      return;
366d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  }
376d1862363c88c183b0ed7740fca876342cf0474bStephen Hines}
386d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
396d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid copy_uninit_thread1(int level) {
406d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  if (!level)
416d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    copy_uninit_thread2();
426d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  else
436d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    copy_uninit_thread1(level - 1);
446d1862363c88c183b0ed7740fca876342cf0474bStephen Hines}
456d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
466d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid *copy_uninit_thread(void *id) {
476d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  copy_uninit_thread1((long)id);
486d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  return 0;
496d1862363c88c183b0ed7740fca876342cf0474bStephen Hines}
506d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
516d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// Run through stackdepot in the child process.
526d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// If any of the hash table cells are locked, this may deadlock.
536d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid child() {
546d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  volatile int x;
556d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  volatile int v;
566d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  for (int i = 0; i < 10000; ++i) {
576d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    v = x;
586d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    x = v;
596d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  }
606d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  write(2, "done\n", 5);
616d1862363c88c183b0ed7740fca876342cf0474bStephen Hines}
626d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
636d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesvoid test() {
646d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  const int kThreads = 10;
656d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  pthread_t t[kThreads];
666d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  for (int i = 0; i < kThreads; ++i)
676d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    pthread_create(&t[i], NULL, copy_uninit_thread, (void*)(long)i);
686d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  usleep(100000);
696d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  pid_t pid = fork();
706d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  if (pid) {
716d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    // parent
726d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    __atomic_store_n(&done, 1, __ATOMIC_RELAXED);
736d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    pid_t p;
746d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    while ((p = wait(NULL)) == -1) {  }
756d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  } else {
766d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    // child
776d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    child();
786d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  }
796d1862363c88c183b0ed7740fca876342cf0474bStephen Hines}
806d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
816d1862363c88c183b0ed7740fca876342cf0474bStephen Hinesint main() {
826d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  const int kChildren = 20;
836d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  for (int i = 0; i < kChildren; ++i) {
846d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    pid_t pid = fork();
856d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    if (pid) {
866d1862363c88c183b0ed7740fca876342cf0474bStephen Hines      // parent
876d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    } else {
886d1862363c88c183b0ed7740fca876342cf0474bStephen Hines      test();
896d1862363c88c183b0ed7740fca876342cf0474bStephen Hines      exit(0);
906d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    }
916d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  }
926d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
936d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  for (int i = 0; i < kChildren; ++i) {
946d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    pid_t p;
956d1862363c88c183b0ed7740fca876342cf0474bStephen Hines    while ((p = wait(NULL)) == -1) {  }
966d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  }
976d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
986d1862363c88c183b0ed7740fca876342cf0474bStephen Hines  return 0;
996d1862363c88c183b0ed7740fca876342cf0474bStephen Hines}
1006d1862363c88c183b0ed7740fca876342cf0474bStephen Hines
1016d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// Expect 20 (== kChildren) "done" messages.
1026d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// CHECK: done
1036d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// CHECK: done
1046d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// CHECK: done
1056d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// CHECK: done
1066d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// CHECK: done
1076d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// CHECK: done
1086d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// CHECK: done
1096d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// CHECK: done
1106d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// CHECK: done
1116d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// CHECK: done
1126d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// CHECK: done
1136d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// CHECK: done
1146d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// CHECK: done
1156d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// CHECK: done
1166d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// CHECK: done
1176d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// CHECK: done
1186d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// CHECK: done
1196d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// CHECK: done
1206d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// CHECK: done
1216d1862363c88c183b0ed7740fca876342cf0474bStephen Hines// CHECK: done
122