1// RUN: %clang_tsan -fno-sanitize=thread -shared -fPIC -O1 -DBUILD_SO=1 %s -o \ 2// RUN: %t.so && \ 3// RUN: %clang_tsan -O1 %s %t.so -o %t && %run %t 2>&1 | FileCheck %s 4// RUN: llvm-objdump -t %t | FileCheck %s --check-prefix=CHECK-DUMP 5// CHECK-DUMP: {{[.]preinit_array.*__local_tsan_preinit}} 6 7// SANITIZER_CAN_USE_PREINIT_ARRAY is undefined on android. 8// UNSUPPORTED: android 9 10// Test checks if __tsan_init is called from .preinit_array. 11// Without initialization from .preinit_array, __tsan_init will be called from 12// constructors of the binary which are called after constructors of shared 13// library. 14 15#include <stdio.h> 16 17#if BUILD_SO 18 19// "volatile" is needed to avoid compiler optimize-out constructors. 20volatile int counter = 0; 21volatile int lib_constructor_call = 0; 22volatile int tsan_init_call = 0; 23 24__attribute__ ((constructor)) 25void LibConstructor() { 26 lib_constructor_call = ++counter; 27}; 28 29#else // BUILD_SO 30 31extern int counter; 32extern int lib_constructor_call; 33extern int tsan_init_call; 34 35volatile int bin_constructor_call = 0; 36 37__attribute__ ((constructor)) 38void BinConstructor() { 39 bin_constructor_call = ++counter; 40}; 41 42namespace __tsan { 43 44void OnInitialize() { 45 tsan_init_call = ++counter; 46} 47 48} 49 50int main() { 51 // CHECK: TSAN_INIT 1 52 // CHECK: LIB_CONSTRUCTOR 2 53 // CHECK: BIN_CONSTRUCTOR 3 54 printf("TSAN_INIT %d\n", tsan_init_call); 55 printf("LIB_CONSTRUCTOR %d\n", lib_constructor_call); 56 printf("BIN_CONSTRUCTOR %d\n", bin_constructor_call); 57 return 0; 58} 59 60#endif // BUILD_SO 61