On 12 Mar 2011, at 17:52, Quincey Morris wrote: > On Mar 12, 2011, at 06:36, [email protected] wrote: > >> keychainRef also has an initial retainCount of 2 (the framework recycles the >> same object I presume).
> > Unfortunately, this is meaningless. Trying to interpret retain count values > leads to madness. > >> Either way I could not trigger an auto_zone_resurrection_error(). > > Sorry, I ignored this key point -- where the error was detected. Although the > error message didn't say this, the fact that is was reported as a > resurrection error tells you one important thing -- the object had no strong > references, but during the 'finalize' method of some other object your > SecKeychainRef was CFRetain'ed again. Let's look at the crash report again: > >> Exception Type: EXC_BAD_INSTRUCTION (SIGILL) >> Exception Codes: 0x0000000000000001, 0x0000000000000000 >> Crashed Thread: 2 Dispatch queue: Garbage Collection Work Queue >> >> Application Specific Information: >> objc[4128]: garbage collection is ON >> fatal resurrection error for garbage block 0x10bbcf0(SecKeychain[304]): >> over-retained during finalization, refcount = 1 >> ... >> malloc: garbage block 0x10bbcf0(SecKeychain[304]) was over-retained during >> finalization, refcount = 1 >> This could be an unbalanced CFRetain(), or CFRetain() balanced with -release. >> Break on auto_zone_resurrection_error() to debug. >> KosmicTask(4128,0xb013d000) malloc: fatal resurrection error for garbage >> block 0x10bbcf0(SecKeychain[304]): over-retained during finalization, >> refcount = 1 > > > So here's the sequence of events (I'm guessing): > > 1. The SecKeychainRef's lifetime had ended -- no strong references, no > outstanding CFRetain. > > 2. Something called 'malloc' to allocate memory in the GC zone. > > 3. The collector decided to run during the 'malloc' call (maybe there wasn't > enough free memory, or maybe it happened for kinky GC reasons). > > 4. The GC found all the dying objects, which included the SecKeychainRef and > some others. > > 5. The GC started invoking 'finalize' on the dying objects. > > 6. Some object (most likely not the SecKeychainRef) CFRetain'ed the > SecKeychainRef object. (It's not clear that this is technically illegal, but > it seems like a bad idea. Leaving a finalize having left behind a new strong > reference to a dying object is certainly illegal.) There was no balancing > CFRelease. > > 7. It's interesting that the final crash was an illegal instruction. I'm not > sure if that can be interpreted to mean that a function in one of the dead > objects was called. > > So it's not simply a missing CFRelease during the normal flow of execution. > There are at least two possibilities: > > 1. One of your 'finalize' methods invokes other methods that eventually cause > something to retain the SecKeychainRef again. That sort of thing often > happens when you do too much stuff in 'finalize', because you can > inadvertently trigger consequences you never thought of. It's also possible > that it's a frameworks 'finalize' that's doing it, not you, but that's > probably not the best assumption to start from. > > 2. One of your 'finalize' methods does something that seems self-contained, > but starts something asynchronous behind the scenes. Eventually, if this > wasn't started from 'finalize', it would complete and the memory management > would be balanced, but in this context it never gets to complete before the > rug is pulled out. > > So, I'd try this two-headed approach: > > 1. Examine your code to try to find everything that could cause your > SecKeychainRef to be retained (directly or indirectly, unfortunately), and > try to figure out if this could be executed (directly or indirectly) during > some 'finalize' or other. > > 2. Examine all your 'finalize' methods, and see if they could cause a > SecKeychainRef to be retained (directly or indirectly), even if it's > apparently only temporary and properly balanced by a CFRelease. > > Sorry, can't think of anything more useful than that. > Thanks again Quincey for the suggestions. I have examined my code carefully and just cannot get any traction on this. The SecKeychainRef is stashed on the stack and passed into a class method so I don't see how it could get anywhere near a finalize method. I have encountered, and fixed, NSObject resurrection errors before but there was repeatability. Maybe the finalize reference in the crash report is misleading - search for handle_overretained_garbage in the link below: http://www.opensource.apple.com/source/libauto/libauto-141.2/AutoZone.cpp?txt Does the finalize concept even apply in the context of a CFType? I do utilise some other keychain access code but it doesn't create an explicit SecKeychainRef - though I presume the framework would have to. I think I will have to wait on some more crash reports. Thanks again. Regards Jonathan Mitchell Developer Mugginsoft LLP http://www.mugginsoft.com _______________________________________________ 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]
