iOS SDK에서 Concurrency 사용시 app crash

KakaoOpenSDK - 2.24.0
App ID - 573044
문의 시, 사용하시는 SDK 버전 정보와 디벨로퍼스 앱ID를 알려주세요.


앱에서 Concurrency 사용을 위해서 UserApi.shared.loginWithKakaoTalk 를 withCheckedThrowingContinuation로 감싸서 사용중인데 crash Report로
CheckedContinuation.resume(returning:)
CheckedContinuation.resume(throwing:)
이 간혈적으로 잡히고 있습니다.
함수는 아래와 같이 감싸져있는데 이유를 알 수 있을까요 ??

@MainActor
func loginWithKakaoTalk() async throws -> OAuthToken {
    try await withCheckedThrowingContinuation { continuation in
        UserApi.shared.loginWithKakaoTalk { oAuthToken, error in
            if let error {
                continuation.resume(throwing: error)
            } else if let oAuthToken {
                continuation.resume(returning: oAuthToken)
            } else {
                continuation.resume(throwing: KakaoLoginError.emptyData)
            }
        }
    }
}

어떤 상황인지 확인 위해 크래시 로그 기재해주시겠어요?

Thread 0 Crashed:
0   libswiftCore.dylib            	0x0000000199fb4e2c _assertionFailure(_:_:file:line:flags:) + 264 (AssertCommon.swift:147)
1   libswift_Concurrency.dylib    	0x00000001a72874a0 CheckedContinuation.resume(returning:) + 412 (CheckedContinuation.swift:169)
2   DongwonMall                   	0x00000001027dd160 closure #1 in closure #1 in KakaoLoginRepository.loginWithKakaoTalk() + 392
3   DongwonMall                   	0x00000001027dd5f0 partial apply for closure #1 in closure #1 in KakaoLoginRepository.loginWithKakaoTalk() + 68
4   ThirdPartyLibraryKit          	0x0000000103bda968 closure #1 in closure #1 in AuthController._authorizeWithTalk(launchMethod:prompts:channelPublicIds:serviceTerms:nonce:completion:) + 388
5   ThirdPartyLibraryKit          	0x0000000103bdf72c partial apply for closure #1 in closure #1 in AuthController._authorizeWithTalk(launchMethod:prompts:channelPublicIds:serviceTerms:nonce:completion:) + 16 (/<compiler-generated>:0)
6   ThirdPartyLibraryKit          	0x0000000103bd1710 closure #1 in AuthApi.token(code:codeVerifier:redirectUri:completion:) + 880 (AuthApi.swift:101)
7   ThirdPartyLibraryKit          	0x0000000103bcdc7c closure #2 in Api.responseData(_:_:parameters:headers:sessionType:apiType:logging:completion:) + 1384 (Api.swift:193)
8   ThirdPartyLibraryKit          	0x0000000103ad4af4 partial apply for specialized closure #2 in closure #2 in closure #3 in closure #1 in DownloadRequest._response<A>(queue:responseSerializer:completionHandler:) + 48
9   ThirdPartyLibraryKit          	0x0000000103a46614 thunk for @escaping @callee_guaranteed () -> () + 28 (/<compiler-generated>:0)
10  libdispatch.dylib             	0x00000001a3751248 _dispatch_call_block_and_release + 32 (init.c:1549)
11  libdispatch.dylib             	0x00000001a3752fa8 _dispatch_client_callout + 20 (object.m:576)
12  libdispatch.dylib             	0x00000001a3761a34 _dispatch_main_queue_drain + 984 (queue.c:8093)
13  libdispatch.dylib             	0x00000001a376164c _dispatch_main_queue_callback_4CF + 44 (queue.c:8253)
14  CoreFoundation                	0x000000019ba0abcc __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 16 (CFRunLoop.c:1793)
15  CoreFoundation                	0x000000019ba071c0 __CFRunLoopRun + 1996 (CFRunLoop.c:3163)
16  CoreFoundation                	0x000000019ba59284 CFRunLoopRunSpecific + 588 (CFRunLoop.c:3434)
17  GraphicsServices              	0x00000001e8cc94c0 GSEventRunModal + 164 (GSEvent.c:2196)
18  UIKitCore                     	0x000000019e5a2674 -[UIApplication _run] + 816 (UIApplication.m:3846)
19  UIKitCore                     	0x000000019e1c8e88 UIApplicationMain + 340 (UIApplication.m:5503)
20  UIKitCore                     	0x000000019e90515c UIApplicationMain(_:_:_:_:) + 104 (UIKit.swift:565)
21  DongwonMall                   	0x0000000102674bec specialized static UIApplicationDelegate.main() + 28 (/<compiler-generated>:32)
22  DongwonMall                   	0x0000000102674bec static AppDelegate.$main() + 28 (AppDelegate.swift:0)
23  DongwonMall                   	0x0000000102674bec main + 116
24  dyld                          	0x00000001c1cb5de8 start + 2724 (dyldMain.cpp:1338)

