Weird crash with Concurrency

Hi everyone :wave:

Since some time we have really weird crash in our concurrency stack :/

We made many research and tests but it's looking like totally random and I have no more idea now ...

Some examples :

Crashed: com.apple.root.user-initiated-qos.cooperative
0  libswift_Concurrency.dylib     0x43710 performEscalationAction(swift::TaskStatusRecord*, swift::JobPriority) + 28
1  libswift_Concurrency.dylib     0x43160 swift_task_escalateImpl(swift::AsyncTask*, swift::JobPriority) + 276
2  libswift_Concurrency.dylib     0x3ee04 swift::AsyncTask::waitFuture(swift::AsyncTask*, swift::AsyncContext*, void (swift::AsyncContext* swift_async_context) swiftasynccall*, swift::AsyncContext*, swift::OpaqueValue*) + 552
3  libswift_Concurrency.dylib     0x3f584 swift_task_future_wait_throwingImpl(swift::OpaqueValue*, swift::AsyncContext*, swift::AsyncTask*, void (swift::AsyncContext* swift_async_context, void* swift_context) swiftasynccall*, swift::AsyncContext*) + 144
4  libswift_Concurrency.dylib     0x3b7cc swift::runJobInEstablishedExecutorContext(swift::Job*) + 244
5  libswift_Concurrency.dylib     0x3c1e8 swift_job_runImpl(swift::Job*, swift::ExecutorRef) + 72
6  libdispatch.dylib              0x15164 _dispatch_root_queue_drain + 396
7  libdispatch.dylib              0x1596c _dispatch_worker_thread2 + 164
8  libsystem_pthread.dylib        0x1080 _pthread_wqthread + 228
9  libsystem_pthread.dylib        0xe5c start_wqthread + 8
Crashed: com.apple.root.user-initiated-qos.cooperative
0  libswift_Concurrency.dylib     0x30f9c waitForStatusRecordUnlock(swift::AsyncTask*, swift::ActiveTaskStatus&) + 72
1  libswift_Concurrency.dylib     0x2fd00 acquireStatusRecordLock(swift::AsyncTask*, llvm::Optional<(anonymous namespace)::StatusRecordLockRecord>&, LockContext) + 148
2  libswift_Concurrency.dylib     0x30c28 swift_task_escalateImpl(swift::AsyncTask*, swift::JobPriority) + 84
3  libswift_Concurrency.dylib     0x2da54 swift::AsyncTask::waitFuture(swift::AsyncTask*, swift::AsyncContext*, void (swift::AsyncContext* swift_async_context) swiftasynccall*, swift::AsyncContext*, swift::OpaqueValue*) + 480
4  libswift_Concurrency.dylib     0x2df68 swift_task_future_wait_throwingImpl(swift::OpaqueValue*, swift::AsyncContext*, swift::AsyncTask*, void (swift::AsyncContext* swift_async_context, void* swift_context) swiftasynccall*, swift::AsyncContext*) + 84
5  libswift_Concurrency.dylib     0x2b0f0 swift::runJobInEstablishedExecutorContext(swift::Job*) + 132
6  libswift_Concurrency.dylib     0x2b9f8 swift_job_runImpl(swift::Job*, swift::ExecutorRef) + 72
7  libdispatch.dylib              0x482f0 _dispatch_root_queue_drain + 328
8  libdispatch.dylib              0x48acc _dispatch_worker_thread2 + 160
9  libsystem_pthread.dylib        0x4e48 _pthread_wqthread + 224
10 libsystem_pthread.dylib        0x49f0 start_wqthread + 8
Crashed: NSOperationQueue 0x1075db8e0 (QOS: UNSPECIFIED)
0  libobjc.A.dylib                0x39c8 objc_retain + 8
1  CFNetwork                      0x42db0 CFURLRequestSetShouldStartSynchronously + 34084
2  CFNetwork                      0x4920c CFURLCacheCurrentDiskUsage + 1020
3  CFNetwork                      0x46dd4 CFURLRequestSetHTTPRequestBodyParts + 9196
4  BRApiKit                       0x57814 HTTPMetrics.init(metrics:task:) + 61 (HTTPMetrics.swift:61)
5  BRApiKit                       0x39f78 specialized HTTPDataLoader.urlSession(_:task:didFinishCollecting:) + 281 (HTTPDataLoader.swift:281)
6  BRApiKit                       0x38310 @objc HTTPDataLoader.urlSession(_:task:didFinishCollecting:) + 4409131792 (<compiler-generated>:4409131792)
7  CFNetwork                      0x26cf4 CFURLRequestCopyHTTPRequestBodyStream + 2320
8  Foundation                     0x51bfc __NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__ + 24
9  Foundation                     0x63f74 -[NSBlockOperation main] + 104
10 Foundation                     0x3c1f4 __NSOPERATION_IS_INVOKING_MAIN__ + 24
11 Foundation                     0x4d5bc -[NSOperation start] + 788
12 Foundation                     0x50c48 __NSOPERATIONQUEUE_IS_STARTING_AN_OPERATION__ + 24
13 Foundation                     0x5edf0 __NSOQSchedule_f + 184
14 libdispatch.dylib              0x12830 _dispatch_block_async_invoke2 + 148
15 libdispatch.dylib              0x3a30 _dispatch_client_callout + 20
16 libdispatch.dylib              0x6eec _dispatch_continuation_pop + 500
17 libdispatch.dylib              0x65f0 _dispatch_async_redirect_invoke + 736
18 libdispatch.dylib              0x15164 _dispatch_root_queue_drain + 396
19 libdispatch.dylib              0x1596c _dispatch_worker_thread2 + 164
20 libsystem_pthread.dylib        0x1080 _pthread_wqthread + 228
21 libsystem_pthread.dylib        0xe5c start_wqthread + 8

