Vitaly Buka | 1326391 | 2016-05-26 17:05:36 +0000 | [diff] [blame] | 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. |
| 20 | volatile int counter = 0; |
| 21 | volatile int lib_constructor_call = 0; |
| 22 | volatile int tsan_init_call = 0; |
| 23 | |
| 24 | __attribute__ ((constructor)) |
| 25 | void LibConstructor() { |
| 26 | lib_constructor_call = ++counter; |
| 27 | }; |
| 28 | |
| 29 | #else // BUILD_SO |
| 30 | |
| 31 | extern int counter; |
| 32 | extern int lib_constructor_call; |
| 33 | extern int tsan_init_call; |
| 34 | |
| 35 | volatile int bin_constructor_call = 0; |
| 36 | |
| 37 | __attribute__ ((constructor)) |
| 38 | void BinConstructor() { |
| 39 | bin_constructor_call = ++counter; |
| 40 | }; |
| 41 | |
| 42 | namespace __tsan { |
| 43 | |
| 44 | void OnInitialize() { |
| 45 | tsan_init_call = ++counter; |
| 46 | } |
| 47 | |
| 48 | } |
| 49 | |
| 50 | int 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 |