위와 같습니다.

@이준복8743

안녕하세요. iOS SDK 담당자입니다.

현재 전달 주신 로그를 확인 했을 때, continuation.resume(returning: oAuthToken) 가 발생하기 전에 continuation.resume(:)이 일어난 것으로 보이는데요. 이 때, resume 된 값이 어떤 값인지 확인 가능할까요?

크래시 재현이 불가해서 어떤값인지 확인이 불가능합니다… 하지만 returning뿐 아니라 throwing에서도 오류가 발생하고 있습니다

0   libswiftCore.dylib            	0x0000000186d78e2c _assertionFailure(_:_:file:line:flags:) + 264 (AssertCommon.swift:147)
1   libswift_Concurrency.dylib    	0x000000019404b67c CheckedContinuation.resume(throwing:) + 472 (CheckedContinuation.swift:189)
2   DongwonMall                   	0x00000001002a9120 closure #1 in closure #1 in KakaoLoginRepository.loginWithKakaoTalk() + 328
3   DongwonMall                   	0x00000001002a95f0 partial apply for closure #1 in closure #1 in KakaoLoginRepository.loginWithKakaoTalk() + 68
4   ThirdPartyLibraryKit          	0x0000000100b3e6dc closure #1 in AuthController._authorizeWithTalk(launchMethod:prompts:channelPublicIds:serviceTerms:nonce:completion:) + 616 (AuthController.swift:130)
5   ThirdPartyLibraryKit          	0x0000000100b46474 closure #1 in static AuthController.handleOpenUrl(url:options:) + 8 (AuthController.swift:208)
6   ThirdPartyLibraryKit          	0x0000000100b46474 partial apply for closure #1 in static CertApi.handleOpenUrl(url:options:) + 52 (/<compiler-generated>:0)
7   ThirdPartyLibraryKit          	0x00000001009ae614 thunk for @escaping @callee_guaranteed () -> () + 28 (/<compiler-generated>:0)
8   libdispatch.dylib             	0x0000000190516fa8 _dispatch_client_callout + 20 (object.m:576)
9   libdispatch.dylib             	0x000000019051a45c _dispatch_continuation_pop + 596 (queue.c:325)
10  libdispatch.dylib             	0x000000019052e620 _dispatch_source_latch_and_call + 420 (source.c:596)
11  libdispatch.dylib             	0x000000019052d1e8 _dispatch_source_invoke + 836 (source.c:961)
12  libdispatch.dylib             	0x0000000190525948 _dispatch_main_queue_drain + 748 (queue.c:8093)
13  libdispatch.dylib             	0x000000019052564c _dispatch_main_queue_callback_4CF + 44 (queue.c:8253)
14  CoreFoundation                	0x00000001887cebcc __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 16 (CFRunLoop.c:1793)
15  CoreFoundation                	0x00000001887cb1c0 __CFRunLoopRun + 1996 (CFRunLoop.c:3163)
16  CoreFoundation                	0x000000018881d284 CFRunLoopRunSpecific + 588 (CFRunLoop.c:3434)
17  GraphicsServices              	0x00000001d5a8d4c0 GSEventRunModal + 164 (GSEvent.c:2196)
18  UIKitCore                     	0x000000018b366674 -[UIApplication _run] + 816 (UIApplication.m:3846)
19  UIKitCore                     	0x000000018af8ce88 UIApplicationMain + 340 (UIApplication.m:5503)
20  UIKitCore                     	0x000000018b6c915c UIApplicationMain(_:_:_:_:) + 104 (UIKit.swift:565)
21  DongwonMall                   	0x0000000100140bec specialized static UIApplicationDelegate.main() + 28 (/<compiler-generated>:32)
22  DongwonMall                   	0x0000000100140bec static AppDelegate.$main() + 28 (AppDelegate.swift:0)
23  DongwonMall                   	0x0000000100140bec main + 116
24  dyld                          	0x00000001aea79de8 start + 2724 (dyldMain.cpp:1338)