We have many other like that :/
Any idea what we are missing and why we have some random crash like that ?
Thanks for your help :pray:

This looks like a known race in the current runtime which has been fixed in 5.7. Unfortunately, we do not currently have a solution for this race on previously-released runtimes.

4 Likes

I'm receiving this type of crash with Swift 5.7 as well. Is this the same issue or is there any workaround?

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

Triggered by Thread:  13

Thread 13 name:
Thread 13 Crashed:
0   libsystem_platform.dylib      	0x0000000227272140 _os_unfair_lock_corruption_abort + 88 (lock.c:534)
1   libsystem_platform.dylib      	0x000000022726ca28 _os_unfair_lock_lock_slow + 296 (lock.c:586)
2   libswift_Concurrency.dylib    	0x0000000237626438 waitForStatusRecordUnlock(swift::AsyncTask*, swift::ActiveTaskStatus&) + 156 (Mutex.h:354)
3   libswift_Concurrency.dylib    	0x00000002376260b0 swift_task_escalateImpl(swift::AsyncTask*, swift::JobPriority) + 100 (TaskStatus.cpp:175)
4   libswift_Concurrency.dylib    	0x0000000237621e04 swift::AsyncTask::waitFuture(swift::AsyncTask*, swift::AsyncContext*, void (swift::AsyncContext* swift_async_context) swiftasynccall*, swift::AsyncContext*, swift::OpaqueValue*) + 552 (Task.cpp:143)
5   libswift_Concurrency.dylib    	0x0000000237622584 swift_task_future_wait_throwingImpl(swift::OpaqueValue*, swift::AsyncContext*, swift::AsyncTask*, void (swift::AsyncContext* swift_async_context, void* swift_context) swiftasynccall*, swift::AsyncC... + 144 (Task.cpp:852)
6   ***********                   	0x0000000104b7eaed (2) await resume partial function for URLRequest.setHTTPBody(_:) + 4303597 (URLRequest+Extension.swift:97)
7   ***********                   	0x0000000104b5e60d (2) await resume partial function for HTTPRequest.urlRequest(inClient:) + 4171277 (HTTPRequest.swift:467)
8   ***********                   	0x0000000104b76ca1 (1) await resume partial function for partial apply for closure #2 in HTTPDataLoader.fetch(_:) + 4271265 (<compiler-generated>:0)
9   libswift_Concurrency.dylib    	0x00000002375fd225 $ss27withTaskCancellationHandler9operation8onCancelxxyYaKXE_yyYbXEtYaKlFTQ0_ + 1 (TaskCancellation.swift:40)
10  ***********                   	0x0000000104b71601 (4) await resume partial function for HTTPDataLoader.fetch(_:) + 4249089 (HTTPDataLoader.swift:69)
11  ***********                   	0x0000000104b5b40d (2) await resume partial function for HTTPRequest.fetch(_:) + 4158477 (HTTPRequest.swift:237)
12  ***********                   	0x0000000104b44305 (3) await resume partial function for BaseServiceProvider.fetch(_:) + 4064005 (BaseServiceProvider.swift:54)
13  ***********                   	0x0000000104b4d76d (2) await resume partial function for ServiceServiceProvider.isAppSupportedByBackend() + 4101997 (ServiceProvider.swift:20)
14  ***********                   	0x00000001047c3089 (2) await resume partial function for RealServicesInteractor.resolveIsAppSupportedByBackend() + 389257 (ServicesInteractor.swift:50)
15  ***********                   	0x00000001047c3559 (1) await resume partial function for protocol witness for ServicesInteractor.resolveIsAppSupportedByBackend() in conformance RealServicesInteractor + 390489 (<compiler-generated>:0)
16  ***********                   	0x00000001047eb341 (2) await resume partial function for closure #1 in RealSystemEventsHandler.appDidBecomeActive() + 553793 (SystemEventsHandler.swift:93)
17  ***********                   	0x00000001047ef47d (1) await resume partial function for partial apply for closure #1 in RealSystemEventsHandler.appDidBecomeActive() + 570493 (<compiler-generated>:0)
18  libswift_Concurrency.dylib    	0x0000000237624081 completeTaskWithClosure(swift::AsyncContext*, swift::SwiftError*) + 1 (Task.cpp:399)

What OS are you seeing that crash on? For now, the fix is only in the latest OS releases.

On 15.6.1 (19G82). So, this issue is fixed only in iOS 16 so far? Is there any workaround for iOS 15?

"Task escalation" is triggered when you wait for a task that was created at a lower priority than your current task; it should be a no-op if the task already has sufficient priority, so you might be able to work around the bug by making sure you don't create tasks with lower priority than the task that will ultimately wait for them. (That's usually good practice for avoiding priority inversions anyway.)

Hopefully you can figure out what task it is from the backtrace.

2 Likes