Core Data initialization causes app to deadlock on startup

Users have been reporting that the TestFlight version of my app (compiled with Xcode 26 Beta 6 17A5305f) is sometimes crashing on startup. Upon investigating their ips files, it looks like Core Data is locking up internally during its initialization, resulting in iOS killing my app. I have not recently changed my Core Data initialization logic, and it's unclear how I should proceed.

Is this a known issue? Any recommended workaround? I have attached the crash stack below.

Thanks!

Answered by DTS Engineer in 856061022

Your crash report is only partially symbolicated. To be completely clear what happened in your app, you might consider fully symbolicating your report. The details of how to do so is covered in this article.

Having said that, your crash report indicates that the main thread (thread 0) was blocked when SwiftUI initialized a tab view (frame 8). Your app got involved into the process (frame 4, 5), and eventually ran into _dispatch_once_wait (frame 3) and __ulock_wait (frame 0):

Thread 0 name:   Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   libsystem_kernel.dylib        	       0x1df207f70 __ulock_wait + 8
1   libdispatch.dylib             	       0x196334c3c _dlock_wait + 56
2   libdispatch.dylib             	       0x196367408 _dispatch_once_wait.cold.1 + 148
3   libdispatch.dylib             	       0x196334b98 _dispatch_once_wait + 60
4   MyApp                       	       0x10047b7d4 0x100360000 + 1161172
5   MyApp                       	       0x100563524 0x100360000 + 2110756
6   SwiftUI                       	       0x19369cbd4 Tab<>.init<>(_:systemImage:value:content:) + 300
7   MyApp                       	       0x1005628a8 0x100360000 + 2107560
8   SwiftUI                       	       0x1931b5780 TabView.init<a>(selection:content:) + 360
9   MyApp                       	       0x1005620f4 0x100360000 + 2105588
10  MyApp                       	       0x1005669dc 0x100360000 + 2124252
11  SwiftUI                       	       0x192c2f4e8 LazyView.body.getter + 196

At the same time, NSPersistentCloudKitContainer was saving a context at thread 1 (frame 25), and the didSave notification triggered your code (frame 11 ~ 17). There, you did a fetch (frame 10), which led to a synchronous performBlockAndWait (frame 5) and then a __ulock_wait(frame 0).

Thread 1 name:   Dispatch queue: NSManagedObjectContext 0x1423ab480
Thread 1:
0   libsystem_kernel.dylib        	       0x1df207f70 __ulock_wait + 8
1   libdispatch.dylib             	       0x196334c3c _dlock_wait + 56
2   libdispatch.dylib             	       0x196334a5c _dispatch_thread_event_wait_slow + 56
3   libdispatch.dylib             	       0x196342a08 __DISPATCH_WAIT_FOR_QUEUE__ + 368
4   libdispatch.dylib             	       0x1963425c0 _dispatch_sync_f_slow + 148
5   CoreData                      	       0x19657889c -[NSManagedObjectContext performBlockAndWait:] + 308
...
10  CoreData                      	       0x19667f68c NSManagedObjectContext.fetch</a><a>(_:) + 84
11  MyApp                       	       0x1005f6c5c 0x100360000 + 2714716
12  MyApp                       	       0x1005f7a14 0x100360000 + 2718228
13  MyApp                       	       0x1005f3614 0x100360000 + 2700820
14  libdispatch.dylib             	       0x19634c584 _dispatch_client_callout + 16
15  libdispatch.dylib             	       0x1963359a8 _dispatch_once_callout + 32
16  MyApp                       	       0x1004c34f4 0x100360000 + 1455348
17  MyApp                       	       0x1004c320c 0x100360000 + 1454604
18  CoreFoundation                	       0x18e3aaf80 __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 148
19  CoreFoundation                	       0x18e3adfb0 ___CFXRegistrationPost_block_invoke + 92
...
25  CoreData                      	       0x1965ad3ac -[NSManagedObjectContext save:] + 3576
26  CoreData                      	       0x196847fc8 __85-[PFCloudKitMetadataModelMigrator checkForRecordMetadataZoneCorruptionInStore:error:]_block_invoke_2 + 504
...

