SwiftData 0xdead10cc with cloudKitDatabase

I recently added SwiftData to my project in a limited capacity. I'm creating ModelConfiguration -> ModelContext directly in Swift code rather than in SwiftUI. I'm using an app group & a CloudKit database/container.

The functionality all seems fine, but I'm dealing with random 0xdead10cc crashes from threads with CoreData/libsqlite3.dylib in the stack traces (particularly with widgets & complications which aren't actively writing anything), often with NSCloudKitMirroringDelegate.m also in the stack. I haven't seen any actual functionality issues, but the crashing is worrisome.

I understand they're keeping files open to cause the 0xdead10cc, but my question is: Is there a clean way to shut down or force shut down SwiftData when using CloudKit? I've looked through example code on Apple's Developer site, but I can't seem to find anything about cleanup/shutdown best practices, though I may be missing something.

Here's an example thread from a crash log:

Thread 12:
0   libsystem_kernel.dylib        	0x00000000258b4fe4 pread + 12
1   libsqlite3.dylib              	0x0000000023ce7684 seekAndRead + 88 (sqlite3.c:44032)
2   libsqlite3.dylib              	0x0000000023c5ffc4 unixRead + 200 (sqlite3.c:44124)
3   libsqlite3.dylib              	0x0000000023c730fc readDbPage + 132 (sqlite3.c:66901)
4   libsqlite3.dylib              	0x0000000023cf14e4 getPageNormal + 532 (sqlite3.c:69515)
5   libsqlite3.dylib              	0x0000000023cfd684 getAndInitPage + 104 (sqlite3.c:79184)
6   libsqlite3.dylib              	0x0000000023c8f99c moveToRoot + 532 (sqlite3.c:82309)
7   libsqlite3.dylib              	0x0000000023cfa448 sqlite3BtreeTableMoveto + 168 (sqlite3.c:82547)
8   libsqlite3.dylib              	0x0000000023c859fc sqlite3VdbeExec + 4996 (sqlite3.c:105391)
9   libsqlite3.dylib              	0x0000000023c83da4 sqlite3_step + 976 (sqlite3.c:97868)
10  CoreData                      	0x00000000211c92d4 _execute + 128 (NSSQLiteConnection.m:4573)
11  CoreData                      	0x00000000211c5e74 -[NSSQLiteConnection execute] + 1784 (NSSQLiteConnection.m:5014)
12  CoreData                      	0x000000002121c3f8 -[NSSQLiteConnection insertRow:] + 1488 (NSSQLiteConnection.m:3608)
13  CoreData                      	0x00000000211ca160 _executeSaveChangesRequest + 1792 (NSSQLCore_Functions.m:2543)
14  CoreData                      	0x00000000211dc128 -[NSSQLSaveChangesRequestContext executeRequestCore:] + 28 (NSSQLSaveChangesRequestContext.m:263)
15  CoreData                      	0x00000000211fa424 -[NSSQLStoreRequestContext executeRequestUsingConnection:] + 220 (NSSQLStoreRequestContext.m:183)
16  CoreData                      	0x00000000211cce3c __52-[NSSQLDefaultConnectionManager handleStoreRequest:]_block_invoke + 56 (NSSQLConnectionManager.m:302)
17  CoreData                      	0x00000000211c99d4 __37-[NSSQLiteConnection performAndWait:]_block_invoke + 40 (NSSQLiteConnection.m:733)
18  libdispatch.dylib             	0x0000000020af2b94 _dispatch_client_callout + 16 (object.m:576)
19  libdispatch.dylib             	0x0000000020b004d8 _dispatch_lane_barrier_sync_invoke_and_complete + 56 (queue.c:1104)
20  CoreData                      	0x00000000211c3d4c -[NSSQLiteConnection performAndWait:] + 140 (NSSQLiteConnection.m:730)
21  CoreData                      	0x000000002122fb3c -[NSSQLDefaultConnectionManager handleStoreRequest:] + 208 (NSSQLConnectionManager.m:297)
22  CoreData                      	0x00000000211bd16c -[NSSQLCoreDispatchManager routeStoreRequest:] + 216 (NSSQLCoreDispatchManager.m:60)
23  CoreData                      	0x00000000211bfb8c -[NSSQLCore dispatchRequest:withRetries:] + 168 (NSSQLCore.m:3999)
24  CoreData                      	0x00000000211c0480 -[NSSQLCore executeRequest:withContext:error:] + 2044 (NSSQLCore.m:2963)
25  CoreData                      	0x000000002134662c __65-[NSPersistentStoreCoordinator executeRequest:withContext:error:]_block_invoke.387 + 8968 (NSPersistentStoreCoordinator.m:2967)
26  CoreData                      	0x00000000211c6190 -[NSPersistentStoreCoordinator _routeHeavyweightBlock:] + 220 (NSPersistentStoreCoordinator.m:644)
27  CoreData                      	0x00000000211bf3fc -[NSPersistentStoreCoordinator executeRequest:withContext:error:] + 1112 (NSPersistentStoreCoordinator.m:2779)
28  CoreData                      	0x00000000211d5468 -[NSManagedObjectContext save:] + 988 (NSManagedObjectContext.m:1624)
29  CoreData                      	0x0000000021296ba8 __52+[NSCKEvent beginEventForRequest:withMonitor:error:]_block_invoke_2 + 280 (NSCKEvent.m:76)
30  CoreData                      	0x00000000211d1024 developerSubmittedBlockToNSManagedObjectContextPerform + 156 (NSManagedObjectContext.m:3987)
31  libdispatch.dylib             	0x0000000020af2b94 _dispatch_client_callout + 16 (object.m:576)
32  libdispatch.dylib             	0x0000000020b004d8 _dispatch_lane_barrier_sync_invoke_and_complete + 56 (queue.c:1104)
33  CoreData                      	0x00000000211e3d8c -[NSManagedObjectContext performBlockAndWait:] + 256 (NSManagedObjectContext.m:4104)
34  CoreData                      	0x000000002129e14c __52+[NSCKEvent beginEventForRequest:withMonitor:error:]_block_invoke + 152 (NSCKEvent.m:66)
35  CoreData                      	0x00000000212231d0 -[PFCloudKitStoreMonitor performBlock:] + 84 (PFCloudKitStoreMonitor.m:148)
36  CoreData                      	0x0000000021284c28 +[NSCKEvent beginEventForRequest:withMonitor:error:] + 184 (NSCKEvent.m:61)
37  CoreData                      	0x000000002125fb80 __57-[NSCloudKitMirroringDelegate _performExportWithRequest:]_block_invoke + 256 (NSCloudKitMirroringDelegate.m:1435)
38  CoreData                      	0x0000000021209cb4 __92-[NSCloudKitMirroringDelegate _openTransactionWithLabel:assertionLabel:andExecuteWorkBlock:]_block_invoke + 64 (NSCloudKitMirroringDelegate.m:959)
39  libdispatch.dylib             	0x0000000020af1288 _dispatch_call_block_and_release + 24 (init.c:1549)
40  libdispatch.dylib             	0x0000000020af2b94 _dispatch_client_callout + 16 (object.m:576)
41  libdispatch.dylib             	0x0000000020af96bc _dispatch_lane_serial_drain + 680 (queue.c:3934)
42  libdispatch.dylib             	0x0000000020afa124 _dispatch_lane_invoke + 376 (queue.c:4025)
43  libdispatch.dylib             	0x0000000020b03c40 _dispatch_root_queue_drain_deferred_wlh + 268 (queue.c:7193)
44  libdispatch.dylib             	0x0000000020b034fc _dispatch_workloop_worker_thread + 516 (queue.c:6787)
45  libsystem_pthread.dylib       	0x0000000025f9b7bc _pthread_wqthread + 280 (pthread.c:2696)
46  libsystem_pthread.dylib       	0x0000000025f9b85c start_wqthread + 8 (:-1)
Answered by DTS Engineer in 800391022