@이준복8743

현재 해당 에러의 재현 및 원인 파악이 어려운데요.
카카오 로그인 콜백을 받았을 때, 처리하는 handleOpenUrl() 호출부와 func loginWithKakaoTalk() async throws 호출부의 구현 단을 공유해주실 수 있을까요?

개발자 문서에 나와있는 내용을 토대로 url이 들어왔을때 kakao링크라면 handleOpenUrl()에 url만 전달해주고 있습니다.
마찬가지로 loginWithKakaoTalk()는 withCheckedThrowingContinuation로만 감싸주고 있습니다.

 func application(
        _ app: UIApplication,
        open url: URL,
        options: [UIApplication.OpenURLOptionsKey : Any] = [:]
    ) -> Bool {
        
        ...
        // Kakao
        if AuthApi.isKakaoTalkLoginUrl(url) {
            return AuthController.handleOpenUrl(url: url)
        }
       ...
        return false
    }
@MainActor
    func loginWithKakao() async throws -> OAuthToken {
        try await UserApi.isKakaoTalkLoginAvailable() ? loginWithKakaoTalk() : loginWithKakaoAccount()
    }
    
    @MainActor
    func loginWithKakaoTalk() async throws -> OAuthToken {
        try await withCheckedThrowingContinuation { continuation in
            UserApi.shared.loginWithKakaoTalk { oAuthToken, error in
                if let error {
                    continuation.resume(throwing: error)
                } else if let oAuthToken {
                    continuation.resume(returning: oAuthToken)
                } else {
                    continuation.resume(throwing: KakaoLoginError.emptyData)
                }
            }
        }
    }
    
    @MainActor
    func loginWithKakaoAccount() async throws -> OAuthToken {
        try await withCheckedThrowingContinuation { continuation in
            UserApi.shared.loginWithKakaoAccount { oAuthToken, error in
                if let error {
                    continuation.resume(throwing: error)
                } else if let oAuthToken {
                    continuation.resume(returning: oAuthToken)
                } else {
                    continuation.resume(throwing: KakaoLoginError.emptyData)
                }
            }
        }
    }

@이준복8743

내부에서 테스트 시 이미 사용된 authorizeWithTalkCompletionHandler 가 2번 이상 불리는 경우 말씀주신 사항이 발생하는 것 확인하였습니다.

해당 부분 수정하여 배포하도록 하겠습니다.

제보 감사합니다.

cc. @tim.l @woody.ho

2개의 좋아요

도움이 되어 다행입니다 !
빠른 확인 감사합니다

안녕하세요.

해당 부분이 수정된 iOS SDK 2.24.1이 배포되었습니다.

확인 하시고 문제가 있다면 말씀 부탁드립니다.

감사합니다.

cc. @woody.ho @tim.l

1개의 좋아요

안녕하세요. 2.24.1을 적용한 버전에서 약간 다른 Crash가 발생하여 공유드립니다.
변경사항은 sdk 버전만 2.24.0에서 2.24.1로 변경되었고
이번 Crash 역시 특정 OS나 기기, 유저 문제는 아닌것으로 보이는게
같은 조건이여도 성공하는 경우가 보통이고 아주 간혈적으로 아래와 같은 Crash가 발생하고 있습니다.


혹시 로그가 필요하시다면 말씀해주세요 !

