URL: <http://savannah.gnu.org/bugs/?46956>
Summary: Thread safety issues in NSUserDefaults.m cause unwarranted exceptions to be raised Project: GNUstep Submitted by: lcampbel Submitted on: Sat 23 Jan 2016 09:19:50 PM GMT Category: Base/Foundation Severity: 3 - Normal Item Group: Bug Status: None Privacy: Public Assigned to: None Open/Closed: Open Discussion Lock: Any _______________________________________________________ Details: The fix for bug #40620 has caused a new problem. Since _createArgumentsDictionary can now return nil, this can cause this snippet of initWithContentsOfFile: [_tempDomains setObject: [self _createArgumentDictionary] forKey: NSArgumentDomain]; to raise an exception: Tried to add nil value for key 'NSArgumentDomain' to dictionary Since this code can be called implicitly when you call something, like NSLog, that you don't really expect ever to raise exceptions, this can cause problems. (In my case, a lock was left locked, because I really didn't expect to have to catch exceptions from NSLog, and this caused a deadlock later on.) The following code snippet easily reproduces the problem: - (void)cr3283311_thread0:(NSDate *)deadline { NSAutoreleasePool *pool = [NSAutoreleasePool new]; const NSTimeInterval sleepTime = 0.01; unsigned frobs = 0; const NSTimeInterval blagInterval = 2.0; NSDate *nextBlag = [[NSDate dateWithTimeIntervalSinceNow:blagInterval] retain]; NSLog(@"cr3283311_thread0 starting"); while ([deadline timeIntervalSinceNow] > 0.0) { NSAutoreleasePool *pool = [NSAutoreleasePool new]; [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"freddieboy"]; [NSUserDefaults resetStandardUserDefaults]; [NSThread sleepForTimeInterval:sleepTime]; [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"freddieboy"]; [NSUserDefaults resetStandardUserDefaults]; [NSThread sleepForTimeInterval:sleepTime]; frobs++; if ([nextBlag timeIntervalSinceNow] < 0.0) { NSTimeInterval t = -[deadline timeIntervalSinceNow]; NSLog(@" Time remaining: %.1f sec; frobs: %u", t, frobs); [nextBlag release]; nextBlag = [[NSDate dateWithTimeIntervalSinceNow:blagInterval] retain]; } [pool release]; } [nextBlag release]; NSLog(@"cr3283311_thread0 ending"); [pool release]; } - (void)cr3283311_threadn:(NSDate *)deadline { NSAutoreleasePool *pool = [NSAutoreleasePool new]; const NSTimeInterval sleepTime = 0.01; NSUInteger counts = 0; unsigned trips = 0; NSLog(@"cr3283311_threadn starting"); while ([deadline timeIntervalSinceNow] > 0.0) { NSAutoreleasePool *pool = [NSAutoreleasePool new]; NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; NSDictionary *d; NSAssert(ud != nil, @"NSUserDefaults botch"); d = [ud dictionaryRepresentation]; counts += [d count]; trips++; [NSThread sleepForTimeInterval:sleepTime]; [pool release]; } NSLog(@"cr3283311_threadn ending"); [pool release]; } - (void)cr3283311 { const unsigned threadCount = 4; unsigned i; const NSTimeInterval runningTime = 60.0; NSDate *deadline = [NSDate dateWithTimeIntervalSinceNow:runningTime]; [NSThread detachNewThreadSelector:@selector(cr3283311_thread0:) toTarget:self withObject:deadline]; for (i = 0; i < threadCount; i++) [NSThread detachNewThreadSelector:@selector(cr3283311_threadn:) toTarget:self withObject:deadline]; while ([deadline timeIntervalSinceNow] > 0.0) [NSThread sleepForTimeInterval:0.1]; } _______________________________________________________ Reply to this item at: <http://savannah.gnu.org/bugs/?46956> _______________________________________________ Message sent via/by Savannah http://savannah.gnu.org/ _______________________________________________ Bug-gnustep mailing list Bug-gnustep@gnu.org https://lists.gnu.org/mailman/listinfo/bug-gnustep