Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash when compiling code using 6.0, can related to retroactive #76530

Open
m1entus opened this issue Sep 17, 2024 · 1 comment
Open

Crash when compiling code using 6.0, can related to retroactive #76530

m1entus opened this issue Sep 17, 2024 · 1 comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. crash Bug: A crash, i.e., an abnormal termination of software triage needed This issue needs more specific labels

Comments

@m1entus
Copy link

m1entus commented Sep 17, 2024

Description

I am getting crash on Swift 6.0 where all works fine on 5.9, can be related to retroactive implementation. Seems for UNUserNotificationService code stopped on dispatch_assert_queue which can be Foundation issue with Swift 6.0 but other stack dump might be related to retroactive (see additional information).

Reproduction

Inside @main AppDelegate i have applicationDidBecomeActive which call this method which causes a crash on swift 6.0 but not cause when i have swift 5.9:

private func registerForRemoteNotificationsIfAuthorized() {
        UNUserNotificationCenter.current().getNotificationSettings { settings in
            if settings.authorizationStatus == .authorized {
                DispatchQueue.main.async {
                    UIApplication.shared.registerForRemoteNotifications()
                }
            }
        }
    }

Worth mention that i include SPM packages Models which contains this code:

extension UNUserNotificationCenter: @unchecked @retroactive Sendable, UserNotificationCenterServing {
    public func notificationAuthorizationStatus() async -> UNAuthorizationStatus {
        await notificationSettings().authorizationStatus
    }
}

When i changed method registerForRemoteNotificationsIfAuthorized to this implementation it works fine:

Task {
            let status = await notificationCenter.notificationAuthorizationStatus()
            if status == .authorized {
                UIApplication.shared.registerForRemoteNotifications()
            }
        }

Personally feel this can something related to @retroactive, because i tried to migrate other module and seeing crash on classes where @retroactive implemented too.

Stack dump

* thread #9, queue = 'com.apple.usernotifications.UNUserNotificationServiceConnection.call-out', stop reason = EXC_BREAKPOINT (code=1, subcode=0x1111183f8)
  * frame #0: 0x00000001111183f8 libdispatch.dylib`_dispatch_assert_queue_fail + 116
    frame #1: 0x0000000111118384 libdispatch.dylib`dispatch_assert_queue + 188
    frame #2: 0x00000001112103e0 libswift_Concurrency.dylib`swift_task_isCurrentExecutorImpl(swift::SerialExecutorRef) + 284
    frame #3: 0x00000001217ed4a0 geneva-dev.debug.dylib`closure #1 in AppDelegate.registerForRemoteNotificationsIfAuthorized(settings=0x000060000313e1c0) at <stdin>:0
    frame #4: 0x00000001217ed810 geneva-dev.debug.dylib`thunk for @escaping @callee_guaranteed (@guaranteed UNNotificationSettings) -> () at <compiler-generated>:0
    frame #5: 0x0000000111114ec0 libdispatch.dylib`_dispatch_call_block_and_release + 24
    frame #6: 0x00000001111167b8 libdispatch.dylib`_dispatch_client_callout + 16
    frame #7: 0x000000011111eaac libdispatch.dylib`_dispatch_lane_serial_drain + 912
    frame #8: 0x000000011111f7b0 libdispatch.dylib`_dispatch_lane_invoke + 420
    frame #9: 0x000000011112c1f0 libdispatch.dylib`_dispatch_root_queue_drain_deferred_wlh + 324
    frame #10: 0x000000011112b75c libdispatch.dylib`_dispatch_workloop_worker_thread + 732
    frame #11: 0x0000000112897814 libsystem_pthread.dylib`_pthread_wqthread + 284

Expected behavior

Should not crash

Environment

Swift 6.0 (6.0.0.9.10) - Xcode 16 Release

Additional information

Other place stack dump that i am getting some crash and custom actors are implemented is:

Inside initializer i have:

extension Notification: @unchecked @retroactive Sendable {}

extension Socket {
    @Socket.ClientActor
    public final class Client: SocketProviding { // swiftlint:disable:this type_body_length
        
        nonisolated public convenience init(notificationCenter: NotificationCenter) {
            self.init(center: notificationCenter)
            
            Task { @Socket.ClientActor in
                await setupObservers()
            }
        }
        
