109 lines · cpp
1// RUN: basename %t-lib-instrumented.dylib | tr -d '\n' > %t.basename2// RUN: %clangxx_tsan %p/external-lib.cpp -shared \3// RUN: -o %t-lib-instrumented.dylib \4// RUN: -install_name @rpath/%{readfile:%t.basename}5 6// RUN: basename %t-lib-noninstrumented.dylib | tr -d '\n' > %t.basename7// RUN: %clangxx_tsan %p/external-lib.cpp -shared -fno-sanitize=thread \8// RUN: -o %t-lib-noninstrumented.dylib \9// RUN: -install_name @rpath/%{readfile:%t.basename}10 11// RUN: basename %t-lib-noninstrumented-callbacks.dylib | tr -d '\n' > %t.basename12// RUN: %clangxx_tsan %p/external-lib.cpp -shared -fno-sanitize=thread -DUSE_TSAN_CALLBACKS \13// RUN: -o %t-lib-noninstrumented-callbacks.dylib \14// RUN: -install_name @rpath/%{readfile:%t.basename}15 16// RUN: %clangxx_tsan %s %t-lib-instrumented.dylib -o %t-lib-instrumented17// RUN: %clangxx_tsan %s %t-lib-noninstrumented.dylib -o %t-lib-noninstrumented18// RUN: %clangxx_tsan %s %t-lib-noninstrumented-callbacks.dylib -o %t-lib-noninstrumented-callbacks19 20// RUN: %deflake %run %t-lib-instrumented 2>&1 \21// RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=TEST122// RUN: %run %t-lib-noninstrumented 2>&1 \23// RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=TEST224// RUN: %deflake %run %t-lib-noninstrumented-callbacks 2>&1 \25// RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=TEST326 27#include <thread>28 29#include <stdio.h>30#include <stdlib.h>31 32struct MyObject;33typedef MyObject *MyObjectRef;34extern "C" {35 void InitializeLibrary();36 MyObject *ObjectCreate();37 long ObjectRead(MyObject *);38 void ObjectWrite(MyObject *, long);39 void ObjectWriteAnother(MyObject *, long);40}41 42int main(int argc, char *argv[]) {43 InitializeLibrary();44 45 {46 MyObjectRef ref = ObjectCreate();47 std::thread t1([ref]{ ObjectRead(ref); });48 std::thread t2([ref]{ ObjectRead(ref); });49 t1.join();50 t2.join();51 }52 53 // CHECK-NOT: WARNING: ThreadSanitizer54 55 fprintf(stderr, "RR test done\n");56 // CHECK: RR test done57 58 {59 MyObjectRef ref = ObjectCreate();60 std::thread t1([ref]{ ObjectRead(ref); });61 std::thread t2([ref]{ ObjectWrite(ref, 66); });62 t1.join();63 t2.join();64 }65 66 // TEST1: WARNING: ThreadSanitizer: data race67 // TEST1: {{Write|Read}} of size 8 at68 // TEST1: Previous {{write|read}} of size 8 at69 // TEST1: Location is heap block of size 16 at70 71 // TEST2-NOT: WARNING: ThreadSanitizer72 73 // TEST3: WARNING: ThreadSanitizer: race on MyLibrary::MyObject74 // TEST3: {{Modifying|Read-only}} access of MyLibrary::MyObject at75 // TEST3: {{ObjectWrite|ObjectRead}}76 // TEST3: Previous {{modifying|read-only}} access of MyLibrary::MyObject at77 // TEST3: {{ObjectWrite|ObjectRead}}78 // TEST3: Location is MyLibrary::MyObject of size 16 at79 // TEST3: {{ObjectCreate}}80 // TEST3: SUMMARY: ThreadSanitizer: race on MyLibrary::MyObject {{.*}} in {{ObjectWrite|ObjectRead}}81 82 fprintf(stderr, "RW test done\n");83 // CHECK: RW test done84 85 {86 MyObjectRef ref = ObjectCreate();87 std::thread t1([ref]{ ObjectWrite(ref, 76); });88 std::thread t2([ref]{ ObjectWriteAnother(ref, 77); });89 t1.join();90 t2.join();91 }92 93 // TEST1-NOT: WARNING: ThreadSanitizer: data race94 95 // TEST2-NOT: WARNING: ThreadSanitizer96 97 // TEST3: WARNING: ThreadSanitizer: race on MyLibrary::MyObject98 // TEST3: Modifying access of MyLibrary::MyObject at99 // TEST3: {{ObjectWrite|ObjectWriteAnother}}100 // TEST3: Previous modifying access of MyLibrary::MyObject at101 // TEST3: {{ObjectWrite|ObjectWriteAnother}}102 // TEST3: Location is MyLibrary::MyObject of size 16 at103 // TEST3: {{ObjectCreate}}104 // TEST3: SUMMARY: ThreadSanitizer: race on MyLibrary::MyObject {{.*}} in {{ObjectWrite|ObjectWriteAnother}}105 106 fprintf(stderr, "WW test done\n");107 // CHECK: WW test done108}109