On Oct 1, 2008, at 5:35 AM, Oleg Krupnov wrote:
In my application, I create a (single) background thread, for creating
thumbnail images. I use NSRunLoop and - [NSObject
performSelector:onThread:withObject:waitUntilDone:] to communicate
between the main and the background threads.

I am experiencing weird random crashes with the following log:

IconView(49550,0xb0103000) malloc: free_garbage: garbage ptr =
0x1239260, has non-zero refcount = 1
IconView(49550,0xb0103000) malloc: *** free() called with 0x1bdcf6b0
with refcount 0
IconView(49550,0xb0103000) malloc: *** auto malloc[49550]: agc error
for object 0x1bdcf6b0: Deallocating a non-block

Turn on malloc_history (see the malloc man page) and then grab a history of all allocation events at address 0x1bdcf6b0. Most likely (in your case, not all cases), whatever object was last at 0x1bdcf6b0 is the one that is being freed early.

My application relies heavily on garbage collection (the gc required
mode), so I never call malloc/free explicitly. I don't create
NSAutoreleasePool in the background thread's main method.

To verify:

- you are creating the thread via NSThread?

- you are running a Run Loop in said thread?

That should be sufficient to make the collector aware of the thread. If you were spinning up a pthread and doing your own cross-thread communication via the pthread synchronization primitives, then you would need to call [NSThread currentThread] from that thread to make the collector aware of the thread.

I set breakpoint on malloc_printf and I see the following stack trace:
malloc_printf
autocollect_internal
autocollection_thread
_pthread_start
thread_start.

I have noticed that these crashes occur more often when the workload
is high - i.e. there are many sequential requests to the background
thread.

Likely, simply a catalyst to failure. Under high load, there will be more objects created and destroyed. As such, the collector will be busier. As well, whatever race condition is causing the issue -- and it is a race condition, given the intermittent nature of the crasher -- is more likely to happen when more stuff is happening in your app, especially stuff that causes variation in thread scheduling.

Also, I have located a piece of code in the main thread such that when
I comment it out, the crash disappears, although the code fragment has
absolutely nothing to do with the background thread. It actually fills
a round rect with a gradient fill, in the main thread. Funny enough,
when the rect is square, not round, the bug also disappears.

Aha! When you are filling that rect, you are likely causing the main thread's stack to go fairly deep as the thread passes through the rendering machinery. And a round rect likely goes deeper than a square rect because of the extra math involved.

How is that significant?

It most likely indicates that the object being reaped too early by the collector is only being kept alive by the main thread's stack and, then, only inadvertently.

So:

- are you passing references to hunks of memory on the stack between threads?

- are you using NSInvocation? It doesn't correctly retain its arguments under GC. You'll want to keep references to arguments in some other container.

- are you storing pointers into malloc()'d memory or other places where the collector might not see them? If so, either don't or use CFRetain/CFRelease on the pointers that land outside of the collector's zone.

b.bum


Attachment: smime.p7s
Description: S/MIME cryptographic signature

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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