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