1// Regression test for 2// https://code.google.com/p/address-sanitizer/issues/detail?id=178 3 4// Assume we're on Darwin and try to pass -U to the linker. If this flag is 5// unsupported, don't use it. 6// RUN: %clangxx_asan -O0 -DSHARED_LIB %s \ 7// RUN: -fPIC -shared -o %t-so.so -Wl,-U,_inc_global || \ 8// RUN: %clangxx_asan -O0 -DSHARED_LIB %s \ 9// RUN: -fPIC -shared -o %t-so.so 10// If the linker doesn't support --export-dynamic (which is ELF-specific), 11// try to link without that option. 12// FIXME: find a better solution. 13// RUN: %clangxx_asan -O0 %s -pthread -ldl -o %t -Wl,--export-dynamic || \ 14// RUN: %clangxx_asan -O0 %s -pthread -ldl -o %t 15// RUN: ASAN_OPTIONS=strict_init_order=true %run %t 2>&1 | FileCheck %s 16#if !defined(SHARED_LIB) 17#include <dlfcn.h> 18#include <pthread.h> 19#include <stdio.h> 20#include <unistd.h> 21 22#include <string> 23 24using std::string; 25 26int foo() { 27 return 42; 28} 29int global = foo(); 30 31__attribute__((visibility("default"))) 32extern "C" 33void inc_global() { 34 global++; 35} 36 37void *global_poller(void *arg) { 38 while (true) { 39 if (global != 42) 40 break; 41 usleep(100); 42 } 43 return 0; 44} 45 46int main(int argc, char *argv[]) { 47 pthread_t p; 48 pthread_create(&p, 0, global_poller, 0); 49 string path = string(argv[0]) + "-so.so"; 50 if (0 == dlopen(path.c_str(), RTLD_NOW)) { 51 fprintf(stderr, "dlerror: %s\n", dlerror()); 52 return 1; 53 } 54 pthread_join(p, 0); 55 printf("PASSED\n"); 56 // CHECK: PASSED 57 return 0; 58} 59#else // SHARED_LIB 60#include <stdio.h> 61#include <unistd.h> 62 63extern "C" void inc_global(); 64 65int slow_init() { 66 sleep(1); 67 inc_global(); 68 return 42; 69} 70 71int slowly_init_glob = slow_init(); 72#endif // SHARED_LIB 73