Skip to content

Commit 105e4ad

Browse files
committed
[TSan] Add positive test for TSan + Dispatch on Linux
1) Enable tests that use `import Dispatch` on Linux. Add substitution `%import-libdispatch` that needs to be used for all cross-platform tests (i.e., tests that are intended to be run on other platforms than Darwin) that do `import Dispatch` or enable thread sanitizer. 2) Make sure as many existing Dispatch and TSan tests as possible run on Linux. Mark tests that would require substantial work with `UNSUPPORTED: OS=linux-gnu`. 3) Add integration-style Swift test that shows that TSan finds a simple race when using `Dispatch.async` incorrectly. A more complete test suite for TSan's libdispatch support lives on the LLVM/compiler-rt side. rdar://problem/49177535
1 parent ce3a5d1 commit 105e4ad

23 files changed

+143
-75
lines changed

test/ClangImporter/Dispatch_test.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// RUN: %target-typecheck-verify-swift
22

33
// REQUIRES: libdispatch
4+
// UNSUPPORTED: OS=linux-gnu
45

56
import Dispatch
67

test/IRGen/tsan-attributes.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22

33
// RUN: %target-swift-frontend -emit-ir -sanitize=thread %s | %FileCheck %s -check-prefix=TSAN
44

5-
// TSan is currently only supported on 64 bit mac and simulators.
6-
// (We do not test the simulators here.)
7-
// REQUIRES: CPU=x86_64, OS=macosx
5+
// TSan is only supported on 64 bit.
6+
// REQUIRES: PTRSIZE=64
87

