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
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]