EXC_BAD_ACCESS after updating to Xcode 13.3
IuliiaMishina opened this issue · 2 comments
After updating to Xcode 13.3 I am not able to mock closures inside protocol anymore using given
method. Whenever I am trying to call a mocked closure I receive EXC_BAD_ACCESS:
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=2, address=0x7ff7ba78ede0)
frame #0: 0x00007ff7ba78ede0
frame #1: 0x000000010d07571c SwiftyMockyTest-Unit-Tests`thunk for @escaping @callee_guaranteed () -> (@out ()) at <compiler-generated>:0
* frame #2: 0x000000010d06c35c SwiftyMockyTest-Unit-Tests`SwiftyMockyClosureTest.testExample(self=0x00007f9df8105900) at SwiftyMockyClosureTest.swift:22:14
frame #3: 0x000000010d06c3b0 SwiftyMockyTest-Unit-Tests`@objc SwiftyMockyClosureTest.testExample() at <compiler-generated>:0
frame #4: 0x00007fff2040d71c CoreFoundation`__invoking___ + 140
frame #5: 0x00007fff2040aa8f CoreFoundation`-[NSInvocation invoke] + 305
frame #6: 0x000000010625f588 XCTestCore`+[XCTFailableInvocation invokeErrorConventionInvocation:completion:] + 118
frame #7: 0x000000010625f510 XCTestCore`__90+[XCTFailableInvocation invokeInvocation:withTestMethodConvention:lastObservedErrorIssue:]_block_invoke + 23
frame #8: 0x000000010625f1ef XCTestCore`__81+[XCTFailableInvocation invokeWithAsynchronousWait:lastObservedErrorIssue:block:]_block_invoke.13 + 71
frame #9: 0x000000010621bd83 XCTestCore`+[XCTSwiftErrorObservation observeErrorsInBlock:] + 68
frame #10: 0x000000010625f084 XCTestCore`+[XCTFailableInvocation invokeWithAsynchronousWait:lastObservedErrorIssue:block:] + 443
frame #11: 0x000000010625f4c3 XCTestCore`+[XCTFailableInvocation invokeInvocation:withTestMethodConvention:lastObservedErrorIssue:] + 205
frame #12: 0x000000010625f7ca XCTestCore`+[XCTFailableInvocation invokeInvocation:lastObservedErrorIssue:] + 64
frame #13: 0x000000010624c2c1 XCTestCore`__24-[XCTestCase invokeTest]_block_invoke.287 + 112
frame #14: 0x0000000106213f33 XCTestCore`-[XCTestCase(XCTIssueHandling) _caughtUnhandledDeveloperExceptionPermittingControlFlowInterruptions:caughtInterruptionException:whileExecutingBlock:] + 181
frame #15: 0x000000010624be4e XCTestCore`-[XCTestCase invokeTest] + 899
frame #16: 0x000000010624d6b8 XCTestCore`__26-[XCTestCase performTest:]_block_invoke.396 + 43
frame #17: 0x0000000106213f33 XCTestCore`-[XCTestCase(XCTIssueHandling) _caughtUnhandledDeveloperExceptionPermittingControlFlowInterruptions:caughtInterruptionException:whileExecutingBlock:] + 181
frame #18: 0x000000010624d041 XCTestCore`__26-[XCTestCase performTest:]_block_invoke.375 + 516
frame #19: 0x00000001062319b6 XCTestCore`+[XCTContext runInContextForTestCase:markAsReportingBase:block:] + 218
frame #20: 0x000000010624cc65 XCTestCore`-[XCTestCase performTest:] + 287
frame #21: 0x0000000106201853 XCTestCore`-[XCTest runTest] + 57
frame #22: 0x0000000106234d12 XCTestCore`-[XCTestSuite runTestBasedOnRepetitionPolicy:testRun:] + 151
frame #23: 0x0000000106234b92 XCTestCore`__27-[XCTestSuite performTest:]_block_invoke + 243
frame #24: 0x00000001062344a6 XCTestCore`__59-[XCTestSuite _performProtectedSectionForTest:testSection:]_block_invoke + 24
frame #25: 0x00000001062319b6 XCTestCore`+[XCTContext runInContextForTestCase:markAsReportingBase:block:] + 218
frame #26: 0x000000010623445d XCTestCore`-[XCTestSuite _performProtectedSectionForTest:testSection:] + 159
frame #27: 0x000000010623474f XCTestCore`-[XCTestSuite performTest:] + 219
frame #28: 0x0000000106201853 XCTestCore`-[XCTest runTest] + 57
frame #29: 0x0000000106234d12 XCTestCore`-[XCTestSuite runTestBasedOnRepetitionPolicy:testRun:] + 151
frame #30: 0x0000000106234b92 XCTestCore`__27-[XCTestSuite performTest:]_block_invoke + 243
frame #31: 0x00000001062344a6 XCTestCore`__59-[XCTestSuite _performProtectedSectionForTest:testSection:]_block_invoke + 24
frame #32: 0x00000001062319b6 XCTestCore`+[XCTContext runInContextForTestCase:markAsReportingBase:block:] + 218
frame #33: 0x000000010623445d XCTestCore`-[XCTestSuite _performProtectedSectionForTest:testSection:] + 159
frame #34: 0x000000010623474f XCTestCore`-[XCTestSuite performTest:] + 219
frame #35: 0x0000000106201853 XCTestCore`-[XCTest runTest] + 57
frame #36: 0x0000000106234d12 XCTestCore`-[XCTestSuite runTestBasedOnRepetitionPolicy:testRun:] + 151
frame #37: 0x0000000106234b92 XCTestCore`__27-[XCTestSuite performTest:]_block_invoke + 243
frame #38: 0x00000001062344a6 XCTestCore`__59-[XCTestSuite _performProtectedSectionForTest:testSection:]_block_invoke + 24
frame #39: 0x00000001062319b6 XCTestCore`+[XCTContext runInContextForTestCase:markAsReportingBase:block:] + 218
frame #40: 0x000000010623445d XCTestCore`-[XCTestSuite _performProtectedSectionForTest:testSection:] + 159
frame #41: 0x000000010623474f XCTestCore`-[XCTestSuite performTest:] + 219
frame #42: 0x0000000106201853 XCTestCore`-[XCTest runTest] + 57
frame #43: 0x0000000106203371 XCTestCore`__89-[XCTTestRunSession executeTestsWithIdentifiers:skippingTestsWithIdentifiers:completion:]_block_invoke + 115
frame #44: 0x00000001062319b6 XCTestCore`+[XCTContext runInContextForTestCase:markAsReportingBase:block:] + 218
frame #45: 0x0000000106203259 XCTestCore`-[XCTTestRunSession executeTestsWithIdentifiers:skippingTestsWithIdentifiers:completion:] + 271
frame #46: 0x000000010626d0da XCTestCore`__72-[XCTExecutionWorker enqueueTestIdentifiersToRun:testIdentifiersToSkip:]_block_invoke_2 + 119
frame #47: 0x000000010626d200 XCTestCore`-[XCTExecutionWorker runWithError:] + 112
frame #48: 0x000000010622edf9 XCTestCore`__25-[XCTestDriver _runTests]_block_invoke.322 + 61
frame #49: 0x000000010620c4a1 XCTestCore`-[XCTestObservationCenter _observeTestExecutionForBlock:] + 307
frame #50: 0x000000010622ea2c XCTestCore`-[XCTestDriver _runTests] + 1457
frame #51: 0x0000000106201e39 XCTestCore`_XCTestMain + 125
frame #52: 0x00000001057734c4 xctest`main + 211
frame #53: 0x000000010598af21 dyld_sim`start_sim + 10
frame #54: 0x000000010cf9a51e dyld`start + 462
Here's the sample code that producing this exception:
protocol TestProtocol {
var item: String { get }
var closure: () -> Void { get }
}
class SwiftyMockyClosureTest: XCTestCase {
var mock: TestProtocolMock!
override func setUp() {
mock = TestProtocolMock()
mock.given(.closure(getter: { }))
}
override func tearDown() {
mock.resetMock(.given)
}
func testExample() throws {
mock.closure()
}
}
The TestProtocol
and SwiftyMockyClosureTest
are in different targets.
If I change the closure to be mutable and mock the property like this:
mock = {}
It works, but breaks immutability of this property. In my case it's not applicable.
Do you have any idea how to avoid this happening, or it's rather a bug in SwiftyMocky itself?
Thanks, Iuliia
I have also experienced the same issue with SwiftMocky 4.0.1 and Xcode 13.3.1.
In our project we have abstraction as below:
public protocol Proxy: AnyObject {
var shouldShowBadge: (() -> Bool)? { get set }
}
When accessing closure from Mock dependency in production code there is a crash.
I have managed to find out that changing code inside mock from this:
public var shouldShowBadge: (() -> Bool)? {
get { invocations.append(.p_shouldShowBadge_get); return __p_shouldShowBadge ?? optionalGivenGetterValue(.p_shouldShowBadge_get, "ProxyMock - stub value for shouldShowBadge was not defined") }
set { invocations.append(.p_shouldShowBadge_set(.value(newValue))); __p_shouldShowBadge = newValue }
}
private var __p_shouldShowBadge: (() -> Bool)?
to this:
public var shouldShowBadge: (() -> Bool)? {
get {
invocations.append(.p_shouldShowBadge_get)
if let __p_shouldShowBadge = __p_shouldShowBadge {
return __p_shouldShowBadge
} else {
return optionalGivenGetterValue(.p_shouldShowBadge_get, "ProxyMock - stub value for shouldShowBadge was not defined") }
}
set { invocations.append(.p_shouldShowBadge_set(.value(newValue))); __p_shouldShowBadge = newValue }
}
private var __p_shouldShowBadge: (() -> Bool)?
solved crash related to memory management. Maybe there is a new compiler optimisation which does not work well with ??
operator in such case.
Looks fixed on Xcode 14.0