Because this isn’t already thorny enough, let me note that adding a [startDate
self] below the dispatch_sync in the first example doesn’t fix the problem.
This shows that it’s surviving long enough to at least reach the
dispatch_sync() call, and in fact malloc_history shows this:
> ALLOC 0x200028960-0x20002896f [size=16]: thread_102787000 |thread_start |
> _pthread_start | __NSThread__main__ | -[MyThread main] |
> -[__NSOperationInternal start] | -[MyOperation main] | +[NSDate date] |
> +[__NSCFDate __new:] | __CFAllocateObject |
> _internal_class_createInstanceFromZone | auto_zone_allocate_object
> ----
> FREE 0x200028960-0x20002896f [size=16]: thread_102787000 |thread_start |
> _pthread_start | __NSThread__main__ | -[MyThread main] |
> -[__NSOperationInternal start] | objc_collect | auto_collect |
> Auto::ThreadLocalCollector::collect(bool) |
> Auto::ThreadLocalCollector::process_local_garbage(bool) |
> Auto::ThreadLocalCollector::scavenge_local(unsigned long, unsigned long*)
In other words, it’s being collected after -main has returned, as part of
-[NSOperation start]’s cleanup.
Also new interesting data is that even in the -doThatThingTo:attachValue:
instances, the resurrected garbage pointer is still an NSDate from the *other*
example. So it seems like there’s some sort of a delayed response, like Core
Data is storing a weak-but-nonzeroing pointer to the NSDate somewhere, the
object is collected, and later mucking in the MOC exposes the dangling pointer.
I remain thoroughly mystified…
Thanks for any assistance,
Benjamin Rister
On Jan 26, 2010, at 10:57 AM, Benjamin Rister wrote:
> I’m getting an auto_zone_resurrection_error from inside Core Data. Because
> this is following switching from locking a MOC on different threads (which
> was working fine) to dispatching blocks to a GCD queue, my suspicion
> naturally tends towards a multithreading violation. However, I’ve been over
> it a million times and just can’t find by inspection any cases of doing
> anything in the MOC (including its MOs, obviously) besides on that queue.
> Using the debug suffix when loading frameworks (to try to enable Core Data’s
> multithreading asserts) dies elsewhere for no apparent reason, not to mention
> that I don’t actually see a _debug version in Core Data.framework, nor see a
> download to obtain one from connect.apple.com like there was for 10.5.
>
> However, there’s also a suspicious trend in the places that this happens of
> it appearing that an object assigned to a local variable or method parameter
> outside of a dispatch_sync() is being collected before its use in the block.
> In other words, the block’s reference may not be keeping the object alive.
> For instance:
>
> - (void)main {
> NSDate* startDate = [NSDate date];
>
> /* lots of stuff */
>
> dispatch_sync(dispatch_get_main_queue(), ^{
> if(![self isCancelled]) {
> MyManagedObject* myMO = self.aRelationship.itsMO;
> ourItem.numericalValue = /* a number; this works fine,
> so it seems the MO is okay*/;
> ourItem.aDate = startDate; /* problem occurs here, and
> Instruments suggests startDate is the resurrected pointer */
>
> /* ... */
> }
> });
> }
>
> So,
> - What’s the current mechanism for enabling Core Data’s multithreading
> asserts?
> - Is there a typical, non-multithreading cause for
> auto_zone_resurrection_errors inside Core Data?
> - Or, are there any known bugs with GC and blocks (or a bug of mine in the
> code snippet I gave) causing this?
>
>
> Some more details, if needed:
>
> malloc: resurrection error for block 0x2000281c0 while assigning
> 0x20003aa00[40] = 0x2000281c0
> garbage pointer stored into reachable memory, break on
> auto_zone_resurrection_error to debug
> (gdb) bt
> #0 0x00007fff8862dc44 in auto_zone_resurrection_error ()
> #1 0x00007fff88628f09 in check_resurrection ()
> #2 0x00007fff8862adac in auto_zone_set_write_barrier ()
> #3 0x00007fff80749625 in objc_assign_strongCast_gc ()
> #4 0x00007fff80251104 in -[NSManagedObject(_NSInternalMethods)
> _newPropertiesForRetainedTypes:andCopiedTypes:preserveFaults:] ()
> #5 0x00007fff80251deb in -[NSManagedObject(_NSInternalMethods)
> _newAllPropertiesWithRelationshipFaultsIntact__] ()
> #6 0x00007fff80251d4e in
> -[NSManagedObjectContext(_NSInternalChangeProcessing)
> _establishEventSnapshotsForObject:] ()
> #7 0x00007fff80251c00 in _PFFastMOCObjectWillChange ()
> #8 0x00007fff80251b15 in _PF_ManagedObject_WillChangeValueForKeyIndex ()
> #9 0x00007fff802519d2 in _sharedIMPL_setvfk_core ()
> #10 0x00007fff80255a0e in _svfk_3 ()
> #11 0x000000010000fd0e in __-[MyOperation
> doThatThingTo:attachValue:]_block_invoke_1 (.block_descriptor=0x1006c6440)
> #12 0x00007fff82873f98 in _dispatch_barrier_sync_f_slow_invoke ()
> #13 0x00007fff8285287a in _dispatch_queue_drain ()
> #14 0x00007fff82853127 in _dispatch_queue_serial_drain_till_empty ()
> #15 0x00007fff82885e4c in _dispatch_main_queue_callback_4CF ()
> ...
>
> This is another method that this typically, but not always, dies in. It’s in
> an NSOperation:
>
> - (void)doThatThingTo:(id)anIdentifier
> attachValue:(CodableClass*)codableObject {
> dispatch_sync(dispatch_get_main_queue(), ^{
> if(![self isCancelled]) {
> MyManagedObject* myMO = /* find the MO that
> anIdentifier leads us to; may create it if necessary */;
> myMO.numericalValue = /* a number; this assignment
> works fine and never has caused any problems, so myMO seems in good shape. */;
> myMO.transformableValue = codableObject; /* this is
> where the problem always seems to happen. */
>
> /* ... */
> }
> });
> }
>
>
> When in the executable info I use the debug suffix when loading frameworks, I
> don’t get into any real part of the program, but end up with SIGABRT in the
> first -[NSUserDefaults standardUserDefaults] call registering defaults.
>
> Program received signal: “SIGABRT”.
> (gdb) bt
> #0 0x00000001001358f2 in __kill ()
> #1 0x00000001001358e4 in kill ()
> #2 0x00000001001fbefc in raise ()
> #3 0x0000000100225acf in abort ()
> #4 0x000000010027d0c2 in _dispatch_abort ()
> #5 0x00000001001152f5 in dispatch_source_set_cancel_handler ()
> #6 0x00007fff87e47fff in ___CFMachPortCreateWithPort2_block_invoke_1 ()
> ...
> #11 0x00007fff87e47b5b in CFMachPortCreate ()
> #12 0x00007fff87e479b1 in _CFXNotificationCenterCreate ()
> ...
> #16 0x00007fff87e44b1b in CFPreferencesCopyAppValue ()
> #17 0x00007fff874875ef in -[NSUserDefaults(NSUserDefaults) initWithUser:] ()
> #18 0x00007fff874870c3 in +[NSUserDefaults(NSUserDefaults)
> standardUserDefaults] ()
> #19 0x000000010001fc18 in +[MyClass initialize] (self=0x100084d58,
> _cmd=0x7fff85309d28)
> #20 0x00007fff80743535 in _class_initialize ()
> ...
>
> The console only has this, which doesn’t seem related:
> <Debug>: _DSLookupGetProcedureNumber getpwuid = 3
> <Debug>: _DSLookupQuery 3 status OK
>
>
>
> --
> Benjamin Rister
> President, Decimus Software, Inc.
> http://decimus.net/
>
_______________________________________________
Cocoa-dev mailing list ([email protected])
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 [email protected]