        private func setupObservers() async {
            notificationCenter
                .publisher(for: UIApplication.didBecomeActiveNotification)
                .sink { [weak self] notification in
                    Task { @Socket.ClientActor [weak self] in
                        self?.handleDidBecomeActive(notification: notification)
                    }
                }.store(in: &bag)
        }
    }
}
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
    frame #0: 0x0000000110654f30 libsystem_kernel.dylib`__pthread_kill + 8
    frame #1: 0x00000001106e7124 libsystem_pthread.dylib`pthread_kill + 256
    frame #2: 0x000000010f5874ec libsystem_c.dylib`abort + 104
    frame #3: 0x000000010f05f44c libswift_Concurrency.dylib`swift::swift_Concurrency_fatalErrorv(unsigned int, char const*, char*) + 28
    frame #4: 0x000000010f05f468 libswift_Concurrency.dylib`swift::swift_Concurrency_fatalError(unsigned int, char const*, ...) + 28
    frame #5: 0x000000010f05f0e0 libswift_Concurrency.dylib`swift_task_checkIsolated + 152
    frame #6: 0x000000010f05c3e0 libswift_Concurrency.dylib`swift_task_isCurrentExecutorImpl(swift::SerialExecutorRef) + 284
    frame #7: 0x0000000120f34a40 geneva-dev.debug.dylib`closure #8 in Socket.Client.setupObservers(notification=Foundation.Notification @ 0x000000016ddbed10) at Socket+Client.swift:0
    frame #8: 0x0000000106be00ac Combine`Combine.Subscribers.Sink.receive(τ_0_0) -> Combine.Subscribers.Demand + 84
    frame #9: 0x0000000106be0760 Combine`protocol witness for Combine.Subscriber.receive(τ_0_0.Input) -> Combine.Subscribers.Demand in conformance Combine.Subscribers.Sink<τ_0_0, τ_0_1> : Combine.Subscriber in Combine + 20
    frame #10: 0x000000010b249f28 Foundation`closure #1 @Sendable (Foundation.Notification) -> () in Foundation.Notification.Subscription.init(__C.NSNotificationCenter, __C.NSNotificationName, Swift.Optional<Swift.AnyObject>, τ_0_0) -> Foundation.Notification.Subscription<τ_0_0> + 268
    frame #11: 0x000000010b249aa8 Foundation`reabstraction thunk helper from @escaping @callee_guaranteed @Sendable (@in_guaranteed Foundation.Notification) -> () to @escaping @callee_unowned @convention(block) @Sendable (@unowned __C.NSNotification) -> () + 48
    frame #12: 0x0000000106e7eaec CoreFoundation`__CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 120
    frame #13: 0x0000000106e7ea24 CoreFoundation`___CFXRegistrationPost_block_invoke + 84
    frame #14: 0x0000000106e7df14 CoreFoundation`_CFXRegistrationPost + 404
    frame #15: 0x0000000106e7d8f0 CoreFoundation`_CFXNotificationPost + 688
    frame #16: 0x000000010b5f4350 Foundation`-[NSNotificationCenter postNotificationName:object:userInfo:] + 88
    frame #17: 0x000000014c00d320 UIKitCore`-[UIApplication _stopDeactivatingForReason:] + 1364
    frame #18: 0x000000014b62d4f0 UIKitCore`-[_UISceneLifecycleMultiplexer _performBlock:withApplicationOfDeactivationReasons:fromReasons:] + 268
    frame #19: 0x000000014b62d794 UIKitCore`-[_UISceneLifecycleMultiplexer _evalTransitionToSettings:fromSettings:forceExit:withTransitionStore:] + 576
    frame #20: 0x000000014b62d1a0 UIKitCore`-[_UISceneLifecycleMultiplexer uiScene:transitionedFromState:withTransitionContext:] + 244
    frame #21: 0x000000014b638058 UIKitCore`__186-[_UIWindowSceneFBSSceneTransitionContextDrivenLifecycleSettingsDiffAction _performActionsForUIScene:withUpdatedFBSScene:settingsDiff:fromSettings:transitionContext:lifecycleActionType:]_block_invoke + 140
    frame #22: 0x000000014bab8770 UIKitCore`+[BSAnimationSettings(UIKit) tryAnimatingWithSettings:fromCurrentState:actions:completion:] + 656
    frame #23: 0x000000014bbdeaa4 UIKitCore`_UISceneSettingsDiffActionPerformChangesWithTransitionContextAndCompletion + 196
    frame #24: 0x000000014b637d64 UIKitCore`-[_UIWindowSceneFBSSceneTransitionContextDrivenLifecycleSettingsDiffAction _performActionsForUIScene:withUpdatedFBSScene:settingsDiff:fromSettings:transitionContext:lifecycleActionType:] + 288
    frame #25: 0x000000014b47c084 UIKitCore`__64-[UIScene scene:didUpdateWithDiff:transitionContext:completion:]_block_invoke.199 + 608
    frame #26: 0x000000014b47ae2c UIKitCore`-[UIScene _emitSceneSettingsUpdateResponseForCompletion:afterSceneUpdateWork:] + 200
    frame #27: 0x000000014b47bd08 UIKitCore`-[UIScene scene:didUpdateWithDiff:transitionContext:completion:] + 220
    frame #28: 0x000000014bae2f40 UIKitCore`-[UIApplicationSceneClientAgent scene:handleEvent:withCompletion:] + 308
    frame #29: 0x0000000115c36380 FrontBoardServices`__76-[FBSScene updater:didUpdateSettings:withDiff:transitionContext:completion:]_block_invoke.159 + 216
    frame #30: 0x0000000115c350a4 FrontBoardServices`-[FBSScene _callOutQueue_coalesceClientSettingsUpdates:] + 60
    frame #31: 0x0000000115c3611c FrontBoardServices`-[FBSScene updater:didUpdateSettings:withDiff:transitionContext:completion:] + 744
    frame #32: 0x0000000115c62fe0 FrontBoardServices`__94-[FBSWorkspaceScenesClient _queue_updateScene:withSettings:diff:transitionContext:completion:]_block_invoke_2 + 120
    frame #33: 0x0000000115c41618 FrontBoardServices`-[FBSWorkspace _calloutQueue_executeCalloutFromSource:withBlock:] + 160
    frame #34: 0x0000000115c62f30 FrontBoardServices`__94-[FBSWorkspaceScenesClient _queue_updateScene:withSettings:diff:transitionContext:completion:]_block_invoke + 308
    frame #35: 0x000000010ef627b8 libdispatch.dylib`_dispatch_client_callout + 16
    frame #36: 0x000000010ef663bc libdispatch.dylib`_dispatch_block_invoke_direct + 388
    frame #37: 0x0000000115c84b58 FrontBoardServices`__FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 44
    frame #38: 0x0000000115c84a34 FrontBoardServices`-[FBSMainRunLoopSerialQueue _targetQueue_performNextIfPossible] + 196
    frame #39: 0x0000000115c84b8c FrontBoardServices`-[FBSMainRunLoopSerialQueue _performNextFromRunLoopSource] + 24
    frame #40: 0x0000000106eb0324 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
    frame #41: 0x0000000106eb026c CoreFoundation`__CFRunLoopDoSource0 + 172
    frame #42: 0x0000000106eafa2c CoreFoundation`__CFRunLoopDoSources0 + 324
    frame #43: 0x0000000106eaa0b0 CoreFoundation`__CFRunLoopRun + 788
    frame #44: 0x0000000106ea9960 CoreFoundation`CFRunLoopRunSpecific + 536
    frame #45: 0x000000011efffb10 GraphicsServices`GSEventRunModal + 160
    frame #46: 0x000000014c011b40 UIKitCore`-[UIApplication _run] + 796
    frame #47: 0x000000014c015d38 UIKitCore`UIApplicationMain + 124
    frame #48: 0x000000014b409184 UIKitCore`UIKit.UIApplicationMain(Swift.Int32, Swift.Optional<Swift.UnsafeMutablePointer<Swift.UnsafeMutablePointer<Swift.Int8>>>, Swift.Optional<Swift.String>, Swift.Optional<Swift.String>) -> Swift.Int32 + 100
    frame #49: 0x000000011f64c450 geneva-dev.debug.dylib`static UIApplicationDelegate.main() at <compiler-generated>:0
    frame #50: 0x000000011f64c3c0 geneva-dev.debug.dylib`static AppDelegate.$main() at <compiler-generated>:0
  * frame #51: 0x000000011f64e63c geneva-dev.debug.dylib`main at AppDelegate.swift:37:16
    frame #52: 0x0000000102095410 dyld_sim`start_sim + 20
    frame #53: 0x000000010219e154 dyld`start + 2476
@m1entus m1entus added bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. crash Bug: A crash, i.e., an abnormal termination of software triage needed This issue needs more specific labels labels Sep 17, 2024
@DannyBloky
Copy link

DannyBloky commented Sep 19, 2024

Hi,
I got the same problem. But I found out that it has to do with iOS 18 and not swift 6.
When using a simulator below iOS 18 it all works fine it seems.

So I think we need to wait for a bug fix on iOS 18 that compiles with swift 6.

So if you want to go further with your migration from swift 5 to 6. I suggest you use a lower iOS version to test.

Also maybe good to know how to fix the data race

@MainActor private func registerForPushNotifications() { UNUserNotificationCenter.current().delegate = self let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound] UNUserNotificationCenter.current().requestAuthorization( options: authOptions, completionHandler: { @Sendable _, _ in }) Messaging.messaging().delegate = self UIApplication.shared.registerForRemoteNotifications() }

So you need to add the @Sendable to the completionHandler

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. crash Bug: A crash, i.e., an abnormal termination of software triage needed This issue needs more specific labels
Projects
None yet
Development

No branches or pull requests

2 participants