brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.5 KiB · c661293 Raw
86 lines · cpp
1// RUN: %clangxx_tsan -O1 %s -DBUILD_SO -fPIC -shared -o %t-so.so2// RUN: %clangxx_tsan -O1 %s %link_libcxx_tsan -o %t && %run %t 2>&1 | FileCheck %s3 4// A test for loading a dynamic library with static TLS.5// Such static TLS is a hack that allows a dynamic library to have faster TLS,6// but it can be loaded only iff all threads happened to allocate some excess7// of static TLS space for whatever reason. If it's not the case loading fails with:8// dlopen: cannot load any more object with static TLS9// We used to produce a false positive because dlopen will write into TLS10// of all existing threads to initialize/zero TLS region for the loaded library.11// And this appears to be racing with initialization of TLS in the thread12// since we model a write into the whole static TLS region (we don't know what part13// of it is currently unused):14// WARNING: ThreadSanitizer: data race (pid=2317365)15//   Write of size 1 at 0x7f1fa9bfcdd7 by main thread:16//     #0 memset17//     #1 init_one_static_tls18//     #2 __pthread_init_static_tls19//     [[ this is where main calls dlopen ]]20//     #3 main21//   Previous write of size 8 at 0x7f1fa9bfcdd0 by thread T1:22//     #0 __tsan_tls_initialization23 24// Failing on bots:25// https://lab.llvm.org/buildbot#builders/184/builds/158026// https://lab.llvm.org/buildbot#builders/18/builds/316727// UNSUPPORTED: target={{(aarch64|powerpc64).*}}28 29#ifdef BUILD_SO30 31__attribute__((tls_model("initial-exec"))) __thread char x = 42;32__attribute__((tls_model("initial-exec"))) __thread char y;33 34extern "C" int sofunc() { return ++x + ++y; }35 36#else // BUILD_SO37 38#  include "../test.h"39#  include <dlfcn.h>40#  include <string>41 42__thread int x[1023];43 44void *lib;45void (*func)();46int ready;47 48void *thread(void *arg) {49  barrier_wait(&barrier);50  if (__atomic_load_n(&ready, __ATOMIC_ACQUIRE))51    func();52  barrier_wait(&barrier);53  if (dlclose(lib)) {54    printf("error in dlclose: %s\n", dlerror());55    exit(1);56  }57  return 0;58}59 60int main(int argc, char *argv[]) {61  barrier_init(&barrier, 2);62  pthread_t th;63  pthread_create(&th, 0, thread, 0);64  lib = dlopen((std::string(argv[0]) + "-so.so").c_str(), RTLD_NOW);65  if (lib == 0) {66    printf("error in dlopen: %s\n", dlerror());67    return 1;68  }69  func = (void (*)())dlsym(lib, "sofunc");70  if (func == 0) {71    printf("error in dlsym: %s\n", dlerror());72    return 1;73  }74  __atomic_store_n(&ready, 1, __ATOMIC_RELEASE);75  barrier_wait(&barrier);76  func();77  barrier_wait(&barrier);78  pthread_join(th, 0);79  fprintf(stderr, "DONE\n");80  return 0;81}82 83#endif // BUILD_SO84 85// CHECK: DONE86