blob: f02280895f8363c3c258d4c468e5d49deaa65b55 [file] [log] [blame]
Stephen Hines2d1fdb22014-05-28 23:58:16 -07001// Check that if the list of shared libraries changes between the two race
2// reports, the second report occurring in a new shared library is still
3// symbolized correctly.
4
Stephen Hines6a211c52014-07-21 00:49:56 -07005// RUN: %clangxx_tsan -O1 %s -DBUILD_SO -fPIC -shared -o %t-so.so
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -08006// RUN: %clangxx_tsan -O1 %s -o %t -rdynamic && %deflake %run %t | FileCheck %s
Stephen Hines6a211c52014-07-21 00:49:56 -07007
8#ifdef BUILD_SO
9
Stephen Hines86277eb2015-03-23 12:06:32 -070010#include "test.h"
Stephen Hines6a211c52014-07-21 00:49:56 -070011
12int GLOB_SHARED = 0;
13
14extern "C"
Stephen Hines86277eb2015-03-23 12:06:32 -070015void init_so() {
16 barrier_init(&barrier, 2);
17}
18
19extern "C"
Stephen Hines6a211c52014-07-21 00:49:56 -070020void *write_from_so(void *unused) {
Stephen Hines86277eb2015-03-23 12:06:32 -070021 if (unused == 0)
22 barrier_wait(&barrier);
Stephen Hines6a211c52014-07-21 00:49:56 -070023 GLOB_SHARED++;
Stephen Hines86277eb2015-03-23 12:06:32 -070024 if (unused != 0)
25 barrier_wait(&barrier);
Stephen Hines6a211c52014-07-21 00:49:56 -070026 return NULL;
27}
28
29#else // BUILD_SO
Stephen Hines2d1fdb22014-05-28 23:58:16 -070030
Stephen Hines86277eb2015-03-23 12:06:32 -070031#include "test.h"
Stephen Hines2d1fdb22014-05-28 23:58:16 -070032#include <dlfcn.h>
Stephen Hines2d1fdb22014-05-28 23:58:16 -070033#include <string>
34
35int GLOB = 0;
36
37void *write_glob(void *unused) {
Stephen Hines86277eb2015-03-23 12:06:32 -070038 if (unused == 0)
39 barrier_wait(&barrier);
Stephen Hines2d1fdb22014-05-28 23:58:16 -070040 GLOB++;
Stephen Hines86277eb2015-03-23 12:06:32 -070041 if (unused != 0)
42 barrier_wait(&barrier);
Stephen Hines2d1fdb22014-05-28 23:58:16 -070043 return NULL;
44}
45
46void race_two_threads(void *(*access_callback)(void *unused)) {
47 pthread_t t1, t2;
48 pthread_create(&t1, NULL, access_callback, (void*)1);
49 pthread_create(&t2, NULL, access_callback, NULL);
50 pthread_join(t1, NULL);
51 pthread_join(t2, NULL);
52}
53
54int main(int argc, char *argv[]) {
Stephen Hines86277eb2015-03-23 12:06:32 -070055 barrier_init(&barrier, 2);
Stephen Hines2d1fdb22014-05-28 23:58:16 -070056 std::string path = std::string(argv[0]) + std::string("-so.so");
57 race_two_threads(write_glob);
58 // CHECK: write_glob
59 void *lib = dlopen(path.c_str(), RTLD_NOW);
60 if (!lib) {
61 printf("error in dlopen(): %s\n", dlerror());
62 return 1;
63 }
Stephen Hines86277eb2015-03-23 12:06:32 -070064 void (*init_so)();
65 *(void **)&init_so = dlsym(lib, "init_so");
66 init_so();
Stephen Hines2d1fdb22014-05-28 23:58:16 -070067 void *(*write_from_so)(void *unused);
68 *(void **)&write_from_so = dlsym(lib, "write_from_so");
69 race_two_threads(write_from_so);
70 // CHECK: write_from_so
71 return 0;
72}
Stephen Hines6a211c52014-07-21 00:49:56 -070073
74#endif // BUILD_SO