안녕하세요.
이번에는 authorizeWithTalkCompletionHandler 가 아닌 token(:) 발급 시도 시 발생하는 것으로 보이는데요.
현재 크래시 역시 resume(:)이 2번 호출된 것이 맞을까요?
이전과 동일하게 throwing 관련 크래시도 발생할까요?

해당 에러에 대한 로그 공유 부탁드립니다.

런루프 문제처럼 보이긴 하는데
우선 resume 로그는 아래 첨부하였고

Incident Identifier: 97414F63-E941-4D49-A4A3-3B69FE56F347
Hardware Model:      iPhone10,4
Process:             DongwonMall [39170]
Path:                /private/var/containers/Bundle/Application/B2DA8073-EE12-4548-9BB4-9A7237F7A480/DongwonMall.app/DongwonMall
Identifier:          com.dongwon.mall
Version:             5.0.7 (0)
AppStoreTools:       16E137
AppVariant:          1:iPhone10,4:16
Code Type:           ARM-64 (Native)
Role:                Foreground
Parent Process:      launchd [1]
Coalition:           com.dongwon.mall [5317]

Date/Time:           2025-05-10 00:22:43.8026 +0900
Launch Time:         2025-05-10 00:20:45.0710 +0900
OS Version:          iPhone OS 16.7.11 (20H360)
Release Type:        User
Baseband Version:    6.01.01
Report Version:      104

Exception Type:  EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000001, 0x00000001b74885a4
Triggered by Thread:  0


Thread 0 name:
Thread 0 Crashed:
0   libswiftCore.dylib            	0x00000001b74885a4 _assertionFailure(_:_:file:line:flags:) + 248 (AssertCommon.swift:143)
1   libswift_Concurrency.dylib    	0x00000001c6fc5278 CheckedContinuation.resume(returning:) + 400 (CheckedContinuation.swift:167)
2   DongwonMall                   	0x00000001002e360c closure #1 in closure #1 in KakaoLoginRepository.loginWithKakaoTalk() + 392
3   DongwonMall                   	0x00000001002e3a9c partial apply for closure #1 in closure #1 in KakaoLoginRepository.loginWithKakaoTalk() + 68
4   ThirdPartyLibraryKit          	0x0000000101bb4f4c closure #1 in closure #1 in AuthController._authorizeWithTalk(launchMethod:prompts:channelPublicIds:serviceTerms:nonce:completion:) + 388
5   ThirdPartyLibraryKit          	0x0000000101bb9b9c partial apply for closure #1 in closure #1 in AuthController._authorizeWithTalk(launchMethod:prompts:channelPublicIds:serviceTerms:nonce:completion:) + 16 (/<compiler-generated>:0)
6   ThirdPartyLibraryKit          	0x0000000101babd50 closure #1 in AuthApi.token(code:codeVerifier:redirectUri:completion:) + 880 (AuthApi.swift:101)
7   ThirdPartyLibraryKit          	0x0000000101ba82e4 closure #2 in Api.responseData(_:_:parameters:headers:sessionType:apiType:logging:completion:) + 1384 (Api.swift:193)
8   ThirdPartyLibraryKit          	0x000000010196ca30 partial apply for specialized closure #2 in closure #2 in closure #3 in closure #1 in DownloadRequest._response<A>(queue:responseSerializer:completionHandler:) + 48
9   ThirdPartyLibraryKit          	0x000000010181b470 thunk for @escaping @callee_guaranteed @Sendable () -> () + 28 (/<compiler-generated>:0)
10  libdispatch.dylib             	0x00000001c432f7a8 _dispatch_call_block_and_release + 24 (init.c:1518)
11  libdispatch.dylib             	0x00000001c4330780 _dispatch_client_callout + 16 (object.m:560)
12  libdispatch.dylib             	0x00000001c4311e10 _dispatch_main_queue_drain + 888 (queue.c:7794)
13  libdispatch.dylib             	0x00000001c4311a88 _dispatch_main_queue_callback_4CF$VARIANT$armv81 + 36 (queue.c:7954)
14  CoreFoundation                	0x00000001bd6119ac __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12 (CFRunLoop.c:1780)
15  CoreFoundation                	0x00000001bd5f5648 __CFRunLoopRun + 2080 (CFRunLoop.c:3147)
16  CoreFoundation                	0x00000001bd5f9d20 CFRunLoopRunSpecific + 584 (CFRunLoop.c:3418)
17  GraphicsServices              	0x00000001f56c9998 GSEventRunModal + 160 (GSEvent.c:2196)
18  UIKitCore                     	0x00000001bf88c34c -[UIApplication _run] + 868 (UIApplication.m:3782)
19  UIKitCore                     	0x00000001bf88bfc4 UIApplicationMain + 312 (UIApplication.m:5372)
20  libswiftUIKit.dylib           	0x00000001c5816ddc UIApplicationMain(_:_:_:_:) + 100 (UIKit.swift:538)
21  DongwonMall                   	0x00000001002c0de8 specialized static UIApplicationDelegate.main() + 28 (/<compiler-generated>:29)
22  DongwonMall                   	0x00000001002c0de8 static AppDelegate.$main() + 28 (AppDelegate.swift:0)
23  DongwonMall                   	0x00000001002c0de8 main + 116
24  dyld                          	0x00000001dadb8344 start + 1860 (dyldMain.cpp:1165)