By reading those unsymbolicated addresses, it's unclear what your app did, but you can review your code if those calls can lead to a deadlock. As an example, if frame 4 in thread 0 was waiting for something from frame 11 in thread 1, and vice versa, that will run into a deadlock.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Accepted Answer

Your crash report is only partially symbolicated. To be completely clear what happened in your app, you might consider fully symbolicating your report. The details of how to do so is covered in this article.

Having said that, your crash report indicates that the main thread (thread 0) was blocked when SwiftUI initialized a tab view (frame 8). Your app got involved into the process (frame 4, 5), and eventually ran into _dispatch_once_wait (frame 3) and __ulock_wait (frame 0):

Thread 0 name:   Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   libsystem_kernel.dylib        	       0x1df207f70 __ulock_wait + 8
1   libdispatch.dylib             	       0x196334c3c _dlock_wait + 56
2   libdispatch.dylib             	       0x196367408 _dispatch_once_wait.cold.1 + 148
3   libdispatch.dylib             	       0x196334b98 _dispatch_once_wait + 60
4   MyApp                       	       0x10047b7d4 0x100360000 + 1161172
5   MyApp                       	       0x100563524 0x100360000 + 2110756
6   SwiftUI                       	       0x19369cbd4 Tab<>.init<>(_:systemImage:value:content:) + 300
7   MyApp                       	       0x1005628a8 0x100360000 + 2107560
8   SwiftUI                       	       0x1931b5780 TabView.init<a>(selection:content:) + 360
9   MyApp                       	       0x1005620f4 0x100360000 + 2105588
10  MyApp                       	       0x1005669dc 0x100360000 + 2124252
11  SwiftUI                       	       0x192c2f4e8 LazyView.body.getter + 196

At the same time, NSPersistentCloudKitContainer was saving a context at thread 1 (frame 25), and the didSave notification triggered your code (frame 11 ~ 17). There, you did a fetch (frame 10), which led to a synchronous performBlockAndWait (frame 5) and then a __ulock_wait(frame 0).

Thread 1 name:   Dispatch queue: NSManagedObjectContext 0x1423ab480
Thread 1:
0   libsystem_kernel.dylib        	       0x1df207f70 __ulock_wait + 8
1   libdispatch.dylib             	       0x196334c3c _dlock_wait + 56
2   libdispatch.dylib             	       0x196334a5c _dispatch_thread_event_wait_slow + 56
3   libdispatch.dylib             	       0x196342a08 __DISPATCH_WAIT_FOR_QUEUE__ + 368
4   libdispatch.dylib             	       0x1963425c0 _dispatch_sync_f_slow + 148
5   CoreData                      	       0x19657889c -[NSManagedObjectContext performBlockAndWait:] + 308
...
10  CoreData                      	       0x19667f68c NSManagedObjectContext.fetch</a><a>(_:) + 84
11  MyApp                       	       0x1005f6c5c 0x100360000 + 2714716
12  MyApp                       	       0x1005f7a14 0x100360000 + 2718228
13  MyApp                       	       0x1005f3614 0x100360000 + 2700820
14  libdispatch.dylib             	       0x19634c584 _dispatch_client_callout + 16
15  libdispatch.dylib             	       0x1963359a8 _dispatch_once_callout + 32
16  MyApp                       	       0x1004c34f4 0x100360000 + 1455348
17  MyApp                       	       0x1004c320c 0x100360000 + 1454604
18  CoreFoundation                	       0x18e3aaf80 __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 148
19  CoreFoundation                	       0x18e3adfb0 ___CFXRegistrationPost_block_invoke + 92
...
25  CoreData                      	       0x1965ad3ac -[NSManagedObjectContext save:] + 3576
26  CoreData                      	       0x196847fc8 __85-[PFCloudKitMetadataModelMigrator checkForRecordMetadataZoneCorruptionInStore:error:]_block_invoke_2 + 504
...

By reading those unsymbolicated addresses, it's unclear what your app did, but you can review your code if those calls can lead to a deadlock. As an example, if frame 4 in thread 0 was waiting for something from frame 11 in thread 1, and vice versa, that will run into a deadlock.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

@DTS Engineer Thank you. I was able to symbolicate the crash report with MacSymbolicator and pinpoint the crash site.

Core Data initialization causes app to deadlock on startup
 
 
Q