98
// TSAN: define {{.*}} @"$s4main4testyyF"() [[DEFAULT_ATTRS:#[0-9]+]]
109
public func test() {

test/IRGen/tsan_coroutines.swift

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
// This test case used to crash when tsan ran before co-routine lowering.
22
// RUN: %target-swift-frontend -emit-ir -sanitize=thread %s | %FileCheck %s
33

4-
// TSan is currently only supported on 64 bit mac and simulators.
5-
// (We do not test the simulators here.)
6-
// REQUIRES: CPU=x86_64, OS=macosx
4+
// TSan is only supported on 64 bit.
5+
// REQUIRES: PTRSIZE=64
76

87
public class C { }
98

@@ -23,7 +22,7 @@ extension Foobar {
2322
}
2423

2524
// We used to crash emitting the subscript function.
26-
// CHECK: define swiftcc { i8*, %T15tsan_coroutines1CC* } @"$s15tsan_coroutines6FoobarVyAA1CCAC5IndexVcir"
25+
// CHECK: define{{( dllexport| protected)?}} swiftcc { i8*, %T15tsan_coroutines1CC* } @"$s15tsan_coroutines6FoobarVyAA1CCAC5IndexVcir"
2726
@_borrowed
2827
public subscript(position: Index) -> C {
2928
return things.values[position.myIndex]

test/Profiler/instrprof_tsan.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// RUN: %target-swift-frontend -emit-ir -profile-generate -sanitize=thread %s | %FileCheck %s
22

3-
// REQUIRES: OS=macosx
4-
// REQUIRES: CPU=x86_64
3+
// TSan is only supported on 64 bit.
4+
// REQUIRES: PTRSIZE=64
55

66
// CHECK: define {{.*}}empty
77
// CHECK-NOT: load{{.*}}empty

test/Runtime/lazy_witness_table_cycle.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// RUN: %target-run-simple-swift
22
// REQUIRES: executable_test
3-
// REQUIRES: objc_interop
3+
// REQUIRES: foundation
44

55
// SR-5958
66
import Foundation

test/SILGen/tsan_instrumentation.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
// RUN: %target-swift-emit-silgen -sanitize=thread %s | %FileCheck %s
2-
// REQUIRES: tsan_runtime
32

4-
// FIXME: This should be covered by "tsan_runtime"; older versions of Apple OSs
5-
// don't support TSan.
6-
// UNSUPPORTED: remote_run
3+
// TSan is only supported on 64 bit.
4+
// REQUIRES: PTRSIZE=64
75

86
func takesInout(_ p: inout Int) { }
97
func takesInout(_ p: inout MyStruct) { }

test/Sanitizers/tsan-emptyarraystorage.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// RUN: %target-run %t_tsan-binary 2>&1 | %FileCheck %s
44
// REQUIRES: executable_test
55
// REQUIRES: tsan_runtime
6+
// REQUIRES: foundation
67
// UNSUPPORTED: OS=tvos
78

89
// FIXME: This should be covered by "tsan_runtime"; older versions of Apple OSs
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// RUN: %target-swiftc_driver %s -g -sanitize=thread %import-libdispatch -o %t_tsan-binary
2+
// RUN: %target-codesign %t_tsan-binary
3+
// RUN: not env %env-TSAN_OPTIONS=abort_on_error=0 %target-run %t_tsan-binary 2>&1 | %FileCheck %s
4+
// REQUIRES: executable_test
5+
// REQUIRES: tsan_runtime
6+
// UNSUPPORTED: OS=tvos
7+
8+
// FIXME: This should be covered by "tsan_runtime"; older versions of Apple OSs
9+
// don't support TSan.
10+
// UNSUPPORTED: remote_run
11+
12+
// Test ThreadSanitizer execution end-to-end with libdispatch.
13+
14+
import Dispatch
15+
16+
let sync1 = DispatchSemaphore(value: 0)
17+
let sync2 = DispatchSemaphore(value: 0)
18+
let finish = DispatchSemaphore(value: 0)
19+
20+
let q = DispatchQueue(label: "q", attributes: .concurrent)
21+
22+
var racy = 1
23+
24+
q.async {
25+
sync1.wait()
26+
sync2.signal()
27+
racy = 2
28+
finish.signal()
29+
}
30+
q.async {
31+
sync1.signal()
32+
sync2.wait()
33+
racy = 3
34+
finish.signal()
35+
}
36+
37+
finish.wait()
38+
finish.wait()
39+
40+
print("Done!")
41+
42+
// CHECK: ThreadSanitizer: data race
43+
// CHECK: Done!

test/Sanitizers/tsan-norace-block-release.swift

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,31 @@
1-
// RUN: %target-swiftc_driver %s -g -sanitize=thread -target %sanitizers-target-triple -o %t_tsan-binary
1+
// RUN: %target-swiftc_driver %s -g -sanitize=thread %import-libdispatch -target %sanitizers-target-triple -o %t_tsan-binary
22
// RUN: %target-codesign %t_tsan-binary
3-
// RUN: env %env-TSAN_OPTIONS=abort_on_error=0:ignore_interceptors_accesses=1 %target-run %t_tsan-binary 2>&1 | %FileCheck %s
3+
// RUN: env %env-TSAN_OPTIONS=abort_on_error=0:ignore_interceptors_accesses=1 %target-run %t_tsan-binary 2>&1 | %FileCheck %s --implicit-check-not='ThreadSanitizer'
44
// REQUIRES: executable_test
5-
// REQUIRES: objc_interop
65
// REQUIRES: tsan_runtime
76

87
// FIXME: This should be covered by "tsan_runtime"; older versions of Apple OSs
98
// don't support TSan.
109
// UNSUPPORTED: remote_run
1110

1211
// Test that we do not report a race on block release operation.
13-
import Foundation
14-
15-
public class Sad : NSObject {
12+
import Dispatch
13+
#if canImport(Darwin)
14+
import Darwin
15+
#elseif canImport(Glibc)
16+
import Glibc
17+
#else
18+
#error("Unsupported platform")
19+
#endif
20+
21+
public class Sad {
1622
private var _source: DispatchSourceTimer?
17-
public override init() {
23+
public init() {
1824
_source = DispatchSource.makeTimerSource()
1925

2026
// If this line is commented out no data race.
2127
_source?.setEventHandler(handler: globalFuncHandler)
2228

23-
super.init()
2429
_source?.resume()
2530
}
2631
deinit {
@@ -40,4 +45,3 @@ sleep(1)
4045
print("Done.")
4146

4247
// CHECK: Done.
43-
// CHECK-NOT: ThreadSanitizer: data race

test/Sanitizers/tsan-norace-deinit-run-time.swift

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,26 @@
1-
// RUN: %target-swiftc_driver %s -g -sanitize=thread -target %sanitizers-target-triple -o %t_tsan-binary
1+
// RUN: %target-swiftc_driver %s -g -sanitize=thread %import-libdispatch -target %sanitizers-target-triple -o %t_tsan-binary
22
// RUN: %target-codesign %t_tsan-binary
3-
// RUN: env %env-TSAN_OPTIONS=abort_on_error=0:ignore_interceptors_accesses=1 %target-run %t_tsan-binary 2>&1 | %FileCheck %s
3+
// RUN: env %env-TSAN_OPTIONS=abort_on_error=0:ignore_interceptors_accesses=1 %target-run %t_tsan-binary 2>&1 | %FileCheck %s --implicit-check-not='ThreadSanitizer'
44
// REQUIRES: executable_test
5-
// REQUIRES: objc_interop
65
// REQUIRES: tsan_runtime
76

87
// FIXME: This should be covered by "tsan_runtime"; older versions of Apple OSs
98
// don't support TSan.
109
// UNSUPPORTED: remote_run
1110

1211
// Test that we do not report a race on deinit; the synchronization is guaranteed by runtime.
13-
import Foundation
14-
15-
public class TestDeallocObject : NSObject {
12+
import Dispatch
13+
#if canImport(Darwin)
14+
import Darwin
15+
#elseif canImport(Glibc)
16+
import Glibc
17+
#else
18+
#error("Unsupported platform")
19+
#endif
20+
21+
public class TestDeallocObject {
1622
public var v : Int
17-
public override init() {
23+
public init() {
1824
v = 1
1925
}
2026

@@ -33,7 +39,7 @@ public class TestDeallocObject : NSObject {
3339
}
3440
}
3541

36-
if (true) {
42+
do {
3743
var tdo : TestDeallocObject = TestDeallocObject()
3844
tdo.accessMember()
3945

@@ -52,4 +58,3 @@ if (true) {
5258
print("Done.")
5359

5460
// CHECK: Done.
55-
// CHECK-NOT: ThreadSanitizer: data race

0 commit comments

Comments
 (0)