UIDocument saveToUrl Delayed Crash

450 Views Asked by At

I have a Core Data app that's been running fine for over 4 years. Last week I updated XCode to version 8.2.1 (can't remember what I was running before this, but it had been months since I updated it).

After updating, I'm now getting a crash that I can't track down. There's a delay between doing something in the app, and getting the crash to occur. I have attempted to setup global breakpoints to gain more information, but nothing specific is shown that I can tell.

I don't explicitly spawn any threads myself.

When my app first launches, in the viewDidLoad of my initial viewController I do this:

- (void)viewDidLoad
{
      [super viewDidLoad];

      NSFileManager* fileManager = [NSFileManager defaultManager];

      NSURL* ubiquitousURL = [fileManager URLForUbiquityContainerIdentifier:nil];

      NSDictionary* localOptions = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES],
               NSMigratePersistentStoresAutomaticallyOption,
               [NSNumber numberWithBool:YES],
               NSInferMappingModelAutomaticallyOption,
               nil];

      NSURL* localURL = [fileManager URLForDirectory:NSDocumentDirectory
                             inDomain:NSUserDomainMask
                             appropriateForURL:nil
                             create:NO
                             error:nil];

      NSURL* localCoreDataURL = [localURL URLByAppendingPathComponent:@"MyData"];

      self.database = [[UIManagedDocument alloc] initWithFileURL:localCoreDataURL];
      self.database.persistentStoreOptions = localOptions;

      if( [fileManager fileExistsAtPath:[localCoreDataURL path]] )
      {
          [self.database openWithCompletionHandler: ^(BOOL success) {
              //log statement
          }];
      }
      else
      {
          NSFileCoordinator* coordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
         [coordinator coordinateWritingItemAtURL:ubiquitousURL
                                      options:NSFileCoordinatorWritingForDeleting
                        error:nil
                        byAccessor:^(NSURL *newURL) {
                        [[NSFileManager defaultManager] removeItemAtURL:newURL error:nil];
                                 }];
         [self.database saveToURL:localCoreDataURL
                        forSaveOperation:UIDocumentSaveForCreating
                        completionHandler:^(BOOL success) {
                            //log statement
                        }];
      }
}

Later in the app, I allow the user to create some data and save it (create a new entity), like this:

NSManagedObjectContext* context = database.managedObjectContext;

NSError* error = nil;
if( ![context save:&error])
{
    [AppUtility printNsError:error];

    [NSException raise:NSInternalInconsistencyException format:@"An error occurred when saving context: %@",[error localizedDescription]];
}
else
{
    if (![[context parentContext] save:&error])
    {
        NSLog(@"Error Saving Parent Data %@, %@", error, [error userInfo]);
    }
}

The app will then run for 15 to 20 seconds, then suddenly crash. There is an error in the log that says

[NSError retain]: message sent to deallocated instance 0x608000443b10

And the output in the debug navigator looks like this:

