1c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenko// Check that if the list of shared libraries changes between the two race 2c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenko// reports, the second report occurring in a new shared library is still 3c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenko// symbolized correctly. 4c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenko 55d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines// RUN: %clangxx_tsan -O1 %s -DBUILD_SO -fPIC -shared -o %t-so.so 65d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s 75d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines 85d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#ifdef BUILD_SO 95d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines 105d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#include <stddef.h> 115d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#include <unistd.h> 125d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines 135d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesint GLOB_SHARED = 0; 145d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines 155d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesextern "C" 165d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hinesvoid *write_from_so(void *unused) { 175d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines if (unused) 185d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines sleep(1); 195d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines GLOB_SHARED++; 205d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines return NULL; 215d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines} 225d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines 235d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#else // BUILD_SO 24c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenko 25c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenko#include <dlfcn.h> 26c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenko#include <pthread.h> 27c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenko#include <stdio.h> 282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include <stddef.h> 292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include <unistd.h> 30c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenko 31c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenko#include <string> 32c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenko 33c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenkoint GLOB = 0; 34c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenko 35c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenkovoid *write_glob(void *unused) { 362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (unused) 372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines sleep(1); 38c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenko GLOB++; 39c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenko return NULL; 40c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenko} 41c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenko 428a6cac57625f46e9e9a8977a518e8b92499d612fKostya Serebryanyvoid race_two_threads(void *(*access_callback)(void *unused)) { 43c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenko pthread_t t1, t2; 442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines pthread_create(&t1, NULL, access_callback, (void*)1); 45c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenko pthread_create(&t2, NULL, access_callback, NULL); 46c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenko pthread_join(t1, NULL); 47c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenko pthread_join(t2, NULL); 48c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenko} 49c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenko 50c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenkoint main(int argc, char *argv[]) { 51c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenko std::string path = std::string(argv[0]) + std::string("-so.so"); 52c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenko race_two_threads(write_glob); 53c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenko // CHECK: write_glob 54c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenko void *lib = dlopen(path.c_str(), RTLD_NOW); 55c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenko if (!lib) { 56c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenko printf("error in dlopen(): %s\n", dlerror()); 57c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenko return 1; 58c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenko } 598a6cac57625f46e9e9a8977a518e8b92499d612fKostya Serebryany void *(*write_from_so)(void *unused); 60c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenko *(void **)&write_from_so = dlsym(lib, "write_from_so"); 61c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenko race_two_threads(write_from_so); 62c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenko // CHECK: write_from_so 63c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenko return 0; 64c8feb2fee6dba5cbd1751ded5758910e230d9262Alexander Potapenko} 655d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines 665d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines#endif // BUILD_SO 67