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]

Reply via email to