Skip to content

Commit 898ce27

Browse files
committed
[TSan] Add positive test for TSan + Dispatch on Linux
1) Enable tests that use `import Dispatch` on Linux 2) Make sure as many existing Dispatch and/or TSan tests as possible work/run on Linux. Tests that would require substantial work are marked with `XFAIL: OS=linux-gnu`. 3) Add test that shows that TSan finds a simple race when using `Dispatch.async` incorrectly. The real test suite for TSan's libdispatch support lives in the LLVM/compiler-rt side. rdar://problem/49177535
1 parent 14a20ee commit 898ce27

14 files changed

+89
-53
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+
// XFAIL: 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 {{(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/Sanitizers/tsan-emptyarraystorage.swift

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,22 @@
99
// don't support TSan.
1010
// UNSUPPORTED: remote_run
1111

12-
import Foundation
12+
import Dispatch
1313

1414
let sem = DispatchSemaphore(value: 0)
15+
let q1 = DispatchQueue(label: "q1")
16+
let q2 = DispatchQueue(label: "q2")
1517

16-
class T1: Thread {
17-
override func main() {
18-
var oneEmptyArray: [[String:String]] = []
19-
oneEmptyArray.append(contentsOf: [])
20-
sem.signal()
21-
}
18+
q1.async {
19+
var oneEmptyArray: [[String:String]] = []
20+
oneEmptyArray.append(contentsOf: [])
21+
sem.signal()
2222
}
23-
let t1 = T1()
24-
t1.start()
25-
26-
class T2: Thread {
27-
override func main() {
28-
var aCompletelyUnrelatedOtherEmptyArray: [[Double:Double]] = []
29-
aCompletelyUnrelatedOtherEmptyArray.append(contentsOf: [])
30-
sem.signal()
31-
}
23+
q2.async {
24+
var aCompletelyUnrelatedOtherEmptyArray: [[Double:Double]] = []
25+
aCompletelyUnrelatedOtherEmptyArray.append(contentsOf: [])
26+
sem.signal()
3227
}
33-
let t2 = T2()
34-
t2.start()
3528

3629
sem.wait()
3730
sem.wait()
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// RUN: %target-swiftc_driver %s -target %sanitizers-target-triple -g -sanitize=thread -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 sem = DispatchSemaphore(value: 0)
17+
let q = DispatchQueue.global(qos: .background)
18+
19+
var racy = 1
20+
21+
for _ in 1...1000 {
22+
q.async {
23+
racy = 2
24+
sem.signal()
25+
}
26+
q.async {
27+
racy = 3
28+
sem.signal()
29+
}
30+
}
31+
32+
for _ in 1...2000 {
33+
sem.wait()
34+
}
35+
36+
// CHECK: ThreadSanitizer: data race

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

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,31 @@
11
// RUN: %target-swiftc_driver %s -g -sanitize=thread -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: %target-run %t_tsan-binary 2>&1 | %FileCheck %s
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: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,26 @@
11
// RUN: %target-swiftc_driver %s -g -sanitize=thread -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: %target-run %t_tsan-binary 2>&1 | %FileCheck %s
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

test/lit.cfg

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1531,12 +1531,10 @@ if run_vendor == 'apple':
15311531
config.available_features.add('foundation')
15321532
config.available_features.add('objc_interop')
15331533
else:
1534-
# TODO(yln): Works with the packaged swift distribution, but not during build.
1535-
# We need to make libdispatch/foundation available in the test resource directory
1536-
# or pass along the proper library include paths in the compiler invocations that are used
1537-
# to build the tests.
15381534
def has_lib(name):
1539-
return False
1535+
file = config.target_shared_library_prefix + name + config.target_shared_library_suffix
1536+
path = make_path(test_resource_dir, config.target_sdk_name, file)
1537+
return os.path.exists(path)
15401538

15411539
if has_lib('dispatch'):
15421540
config.available_features.add('libdispatch')

test/stdlib/Dispatch.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// RUN: %target-run-simple-swift
22
// REQUIRES: executable_test
33
// REQUIRES: libdispatch
4+
// XFAIL: OS=linux-gnu
45

56
import Dispatch
67
import StdlibUnittest

test/stdlib/DispatchData.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,12 @@ DispatchAPI.test("dispatch_data_t deallocator") {
2222
let q = DispatchQueue(label: "dealloc queue")
2323
var t = 0
2424

25-
autoreleasepool {
25+
do {
2626
let size = 1024
2727
let p = UnsafeMutablePointer<UInt8>.allocate(capacity: size)
2828
let _ = DispatchData(bytesNoCopy: UnsafeBufferPointer(start: p, count: size), deallocator: .custom(q, {
2929
t = 1
30+
p.deallocate();
3031
}))
3132
}
3233

test/stdlib/DispatchDeprecationMacOS.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
// RUN: %swift -typecheck -target x86_64-apple-macosx10.9 -verify -sdk %sdk %s
22
// REQUIRES: OS=macosx
3-
// REQUIRES: objc_interop
3+
// REQUIRES: libdispatch
44

5-
import Foundation
65
import Dispatch
76

87
// Don't warn because these APIs were deprecated in macOS 10.10 and the

test/stdlib/DispatchDeprecationWatchOS.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
// RUN: %swift -typecheck -target i386-apple-watchos2.0 -verify -sdk %sdk %s
22
// REQUIRES: CPU=i386, OS=watchos
3-
// REQUIRES: objc_interop
3+
// REQUIRES: libdispatch
44

5-
import Foundation
65
import Dispatch
76

87
// These are deprecated on all versions of watchOS.

test/stdlib/DispatchTypes.swift

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

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

56
import Dispatch
67

0 commit comments

Comments
 (0)