Mailing Lists: Apple Mailing Lists
Image of Mac OS face in stamp
Re: free_garbage and underflow errors when using GC in Cocoa app with SetControlData() and/or HIViewSetText() calls
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: free_garbage and underflow errors when using GC in Cocoa app with SetControlData() and/or HIViewSetText() calls



Curiosity about a "refcount underflow" got the better of me. The top hit was in the GC programming guide: "…using CFRelease to release an object you have previously retained using retain will result in a reference count underflow error."

It looks like you are creating the string using Cocoa methods, then passing it into a Carbon view managing its memory using only CoreFoundation functions. The issue seems to be due to an interaction between the different behaviors of Foundation and CoreFoundation memory management methods/functions.

What happens if you instead use a CFString created by CoreFoundation functions rather than Foundation methods? Can you reproduce the error message if you just do:

CFStringRef string = CFMakeCollectable(CFStringCreateWithFormat(NULL, ...));
OSStatus status = SetControlData(control, kControlEntireControl, kControlStaticTextCFStringTag, sizeof(CFStringRef), &string);
if ([NSGarbageCollector defaultCollector] == NULL) CFRelease(string);

What if you avoid CFMakeCollectable and simply create then release after setting the control data?

—Jeremy

On Sat, Apr 18, 2009 at 1:45 AM, Nikita Zhuk <email@hidden> wrote:
(This is repost from Cocoa-dev since this issue has more to do with Carbon than it has to do with Cocoa).


Hello,

I'm writing a Cocoa application which is running under Mac OS X 10.5.6 and it's using garbage collection. The application is compiled in gc-supported mode (I'm aware that gc-only apps are the recommended practice instead of gc-supported ones). The application uses a Carbon view (HIViewRef) to display some textual information (in my situation I'm forced to use Carbon views instead of Cocoa views for couple of specific reasons).

I've been seeing the following errors in the console when the application is run:

malloc: free_garbage: garbage ptr = 0x1bb9a60, has non-zero refcount = 2
malloc: free_garbage: garbage ptr = 0x1af55d0, has non-zero refcount = 1
malloc: free_garbage: garbage ptr = 0x1b5d740, has non-zero refcount = 3
malloc: *** free() called with 0x1bba4a0 with refcount 0
malloc: reference count underflow for 0x1bba4a0, break on auto_refcount_underflow_error to debug.
malloc: free_garbage: garbage ptr = 0x1f43820, has non-zero refcount = 1
malloc: free_garbage: garbage ptr = 0x1f43990, has non-zero refcount = 1
malloc: *** free() called with 0x1b5e0a0 with refcount 0
malloc: reference count underflow for 0x1b5e0a0, break on auto_refcount_underflow_error to debug.
malloc: *** error for object 0x1f437e0: Non-aligned pointer being freed (2)

By setting a breakpoint to auto_refcount_underflow_error I've been able to find out that these errors occur inside the -[NSCFString finalize] method. By printing values on stack in gdb and using tools like MallocStackLoggingNoCompact, malloc-history, AUTO_RECORD_REFCOUNT_STACKS and auto_print_refcount_stacks() function I've been able to deduce that the string which is being finalized is created and used for the last time here:

NSString *string = [anObjCObject aMethodCreatingNSString]; // 'string' is a local variable. 'aMethodCreatingNSString' is basically just "return [NSString stringWithFormat:...];"
OSStatus status = SetControlData(control, kControlEntireControl, kControlStaticTextCFStringTag, sizeof(CFStringRef), &string); // The ControlKind of 'control' is kControlKindStaticText)
// 'string' is not referenced after these lines.

These errors do not occur every time this code is run - quite contrary, to reproduce these errors I have to run this code usually several hundreds times to get the first underflow or free_garbage error.

Documentation of SetControlData says that the passed-in data (i.e. 'string') is copied by this function, so the caller doesn't have to retain it. I've tried replacing SetControlData() with HIViewSetText(), with the same results. The code is compiled without optimizations, so the local 'string' variable shouldn't be collected by GC even if GC doesn't follow the void* argument of SetControlData() function in which 'string' is passed.

By examining the refcount stacks printed by the auto_print_refcount_stacks() function I can see that the refcount of 'string' is 1 right after it has been created by CFAllocatorAllocate(), then it drops to 0 when CFMakeCollectible() is called (by the Foundation framework), and then it goes up to 1 again when it's passed to the SetControlData() function which calls CFStringCreateCopy(), so everything seems correct here. But I'm still getting those refcount underflows and free_garbage errors.

This problem seems to go away if I add CFRetain(string) and CFRelease(string) around those two lines of code. However, since I can't see why I should be using those functions here I'm feeling that they're only masking the problem instead of fixing it.

Are there some issues I've not taken into account? Are there some GC-incompatibility issues with Carbon I should be aware of? Which debugging techniques should I use to investigate this further?

Best regards,
Nikita Zhuk


_______________________________________________
Do not post admin requests to the list. They will be ignored.
Carbon-dev mailing list      (email@hidden)

Help/Unsubscribe/Update your Subscription:


This email sent to email@hidden

 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Carbon-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden

References: 
 >free_garbage and underflow errors when using GC in Cocoa app with SetControlData() and/or HIViewSetText() calls (From: Nikita Zhuk <email@hidden>)



Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2011 Apple Inc. All rights reserved.