throwing 오류도 발생하는것을 찾긴했는데 2.24.0 버전입니다

Incident Identifier: B82948CF-3F52-43EB-818A-FD7E3E68CE97
Distributor ID:      com.apple.AppStore
Hardware Model:      iPhone13,2
Process:             DongwonMall [95294]
Path:                /private/var/containers/Bundle/Application/455A2722-651C-4F55-A194-0E1136CBD1FF/DongwonMall.app/DongwonMall
Identifier:          com.dongwon.mall
Version:             5.0.6 (1)
AppStoreTools:       16E137
AppVariant:          1:iPhone13,2:18
Code Type:           ARM-64 (Native)
Role:                Foreground
Parent Process:      launchd [1]
Coalition:           com.dongwon.mall [8432]

Date/Time:           2025-05-03 20:17:52.1470 +0900
Launch Time:         2025-05-03 20:16:15.3822 +0900
OS Version:          iPhone OS 18.4.1 (22E252)
Release Type:        User
Baseband Version:    5.51.03
Report Version:      104

Exception Type:  EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000001, 0x000000019371f8c4
Termination Reason: SIGNAL 5 Trace/BPT trap: 5
Terminating Process: exc handler [95294]

Triggered by Thread:  0


Thread 0 name:
Thread 0 Crashed:
0   libswiftCore.dylib            	0x000000019371f8c4 _assertionFailure(_:_:file:line:flags:) + 172 (AssertCommon.swift:162)
1   libswift_Concurrency.dylib    	0x00000001a0ba45a4 CheckedContinuation.resume(throwing:) + 344 (CheckedContinuation.swift:196)
2   DongwonMall                   	0x00000001022d69a8 closure #1 in closure #1 in KakaoLoginRepository.loginWithKakaoTalk() + 328
3   DongwonMall                   	0x00000001022d6e78 partial apply for closure #1 in closure #1 in KakaoLoginRepository.loginWithKakaoTalk() + 68
4   ThirdPartyLibraryKit          	0x000000010298d34c closure #1 in closure #1 in AuthController._authorizeWithTalk(launchMethod:prompts:channelPublicIds:serviceTerms:nonce:completion:) + 232
5   ThirdPartyLibraryKit          	0x0000000102992038 partial apply for closure #1 in closure #1 in AuthController._authorizeWithTalk(launchMethod:prompts:channelPublicIds:serviceTerms:nonce:completion:) + 16 (/<compiler-generated>:0)
6   ThirdPartyLibraryKit          	0x00000001029840a4 closure #1 in AuthApi.token(code:codeVerifier:redirectUri:completion:) + 536 (AuthApi.swift:0)
7   ThirdPartyLibraryKit          	0x00000001029808ac closure #2 in Api.responseData(_:_:parameters:headers:sessionType:apiType:logging:completion:) + 1668 (Api.swift:189)
8   ThirdPartyLibraryKit          	0x0000000102778c40 partial apply for specialized closure #2 in closure #2 in closure #3 in closure #1 in DownloadRequest._response<A>(queue:responseSerializer:completionHandler:) + 48
9   ThirdPartyLibraryKit          	0x00000001026d9710 implicit closure #1 in BenchmarkGauge.record<A>(_:attributes:) + 4 (/<compiler-generated>:0)
10  ThirdPartyLibraryKit          	0x00000001026d9710 MoyaProvider.endpoint(_:) + 20
11  ThirdPartyLibraryKit          	0x00000001026d3470 thunk for @escaping @callee_guaranteed @Sendable () -> () + 28 (/<compiler-generated>:0)
12  libdispatch.dylib             	0x000000019cfcdaac _dispatch_call_block_and_release + 32 (init.c:1575)
13  libdispatch.dylib             	0x000000019cfe7584 _dispatch_client_callout + 16 (client_callout.mm:85)
14  libdispatch.dylib             	0x000000019d004574 _dispatch_main_queue_drain.cold.5 + 812 (queue.c:8104)
15  libdispatch.dylib             	0x000000019cfdcd30 _dispatch_main_queue_drain + 180 (queue.c:8085)
16  libdispatch.dylib             	0x000000019cfdcc6c _dispatch_main_queue_callback_4CF + 44 (queue.c:8264)
17  CoreFoundation                	0x00000001950c22b4 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 16 (CFRunLoop.c:1793)
18  CoreFoundation                	0x00000001950c00b0 __CFRunLoopRun + 1980 (CFRunLoop.c:3163)
19  CoreFoundation                	0x00000001950e4700 CFRunLoopRunSpecific + 572 (CFRunLoop.c:3434)
20  GraphicsServices              	0x00000001e1c25190 GSEventRunModal + 168 (GSEvent.c:2196)
21  UIKitCore                     	0x0000000197d02240 -[UIApplication _run] + 816 (UIApplication.m:3845)
22  UIKitCore                     	0x0000000197d00470 UIApplicationMain + 336 (UIApplication.m:5540)
23  UIKitCore                     	0x000000019815ea30 UIApplicationMain(_:_:_:_:) + 104 (UIKit.swift:565)
24  DongwonMall                   	0x00000001022b48ac specialized static UIApplicationDelegate.main() + 28 (/<compiler-generated>:29)
25  DongwonMall                   	0x00000001022b48ac static AppDelegate.$main() + 28 (AppDelegate.swift:0)
26  DongwonMall                   	0x00000001022b48ac main + 116
27  dyld                          	0x00000001bbae7ad8 start + 5964 (dyldMain.cpp:1443)

