Infinite Loop invoking super ?? -[NSDocument canCloseDocumentWithSelector:::]
Infinite Loop invoking super ?? -[NSDocument canCloseDocumentWithSelector:::]
- Subject: Infinite Loop invoking super ?? -[NSDocument canCloseDocumentWithSelector:::]
- From: Jerry Krinock <email@hidden>
- Date: Mon, 22 Nov 2010 09:32:44 -0800
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="Don't+Save"+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 (email@hidden)
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:
This email sent to email@hidden