forked from swiftlang/swift
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[tsan] Do not report races coming from deinitializers and _Block_release
TSan does not observe the guaranteed syncronization between the ref count drop to zero and object destruction. This can lead to false positive reports. This patch adds an attribute to deinitializers to ignore memory accesses at run time. It also moves the logic to add sanitizer attributes from IRGenFunction to IRGenSILFunction, which means that the automatically generated code such as _Block_release handler will not be instrumented and the accesses made in them will be invisible to TSan. Solves a problem similar to what's addressed in clang commit: https://reviews.llvm.org/D25857
- Loading branch information
Showing
5 changed files
with
109 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// RUN: %target-swiftc_driver %s -g -sanitize=thread -o %t_tsan-binary | ||
// RUN: env TSAN_OPTIONS=abort_on_error=0:ignore_interceptors_accesses=1 %target-run %t_tsan-binary 2>&1 | %FileCheck %s | ||
// REQUIRES: executable_test | ||
// REQUIRES: objc_interop | ||
// REQUIRES: CPU=x86_64 | ||
// REQUIRES: tsan_runtime | ||
// XFAIL: linux | ||
|
||
// Test that we do not report a race on block release operation. | ||
import Foundation | ||
|
||
public class Sad : NSObject { | ||
private var _source: DispatchSourceTimer? | ||
public override init() { | ||
_source = DispatchSource.makeTimerSource() | ||
|
||
// If this line is commented out no data race. | ||
_source?.setEventHandler(handler: globalFuncHandler) | ||
|
||
super.init() | ||
_source?.resume() | ||
} | ||
deinit { | ||
_source?.cancel() | ||
} | ||
} | ||
|
||
func globalFuncHandler() { | ||
} | ||
|
||
func dotest() { | ||
_ = Sad() | ||
} | ||
|
||
dotest() | ||
sleep(1) | ||
print("Done.") | ||
|
||
// CHECK: Done. | ||
// CHECK-NOT: ThreadSanitizer: data race |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
// RUN: %target-swiftc_driver %s -g -sanitize=thread -o %t_tsan-binary | ||
// RUN: env TSAN_OPTIONS=abort_on_error=0:ignore_interceptors_accesses=1 %target-run %t_tsan-binary 2>&1 | %FileCheck %s | ||
// REQUIRES: executable_test | ||
// REQUIRES: objc_interop | ||
// REQUIRES: CPU=x86_64 | ||
// REQUIRES: tsan_runtime | ||
// XFAIL: linux | ||
|
||
// Test that we do not report a race on deinit; the synchronization is guaranteed by runtime. | ||
import Foundation | ||
|
||
public class TestDeallocObject : NSObject { | ||
public var v : Int | ||
public override init() { | ||
v = 1 | ||
} | ||
|
||
@_semantics("optimize.sil.never") | ||
func unoptimize(_ input : Int) -> Int { | ||
return input | ||
} | ||
|
||
func accessMember() { | ||
var local : Int = unoptimize(v) | ||
local += 1 | ||
} | ||
|
||
deinit { | ||
v = 0 | ||
} | ||
} | ||
|
||
if (true) { | ||
var tdo : TestDeallocObject = TestDeallocObject() | ||
tdo.accessMember() | ||
|
||
// Read the value from a different thread. | ||
let concurrentQueue = DispatchQueue(label: "queuename", attributes: .concurrent) | ||
concurrentQueue.async { | ||
tdo.accessMember() | ||
} | ||
// Read the value from this thread. | ||
tdo.accessMember() | ||
sleep(1) | ||
|
||
// Deinit the value. | ||
} | ||
|
||
print("Done.") | ||
|
||
// CHECK: Done. | ||
// CHECK-NOT: ThreadSanitizer: data race |