Author: rfm Date: Fri Apr 29 09:31:48 2016 New Revision: 39708 URL: http://svn.gna.org/viewcvs/gnustep?rev=39708&view=rev Log: Improve checks for attempted use of a deallocate/cached autorelease pool.
Modified: libs/base/trunk/Source/NSAutoreleasePool.m Modified: libs/base/trunk/Source/NSAutoreleasePool.m URL: http://svn.gna.org/viewcvs/gnustep/libs/base/trunk/Source/NSAutoreleasePool.m?rev=39708&r1=39707&r2=39708&view=diff ============================================================================== --- libs/base/trunk/Source/NSAutoreleasePool.m (original) +++ libs/base/trunk/Source/NSAutoreleasePool.m Fri Apr 29 09:31:48 2016 @@ -203,7 +203,7 @@ /* When the _released_count of a pool gets over this value, we raise an exception. This can be adjusted with +setPoolCountThreshhold */ -static unsigned pool_count_warning_threshhold = UINT_MAX; +static unsigned pool_count_warning_threshhold = UINT_MAX-1; /* When the number of pools in a thread gets over this value, we raise an exception. This can be adjusted with +setPoolNumberThreshhold */ @@ -300,7 +300,15 @@ { NSAutoreleasePool *p = pop_pool_from_cache (tv); - NSAssert(++(p->_released_count) == 0, @"corrupted pool in cache"); + /* When we cache a 'deallocated' pool, we set its _released_count to + * UINT_MAX, so when we rtrieve it fromm the cache we must increment + * it to start with a count of zero. + */ + if (++(p->_released_count) != 0) + { + [NSException raise: NSInternalInconsistencyException + format: @"NSAutoreleasePool corrupted pool in cache"]; + } return p; } return NSAllocateObject (self, 0, zone); @@ -331,6 +339,7 @@ { struct autorelease_thread_vars *tv = ARP_THREAD_VARS; unsigned level = 0; + _parent = tv->current_pool; if (_parent) { @@ -536,8 +545,10 @@ return; if (_released_count >= pool_count_warning_threshhold) - [NSException raise: NSGenericException - format: @"AutoreleasePool count threshhold exceeded."]; + { + [NSException raise: NSGenericException + format: @"AutoreleasePool count threshhold exceeded."]; + } /* Get a new array for the list, if the current one is full. */ while (_released->count == _released->size) @@ -707,7 +718,14 @@ { struct autorelease_thread_vars *tv = ARP_THREAD_VARS; + if (UINT_MAX == _released_count) + { + [NSException raise: NSInternalInconsistencyException + format: @"NSAutoreleasePool -dealloc of deallocated pool"]; + } + [self emptyPool]; + NSAssert(0 == _released_count, NSInternalInconsistencyException); /* Remove self from the linked list of pools in use. * We already know that we have deallocated any child (in -emptyPool), @@ -725,12 +743,11 @@ _parent = nil; } - if (_released_count-- != 0) - { - _released_count++; - [NSException raise: NSInternalInconsistencyException - format: @"NSAutoreleasePool -dealloc of deallocated pool"]; - } + /* Mark pool as cached so that any attempt to add an object to use it + * or to deallocate it again will raise an exception. + * We reset to zero when we get i out of the cache as a new allocation. + */ + _released_count = UINT_MAX; /* Don't deallocate ourself, just save us for later use. */ push_pool_to_cache (tv, self); @@ -802,6 +819,7 @@ + (void) setPoolCountThreshhold: (unsigned)c { + if (c >= UINT_MAX) c = UINT_MAX - 1; pool_count_warning_threshhold = c; } _______________________________________________ Gnustep-cvs mailing list Gnustep-cvs@gna.org https://mail.gna.org/listinfo/gnustep-cvs