Thread 1 Queue: com.apple.main-thread
    0 __forwarding__
    1 _forwarding_prep_0__
    2 -[UIDocument saveToURL:forSaveOperation:completionHandler:
    3 __55-[UIDocument _saveUnsavedChangesWithCompletionHandler:)_block_invoke_2
    4 _dispatch_call_block_and_release
    5 _dispatch_client_callout ()
    6 _dispatch_main_queue_callback_4CF
    7 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__
    8 __CFRunLoopRun
    9 CFRunLoopRunSpecific
    10 GSEventRunModal
    11 UIApplicationMain
    12 main
    13 start
    14 start

    Enqueued from UIDocument File Access (Thread 5)
    0 _dispatch_queue_push
    1 __55-[UIDocument _saveUnsavedChangesWithCompletionHandler:]_block_invoke
    2 _dispatch_call_block_and_release
    ...

    Equeued from com.apple.main-thread (Thread 1)
    0 _dispatch_queue_push
    1 -[UIDocument _saveUnsavedChangesWithCompletionHandler:]
    2 -[UIDocument _autosaveWithCompletionHandler:]
    3 +[UIDocument _autosavingTimerDidFireSoContinue:]
    4 __NSFireTimer ()
    5 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__
    ...

In an attempt to get more information, I enabled Zombie settings, then ran this in XCode:

command script import lldb.macosx.heap
malloc_info --stack-history *memory address*

The output of that didn't seem to point to a specific line in my app:

(lldb) malloc_info --stack-history 0x60820f611fd0
       0x000060820f611fd0: malloc(    48) -> 0x60820f611fd0
       _NSZombie_NSError stack[0]: addr = 0x60820f611fd0, type=malloc, frames:
 [0] 0x000000010ffcb130 libsystem_malloc.dylib`calloc + 30
 [1] 0x000000010ea45458 libobjc.A.dylib`class_createInstance + 85
 [2] 0x000000010ea4fd55 libobjc.A.dylib`_objc_rootAlloc + 42
 [3] 0x000000010de1f19b Foundation`+[NSError errorWithDomain:code:userInfo:] + 37
 [4] 0x000000010c1a4a3c CoreData`-[NSPropertyDescription(_NSInternalMethods) _nonPredicateValidateValue:forKey:inObject:error:] + 124
 [5] 0x000000010c1a4bc0 CoreData`-[NSRelationshipDescription(_NSInternalMethods) _nonPredicateValidateValue:forKey:inObject:error:] + 80
 [6] 0x000000010c1a3b40 CoreData`-[NSManagedObject(_NSInternalMethods) _validateValue:forProperty:andKey:withIndex:error:] + 384
 [7] 0x000000010c1a3896 CoreData`-[NSManagedObject(_NSInternalMethods) _validatePropertiesWithError:] + 358
 [8] 0x000000010c1a36f7 CoreData`-[NSManagedObject(_NSInternalMethods) _validateForSave:] + 119
 [9] 0x000000010c1b3d4c CoreData`-[NSManagedObject validateForInsert:] + 76
 [10] 0x000000010c1a2a77 CoreData`-[NSManagedObjectContext(_NSInternalAdditions) _validateObjects:forOperation:error:exhaustive:forSave:] + 1783
 [11] 0x000000010c1a2202 CoreData`-[NSManagedObjectContext(_NSInternalAdditions) _validateChangesForSave:] + 146
 [12] 0x000000010c1a1f56 CoreData`-[NSManagedObjectContext(_NSInternalChangeProcessing) _prepareForPushChanges:] + 214
 [13] 0x000000010c19e972 CoreData`-[NSManagedObjectContext save:] + 562
 [14] 0x000000010ce26a9d UIKit`__43-[UIManagedDocument contentsForType:error:]_block_invoke + 30
 [15] 0x000000010c1b89a7 CoreData`developerSubmittedBlockToNSManagedObjectContextPerform + 199
 [16] 0x000000010c1b885f CoreData`-[NSManagedObjectContext performBlockAndWait:] + 255
 [17] 0x000000010ce269f0 UIKit`-[UIManagedDocument contentsForType:error:] + 258
 [18] 0x000000010cd9477c UIKit`-[UIDocument saveToURL:forSaveOperation:completionHandler:] + 486
 [19] 0x000000010cd962b2 UIKit`__55-[UIDocument _saveUnsavedChangesWithCompletionHandler:]_block_invoke_2 + 156
 [20] 0x000000010fd77978 libdispatch.dylib`_dispatch_call_block_and_release + 12
 [21] 0x000000010fda10cd libdispatch.dylib`_dispatch_client_callout + 8
 [22] 0x000000010fd818a4 libdispatch.dylib`_dispatch_main_queue_callback_4CF + 406
 [23] 0x000000010ef9de49 CoreFoundation`__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 9
 [24] 0x000000010ef6337d CoreFoundation`__CFRunLoopRun + 2205
 [25] 0x000000010ef62884 CoreFoundation`CFRunLoopRunSpecific + 420
 [26] 0x00000001115dfa6f GraphicsServices`GSEventRunModal + 161
 [27] 0x000000010c5a1c68 UIKit`UIApplicationMain + 159
 [28] 0x000000010bac23bf MyApp`main + 111 at main.m:16:9
 [29] 0x000000010fded68d libdyld.dylib`start + 1
 [30] 0x0000000110153001 libsystem_pthread.dylib`_thread + 1

Can someone help me diagnose this?

0

There are 0 best solutions below