앱 내에서 카카오톡으로 로그인 시도가 한 번만 실행되는 것이 보장이 될까요?

현재 의심스러운 상황은 카카오톡으로 로그인이 앱 내에서 짧은 시간 여러 번 발생하여 같은 authorizeWithTalkCompletionHandler이 호출되는 것이 문제인 것으로 추측됩니다.

또한, 카카오톡으로 로그인은 로그인 플로우 동안 1개의 로그인 결과를 반환하기를 기대하는데 여러 번 요청이 들어올 경우 가장 마지막 것만 처리하게 됩니다. 이렇게 될 경우 기존 여러 개 생성된 CheckedContinuation 인스턴스는 결과를 받지 못해 leak 될 확률이 높습니다.

CheckedContinuation 사용 시, 카카오톡으로 로그인으로 요청이 연달아 발생하지 않는지 확인 부탁드립니다.

1개의 좋아요

로그인 시도가 한번만 실행되는것을 보장해주고 있지 않습니다.
앱에서 카카오 로그인 요청시 곧 바로 카카오 로그인 플로우로 넘어가기 때문에 연달아 발생할거라는 부분은 미처 생각치 못하였습니다.
말씀해주신 부분이 맞는것 같습니다.
해당 부분 처리 후 모니터링을 해보겠습니다 감사합니다

1개의 좋아요