diff options
author | Kuba Mracek <mracek@apple.com> | 2017-05-03 16:51:01 +0000 |
---|---|---|
committer | Kuba Mracek <mracek@apple.com> | 2017-05-03 16:51:01 +0000 |
commit | 4e8f70074eb0b1b8612f770d269791afaac38f74 (patch) | |
tree | 145f99b95c637f2424f8340a2352ce2d92a251e1 /test/tsan | |
parent | f5be24d91f5c9975ce71c5343b7c5731ce560d42 (diff) |
[tsan] Detect races on modifying accesses in Swift code
This patch allows the Swift compiler to emit calls to `__tsan_external_write` before starting any modifying access, which will cause TSan to detect races on arrays, dictionaries and other classes defined in non-instrumented modules. Races on collections from the Swift standard library and user-defined structs and a frequent cause of subtle bugs and it's important that TSan detects those on top of existing LLVM IR instrumentation, which already detects races in direct memory accesses.
Differential Revision: https://reviews.llvm.org/D31630
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@302050 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/tsan')
-rw-r--r-- | test/tsan/Darwin/external-dups.cc | 4 | ||||
-rw-r--r-- | test/tsan/Darwin/external-swift.cc | 92 | ||||
-rw-r--r-- | test/tsan/Darwin/external.cc | 14 |
3 files changed, 102 insertions, 8 deletions
diff --git a/test/tsan/Darwin/external-dups.cc b/test/tsan/Darwin/external-dups.cc index 79432bac4..ca1eb3e7c 100644 --- a/test/tsan/Darwin/external-dups.cc +++ b/test/tsan/Darwin/external-dups.cc @@ -28,7 +28,7 @@ int main(int argc, char *argv[]) { barrier_wait(&barrier); ExternalWrite(opaque_object); }); - // CHECK: WARNING: ThreadSanitizer: race on a library object + // CHECK: WARNING: ThreadSanitizer: race on HelloWorld t1.join(); t2.join(); } @@ -46,7 +46,7 @@ int main(int argc, char *argv[]) { barrier_wait(&barrier); ExternalWrite(opaque_object); }); - // CHECK: WARNING: ThreadSanitizer: race on a library object + // CHECK: WARNING: ThreadSanitizer: race on HelloWorld t1.join(); t2.join(); } diff --git a/test/tsan/Darwin/external-swift.cc b/test/tsan/Darwin/external-swift.cc new file mode 100644 index 000000000..f6f9e7f4e --- /dev/null +++ b/test/tsan/Darwin/external-swift.cc @@ -0,0 +1,92 @@ +// RUN: %clangxx_tsan %s -o %t +// RUN: %deflake %run %t 2>&1 | FileCheck %s + +#include <thread> + +#import "../test.h" + +extern "C" { +void __tsan_write8(void *addr); +} + +static void *tag = (void *)0x1; + +__attribute__((no_sanitize("thread"))) +void ExternalWrite(void *addr) { + __tsan_external_write(addr, nullptr, tag); +} + +__attribute__((no_sanitize("thread"))) +void RegularWrite(void *addr) { + __tsan_write8(addr); +} + +int main(int argc, char *argv[]) { + barrier_init(&barrier, 2); + fprintf(stderr, "Start.\n"); + // CHECK: Start. + + { + void *opaque_object = malloc(16); + std::thread t1([opaque_object] { + ExternalWrite(opaque_object); + barrier_wait(&barrier); + }); + std::thread t2([opaque_object] { + barrier_wait(&barrier); + ExternalWrite(opaque_object); + }); + // CHECK: WARNING: ThreadSanitizer: Swift access race + // CHECK: Modifying access of Swift variable at {{.*}} by thread {{.*}} + // CHECK: Previous modifying access of Swift variable at {{.*}} by thread {{.*}} + // CHECK: SUMMARY: ThreadSanitizer: Swift access race + t1.join(); + t2.join(); + } + + fprintf(stderr, "external+external test done.\n"); + // CHECK: external+external test done. + + { + void *opaque_object = malloc(16); + std::thread t1([opaque_object] { + ExternalWrite(opaque_object); + barrier_wait(&barrier); + }); + std::thread t2([opaque_object] { + barrier_wait(&barrier); + RegularWrite(opaque_object); + }); + // CHECK: WARNING: ThreadSanitizer: Swift access race + // CHECK: Write of size 8 at {{.*}} by thread {{.*}} + // CHECK: Previous modifying access of Swift variable at {{.*}} by thread {{.*}} + // CHECK: SUMMARY: ThreadSanitizer: Swift access race + t1.join(); + t2.join(); + } + + fprintf(stderr, "external+regular test done.\n"); + // CHECK: external+regular test done. + + { + void *opaque_object = malloc(16); + std::thread t1([opaque_object] { + RegularWrite(opaque_object); + barrier_wait(&barrier); + }); + std::thread t2([opaque_object] { + barrier_wait(&barrier); + ExternalWrite(opaque_object); + }); + // CHECK: WARNING: ThreadSanitizer: Swift access race + // CHECK: Modifying access of Swift variable at {{.*}} by thread {{.*}} + // CHECK: Previous write of size 8 at {{.*}} by thread {{.*}} + // CHECK: SUMMARY: ThreadSanitizer: Swift access race + t1.join(); + t2.join(); + } + + fprintf(stderr, "regular+external test done.\n"); + // CHECK: regular+external test done. +} + diff --git a/test/tsan/Darwin/external.cc b/test/tsan/Darwin/external.cc index 211694ab7..e72281afa 100644 --- a/test/tsan/Darwin/external.cc +++ b/test/tsan/Darwin/external.cc @@ -67,13 +67,14 @@ int main(int argc, char *argv[]) { // TEST2-NOT: WARNING: ThreadSanitizer - // TEST3: WARNING: ThreadSanitizer: race on a library object - // TEST3: {{Mutating|read-only}} access of MyLibrary::MyObject at + // TEST3: WARNING: ThreadSanitizer: race on MyLibrary::MyObject + // TEST3: {{Modifying|read-only}} access of MyLibrary::MyObject at // TEST3: {{ObjectWrite|ObjectRead}} - // TEST3: Previous {{mutating|read-only}} access of MyLibrary::MyObject at + // TEST3: Previous {{modifying|read-only}} access of MyLibrary::MyObject at // TEST3: {{ObjectWrite|ObjectRead}} // TEST3: Location is MyLibrary::MyObject of size 16 at // TEST3: {{ObjectCreate}} + // TEST3: SUMMARY: ThreadSanitizer: race on MyLibrary::MyObject {{.*}} in {{ObjectWrite|ObjectRead}} fprintf(stderr, "RW test done\n"); // CHECK: RW test done @@ -90,13 +91,14 @@ int main(int argc, char *argv[]) { // TEST2-NOT: WARNING: ThreadSanitizer - // TEST3: WARNING: ThreadSanitizer: race on a library object - // TEST3: Mutating access of MyLibrary::MyObject at + // TEST3: WARNING: ThreadSanitizer: race on MyLibrary::MyObject + // TEST3: Modifying access of MyLibrary::MyObject at // TEST3: {{ObjectWrite|ObjectWriteAnother}} - // TEST3: Previous mutating access of MyLibrary::MyObject at + // TEST3: Previous modifying access of MyLibrary::MyObject at // TEST3: {{ObjectWrite|ObjectWriteAnother}} // TEST3: Location is MyLibrary::MyObject of size 16 at // TEST3: {{ObjectCreate}} + // TEST3: SUMMARY: ThreadSanitizer: race on MyLibrary::MyObject {{.*}} in {{ObjectWrite|ObjectWriteAnother}} fprintf(stderr, "WW test done\n"); // CHECK: WW test done |