I received a strange crash report from a user. User says it is not reproducible. The way I read this, an infinite loop occurred in my NSPersistentDocument subclass of -canCloseDocumentWithDelegate:shouldCloseSelector:contextInfo: when my code invoked super. Here is the crash report.
Thread 0 Crashed: Dispatch queue: com.apple.main-thread 0 libSystem.B.dylib 0x923020d2 tiny_malloc_from_free_list + 5 1 libSystem.B.dylib 0x92301301 szone_malloc_should_clear + 263 2 libSystem.B.dylib 0x923011a8 malloc_zone_malloc + 81 3 com.apple.CoreFoundation 0x90750f27 _CFArrayReplaceValues + 2647 4 com.apple.Foundation 0x92ebe4d7 -[NSCFArray insertObject:atIndex:] + 192 5 com.apple.Foundation 0x92ebe40f -[NSCFArray addObject:] + 68 6 com.apple.CoreFoundation 0x907b680c __NSArrayEnumerate + 1452 7 com.apple.CoreFoundation 0x907b6011 -[NSArray enumerateObjectsUsingBlock:] + 49 8 com.apple.AppKit 0x908f6aea -[NSObjectParameterBinder _updateObject:observedController:observedKeyPath:context:] + 189 9 com.apple.AppKit 0x908f6a25 -[NSObjectParameterBinder _observeValueForKeyPath:ofObject:context:] + 82 10 com.apple.Foundation 0x92ee3714 NSKeyValueNotifyObserver + 372 11 com.apple.Foundation 0x92ee31b3 NSKeyValueDidChange + 377 12 com.apple.Foundation 0x92ec79ea -[NSObject(NSKeyValueObserverNotification) didChangeValueForKey:] + 127 13 com.mycompany.MyPrivateFramework 0x000f04f6 0x6000 + 959734 14 com.mycompany.MyPrivateFramework 0x000fa9d0 0x6000 + 1001936 15 com.mycompany.MyPrivateFramework 0x000faa14 0x6000 + 1002004 16 com.apple.AppKit 0x90c68f2f -[NSDocumentController _closeDocumentsStartingWith:shouldClose:closeAllContext:] + 65 17 com.mycompany.MyPrivateFramework 0x000fa97e 0x6000 + 1001854 18 com.mycompany.MyPrivateFramework 0x000fa97e 0x6000 + 1001854 19 com.mycompany.MyPrivateFramework 0x000fa97e 0x6000 + 1001854 … <snip out identical lines> … 509 com.mycompany.MyPrivateFramework 0x000fa97e 0x6000 + 1001854 510 com.mycompany.MyPrivateFramework 0x000fa97e 0x6000 + 1001854 511 com.mycompany.MyPrivateFramework 0x000fa97e 0x6000 + 1001854 I believe that lines 0-12 simply show the innocent methods which happened to be executing when the stack limit was blown, and that the actual problem is the infinite loop in lines 13-511. GDB says that the address 0x000fa97e 0x6000 is the line invoking super, at the end of my implementation shown below, as noted in the comment. And I believe it, because according to the user's story, the crash did occur when he closed a document, and also, in typical infinite loop behavior, it took more than a few seconds for the crash dialog to appear. How can there be an infinite loop invoking super in a method? Looks like it was re-invoking itself instead of invoking super. Jerry - (void)canCloseDocumentWithDelegate:(id)delegate shouldCloseSelector:(SEL)shouldCloseSelector contextInfo:(void *)contextInfo { if ([[[self macster] autosaveUponClose] boolValue]) { // User has checked ON the 'autosave upon close' option // From the user's account, and my examination of his data, I believe // that this branch did *not* execute prior to the crash. I'm // just including it for completeness // This code was taken from the second-last post in this thread: // http://www.cocoabuilder.com/archive/cocoa/153196-customizing-save-behavior-in-docbased-apps.html?q=%22Don't+Save%22+save+automatically#153196 // Only do this if the document has been previously saved if ([self fileURL]) { NSError* error ; BOOL ok =[[self managedObjectContext] save:&error] ; if (!ok) { [self alertError:error] ; } // Clear change count to prevent the super call from invoking save dialog [self updateChangeCount:NSChangeCleared] ; } } BOOL closeNow = YES ; if (NSApp && !m_skipAskExportDuringNextClose) { // From the user's account, and my examination of his data, I believe // that this branch did *not* execute prior to the crash. I'm // just including it for completeness NSMutableArray* unexportedActiveExporters = [[NSMutableArray alloc] init] ; for (Exporter* exporter in [[self macster] activeExportersOrdered]) { if ([exporter isActive]) { if ([[exporter ixportCount] integerValue] == 0) { [unexportedActiveExporters addObject:exporter] ; break ; } } } if ([unexportedActiveExporters count] > 0) { NSString* and = [NSString localize:@"andEndList"] ; NSString* list = [unexportedActiveExporters listValuesForKey:@"displayName" conjunction:and truncateTo:0] ; NSString* msg = [NSString localizeFormat: @"imex_exportShouldX", list] ; SSYAlert* alert = [SSYAlert alert] ; [alert setSmallText:msg] ; [alert setButton1Title:[[BkmxBasis sharedBasis] labelExportAndClose]] ; [alert setButton2Title:[[BkmxBasis sharedBasis] labelCancel]] ; [alert setButton3Title:[[BkmxBasis sharedBasis] labelClose]] ; NSArray* invocations ; invocations = [NSArray arrayWithObjects: [NSInvocation invocationWithTarget:self // "Export and Close" selector:@selector(exportAndCloseToExporters:) retainArguments:YES argumentAddresses:&unexportedActiveExporters], [NSNull null], // "Cancel" [NSInvocation invocationWithTarget:self // "Close" selector:@selector(close) retainArguments:YES argumentAddresses:NULL], nil] ; m_skipAskExportDuringNextClose = YES ; [self runModalSheetAlert:alert iconStyle:SSYAlertIconInformational modalDelegate:[SSYSheetEnder class] didEndSelector:@selector(didEndGenericSheet:returnCode:invocations:) contextInfo:[invocations retain]] ; closeNow = NO ; } [unexportedActiveExporters release] ; } if (closeNow) { // 20101120 The following line crashed with an infinite loop for user John Doe. [super canCloseDocumentWithDelegate:delegate shouldCloseSelector:shouldCloseSelector contextInfo:contextInfo] ; } m_skipAskExportDuringNextClose = NO ; } _______________________________________________ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com