EXC_BAD_ACCESS when adding item to ordered dictionary and index out of range error in Xcode 14 beta 5

I am exploring modern concurrency by implementing some synchronization primitives with continuations. All of my lest cases pass with swift 5.6 tool chain but when I am running tests with Xcode 14 beta 5, some of my tests crash with bad access error when adding an item to ordered dictionary:

* thread #6, queue = 'com.apple.root.user-initiated-qos.cooperative', stop reason = EXC_BAD_ACCESS (code=1, address=0xbeaddfde4670)
    frame #0: 0x00000001cabfc110 libswiftCore.dylib`_swift_release_dealloc + 32
    frame #1: 0x00000001ca88fdac libswiftCore.dylib`Swift.ContiguousArray.append(__owned τ_0_0) -> () + 228
  * frame #2: 0x00000001300b426c AsyncObjectsTests`OrderedDictionary.subscript.setter(newValue=(canary = 0x0000600000c5d6e0), key=FCD1CAC4-FBD8-4DD8-88B3-0E6768E76D0E, self=OrderedCollections.OrderedDictionary<Foundation.UUID, Swift.CheckedContinuation<(), Swift.Error>> @ 0x0000600003308250) at OrderedDictionary.swift:364:17
    frame #3: 0x00000001300ed634 AsyncObjectsTests`AsyncSemaphore.addContinuation(continuation=(canary = 0x0000600000c5d6e0), key=FCD1CAC4-FBD8-4DD8-88B3-0E6768E76D0E, self=0x00006000033081e0) at AsyncSemaphore.swift:34:28
    frame #4: 0x00000001300eea58 AsyncObjectsTests`closure #1 in closure #2 in AsyncSemaphore.withPromisedContinuation(continuation=(canary = 0x0000600000c5d6e0), self=0x00006000033081e0, key=FCD1CAC4-FBD8-4DD8-88B3-0E6768E76D0E) at AsyncSemaphore.swift:72:22
    frame #5: 0x000000023df01248 libswift_Concurrency.dylib`partial apply forwarder for closure #1 (Swift.UnsafeContinuation<τ_0_0, Swift.Error>) -> () in Swift.withCheckedThrowingContinuation<τ_0_0>(function: Swift.String, _: (Swift.CheckedContinuation<τ_0_0, Swift.Error>) -> ()) async throws -> τ_0_0 + 168
    frame #6: 0x000000023df0135c libswift_Concurrency.dylib`Swift.withUnsafeThrowingContinuation<τ_0_0>((Swift.UnsafeContinuation<τ_0_0, Swift.Error>) -> ()) async throws -> τ_0_0 + 228
    frame #7: 0x000000023df010a0 libswift_Concurrency.dylib`(1) await resume partial function for Swift.withCheckedThrowingContinuation<τ_0_0>(function: Swift.String, _: (Swift.CheckedContinuation<τ_0_0, Swift.Error>) -> ()) async throws -> τ_0_0
    frame #8: 0x00000001300f86e8 AsyncObjectsTests`static CheckedContinuation<>.with(body=0x1300efbf4, self=<unavailable>) at Continuable.swift:87
    frame #9: 0x00000001300ee7bc AsyncObjectsTests`closure #2 in AsyncSemaphore.withPromisedContinuation(self=0x00006000033081e0, key=FCD1CAC4-FBD8-4DD8-88B3-0E6768E76D0E) at AsyncSemaphore.swift:71
    frame #10: 0x00000001300ef8f4 AsyncObjectsTests`partial apply for closure #2 in AsyncSemaphore.withPromisedContinuation() at <compiler-generated>:0
    frame #11: 0x000000023df14ac8 libswift_Concurrency.dylib`(1) await resume partial function for Swift.withTaskCancellationHandler<τ_0_0>(operation: () async throws -> τ_0_0, onCancel: @Sendable () -> ()) async throws -> τ_0_0
    frame #12: 0x00000001300e5ed4 AsyncObjectsTests`withTaskCancellationHandler<T>(handler:operation:) at <compiler-generated>:0
    frame #13: 0x00000001300edd5c AsyncObjectsTests`AsyncSemaphore.withPromisedContinuation(self=0x00006000033081e0) at AsyncSemaphore.swift:66
    frame #14: 0x00000001300ef3b8 AsyncObjectsTests`AsyncSemaphore.wait@Sendable (self=0x00006000033081e0) at AsyncSemaphore.swift:113
    frame #15: 0x000000013001e41c AsyncObjectsTests`closure #1 in closure #1 in AsyncSemaphoreTests.testConcurrentMutation(semaphore=0x00006000033081e0, data=0x0000600000229a80, index=7) at AsyncSemaphoreTests.swift:172
    frame #16: 0x0000000130022448 AsyncObjectsTests`partial apply for closure #1 in closure #1 in AsyncSemaphoreTests.testConcurrentMutation() at <compiler-generated>:0
    frame #17: 0x000000013002286c AsyncObjectsTests`thunk for @escaping @callee_guaranteed @Sendable @async () -> (@out A) at <compiler-generated>:0
    frame #18: 0x00000001300229cc AsyncObjectsTests`partial apply for thunk for @escaping @callee_guaranteed @Sendable @async () -> (@out A) at <compiler-generated>:0

