1*7c3d14c8STreehugger Robot // RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2*7c3d14c8STreehugger Robot 3*7c3d14c8STreehugger Robot // Make sure TSan doesn't deadlock on a file stream lock at program shutdown. 4*7c3d14c8STreehugger Robot // See https://github.com/google/sanitizers/issues/454 5*7c3d14c8STreehugger Robot #ifdef __FreeBSD__ 6*7c3d14c8STreehugger Robot #define _WITH_GETLINE // to declare getline() 7*7c3d14c8STreehugger Robot #endif 8*7c3d14c8STreehugger Robot 9*7c3d14c8STreehugger Robot #include <pthread.h> 10*7c3d14c8STreehugger Robot #include <stdio.h> 11*7c3d14c8STreehugger Robot #include <unistd.h> 12*7c3d14c8STreehugger Robot thread(void * unused)13*7c3d14c8STreehugger Robotvoid *thread(void *unused) { 14*7c3d14c8STreehugger Robot char *line = NULL; 15*7c3d14c8STreehugger Robot size_t size; 16*7c3d14c8STreehugger Robot int fd[2]; 17*7c3d14c8STreehugger Robot pipe(fd); 18*7c3d14c8STreehugger Robot // Forge a non-standard stream to make sure it's not closed. 19*7c3d14c8STreehugger Robot FILE *stream = fdopen(fd[0], "r"); 20*7c3d14c8STreehugger Robot while (1) { 21*7c3d14c8STreehugger Robot volatile int res = getline(&line, &size, stream); 22*7c3d14c8STreehugger Robot (void)res; 23*7c3d14c8STreehugger Robot } 24*7c3d14c8STreehugger Robot return NULL; 25*7c3d14c8STreehugger Robot } 26*7c3d14c8STreehugger Robot main()27*7c3d14c8STreehugger Robotint main() { 28*7c3d14c8STreehugger Robot pthread_t t; 29*7c3d14c8STreehugger Robot pthread_attr_t a; 30*7c3d14c8STreehugger Robot pthread_attr_init(&a); 31*7c3d14c8STreehugger Robot pthread_attr_setdetachstate(&a, PTHREAD_CREATE_DETACHED); 32*7c3d14c8STreehugger Robot pthread_create(&t, &a, thread, NULL); 33*7c3d14c8STreehugger Robot pthread_attr_destroy(&a); 34*7c3d14c8STreehugger Robot fprintf(stderr, "DONE\n"); 35*7c3d14c8STreehugger Robot return 0; 36*7c3d14c8STreehugger Robot // ThreadSanitizer used to hang here because of a deadlock on a file stream. 37*7c3d14c8STreehugger Robot } 38*7c3d14c8STreehugger Robot 39*7c3d14c8STreehugger Robot // CHECK: DONE 40