A 0xdead10cc crash is triggered when the system is suspending an app because it is running out of the background execution time, and yet the app is holding a file lock or SQLite database lock at the moment.

Your app can run in the background in the following scenarios:

  • The user runs your app, and then returns to the home screen or switches to the other app.
  • A source, like the location service or VOIP, launches or resumes your app in the background. What source is relevant depends on the background modes your app supports.

In both cases, the system gives your app a short period of time before suspending it. If the tasks your app does when running in the background are light, the time window is long enough.

The 0xdead10cc prevention post provides more context about the kind of crash, though the solution may not directly apply if it is the synchronization activity of the framework triggering the crash.

Now to comment your questions:

I'm using an app group & a CloudKit database/container.

This configuration implies that multiple processes, such as your app and extensions, can synchronize the data store. If that is the case, it's probably not a great choice. For more information, see Avoid synchronizing a store with multiple persistent containers.

my question is: Is there a clean way to shut down or force shut down SwiftData when using CloudKit?

You can do that by nullifying the model container, and also other SwiftData objects such as model context(s) and models associated with the container because those objects may turn out hold a reference of the container.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Accepted Answer

A 0xdead10cc crash is triggered when the system is suspending an app because it is running out of the background execution time, and yet the app is holding a file lock or SQLite database lock at the moment.

Your app can run in the background in the following scenarios:

  • The user runs your app, and then returns to the home screen or switches to the other app.
  • A source, like the location service or VOIP, launches or resumes your app in the background. What source is relevant depends on the background modes your app supports.

In both cases, the system gives your app a short period of time before suspending it. If the tasks your app does when running in the background are light, the time window is long enough.

The 0xdead10cc prevention post provides more context about the kind of crash, though the solution may not directly apply if it is the synchronization activity of the framework triggering the crash.

Now to comment your questions:

I'm using an app group & a CloudKit database/container.

This configuration implies that multiple processes, such as your app and extensions, can synchronize the data store. If that is the case, it's probably not a great choice. For more information, see Avoid synchronizing a store with multiple persistent containers.

my question is: Is there a clean way to shut down or force shut down SwiftData when using CloudKit?

You can do that by nullifying the model container, and also other SwiftData objects such as model context(s) and models associated with the container because those objects may turn out hold a reference of the container.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

SwiftData 0xdead10cc with cloudKitDatabase
 
 
Q