And when removing first item even after collection empty check I am getting index out of range error:
Screenshot 2022-08-12 at 10.22.48 AM

* thread #4, queue = 'com.apple.root.user-initiated-qos.cooperative', stop reason = Fatal error: Index out of range
    frame #0: 0x00000001cabf932c libswiftCore.dylib`_swift_runtime_on_report
    frame #1: 0x00000001cac8e8d8 libswiftCore.dylib`_swift_stdlib_reportFatalErrorInFile + 208
    frame #2: 0x00000001ca8b21b0 libswiftCore.dylib`closure #1 (Swift.UnsafeBufferPointer<Swift.UInt8>) -> () in closure #1 (Swift.UnsafeBufferPointer<Swift.UInt8>) -> () in closure #1 (Swift.UnsafeBufferPointer<Swift.UInt8>) -> () in Swift._assertionFailure(_: Swift.StaticString, _: Swift.StaticString, file: Swift.StaticString, line: Swift.UInt, flags: Swift.UInt32) -> Swift.Never + 380
    frame #3: 0x00000001ca8b1ef4 libswiftCore.dylib`closure #1 (Swift.UnsafeBufferPointer<Swift.UInt8>) -> () in closure #1 (Swift.UnsafeBufferPointer<Swift.UInt8>) -> () in Swift._assertionFailure(_: Swift.StaticString, _: Swift.StaticString, file: Swift.StaticString, line: Swift.UInt, flags: Swift.UInt32) -> Swift.Never + 200
    frame #4: 0x00000001ca8b1cec libswiftCore.dylib`closure #1 (Swift.UnsafeBufferPointer<Swift.UInt8>) -> () in Swift._assertionFailure(_: Swift.StaticString, _: Swift.StaticString, file: Swift.StaticString, line: Swift.UInt, flags: Swift.UInt32) -> Swift.Never + 212
    frame #5: 0x00000001ca8b184c libswiftCore.dylib`Swift._assertionFailure(_: Swift.StaticString, _: Swift.StaticString, file: Swift.StaticString, line: Swift.UInt, flags: Swift.UInt32) -> Swift.Never + 236
    frame #6: 0x00000001ca9009f4 libswiftCore.dylib`Swift.ContiguousArray.remove(at: Swift.Int) -> τ_0_0 + 348
    frame #7: 0x00000001280df360 AsyncObjectsTests`OrderedSet._removeExistingMember(index=0, bucket=(offset = 0), self=OrderedCollections.OrderedSet<Foundation.UUID> @ 0x0000600003000580) at OrderedSet.swift:475:27
    frame #8: 0x00000001280c5ac8 AsyncObjectsTests`OrderedSet.remove(index=0, self=OrderedCollections.OrderedSet<Foundation.UUID> @ 0x0000600003000580) at OrderedSet+Partial RangeReplaceableCollection.swift:53:12
    frame #9: 0x00000001280ae1a0 AsyncObjectsTests`OrderedDictionary.remove(index=0, self=OrderedCollections.OrderedDictionary<Foundation.UUID, AsyncObjects.TaskQueue.QueuedContinuation> @ 0x0000600003000580) at OrderedDictionary+Partial RangeReplaceableCollection.swift:66:21
    frame #10: 0x00000001280aecf0 AsyncObjectsTests`OrderedDictionary.removeFirst(self=OrderedCollections.OrderedDictionary<Foundation.UUID, AsyncObjects.TaskQueue.QueuedContinuation> @ 0x0000600003000580) at OrderedDictionary+Partial RangeReplaceableCollection.swift:140:12
  * frame #11: 0x00000001281154c0 AsyncObjectsTests`TaskQueue.releaseBarrier(self=0x0000600003000510) at TaskQueue.swift:118:43
    frame #12: 0x000000012811875c AsyncObjectsTests`TaskQueue.runAsBarrier<T>(priority=none, operation=0x128197260, self=0x0000600003000510) at TaskQueue.swift:215
    frame #13: 0x0000000128119b3c AsyncObjectsTests`runTask #1 <T>(barrier=true, self=0x0000600003000510, priority=nil, operation=0x128197260) in TaskQueue.exec<T>(barrier:priority:operation:) at TaskQueue.swift:268
    frame #14: 0x000000012811943c AsyncObjectsTests`TaskQueue.exec<T>(barrier=true, priority=nil, operation=0x128197260, self=0x0000600003000510) at TaskQueue.swift:280
    frame #15: 0x0000000128064180 AsyncObjectsTests`closure #3 in closure #1 in closure #1 in TaskQueueTests.testCancellationOfMultipleBarrierTasksAndOneConcurrentTaskWithoutBlockingQueue(queue=0x0000600003000510) at TaskQueueTests.swift:294
    frame #16: 0x00000001280643a8 AsyncObjectsTests`partial apply for closure #3 in closure #1 in closure #1 in TaskQueueTests.testCancellationOfMultipleBarrierTasksAndOneConcurrentTaskWithoutBlockingQueue() at <compiler-generated>:0

All the data mutation is happening inside actor, any reason why these crashes are happening?

This was happening due to some actor isolation-related changes in Swift 5.7, after resolving all isolation-related warnings this issue is fixed now.

1 Like