• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: GC crash due to being naughty
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: GC crash due to being naughty


  • Subject: Re: GC crash due to being naughty
  • From: Greg Parker <email@hidden>
  • Date: Thu, 15 Oct 2009 16:30:35 -0700

On Oct 15, 2009, at 3:54 PM, Ben Haller wrote:
Hi all. I'm getting a crash in auto_zone_root_write_barrier() that I don't understand. I suspect it has to do with this little blurb in the Garbage Collection Programming Guide:

Limitations on Mac OS X v10.5: You may pass addresses of strong globals or statics into routines expecting
pointers to object pointers (such as id* or NSError**) only if they have first been assigned to directly, rather
than through a pointer dereference. You should never take the address of a weak global, static or instance
variable, as assigning or reading through that pointer will bypass the weak barriers and expose your programs
to race conditions.


But I'm not really sure. :-> Here's the situation. My app generates floods of instances of an NSObject subclass called AKIndividual. So many, in fact, that I don't want to alloc and dealloc them all, as that just thrashes the allocator madly (as verified with Sampler). Instead, I want to allocate a pool of them, and then throw them in the pool when I'm done with them, and get new ones out of the pool. (When I reuse them, I don't call -init again, I just wipe the ivars I'm using and put new values in, which I believe is OK.) When I'm messing about with them, and when they're in the pool, I don't want to keep them in Cocoa collections like NSMutableArray, because again that introduces too much overhead. Countless billions upon billions of these little guys I'm making, and the runtimes of my app will be measured in days to weeks, so optimizing this bottleneck really is important.

So my solution was to keep pointers to them in malloced buffers instead. The "unused pool" is a malloced buffer, the pools of ones that are doing various things are also malloced buffers, and everything is nice fast C code at this level. But I guess pointers to objects kept in malloced buffers are weak references, so my objects would be collected if I didn't have a strong reference somewhere. So when I first allocate them, I throw them into an NSMutableArray, and I don't ever take them out. That array is kept by the controller of the whole shebang; so when that controller gets collected, then all the individuals will be collected, but until then, they should always be strong-referenced.

This seems like it ought to work; and yet I get that crash in auto_zone_root_write_barrier(). After some puzzling, I found the above paragraph in the GC guide. I am indeed on 10.5. Is this what's biting me? I guess all the pointers to my AKIndividuals that are kept in my malloced arrays are all weak references, and so I guess the pointer to the malloced array itself, for example, is a pointer to a weak reference such as I am not supposed to use, and whenever I do something like "individuals[i]" to get an instance from my malloced buffer I guess I'm violating the weak barriers. I find it hard to believe that I'm not allowed to keep an array of pointers to objects, though; is that really what this blurb is saying? (On the other hand, the GC guide also says that "the malloc zone is never scanned", which would imply that this is fine, and that the references I put in my malloced arrays are not even weak; but then I'm puzzled by the crash in a write barrier function...) I don't really understand what is prohibited and exactly why; that blurb is way too short, and the example is too short and cryptic. Can some explain what is actually prohibited, and why, and whether what I'm doing is prohibited?

A pointer value stored in an ordinary malloc block is neither a "strong" nor a "weak" reference. It is a dangling pointer. It can be used safely, but requires great care because the garbage collector has no knowledge of what you're doing.


The auto_zone_root_write_barrier() crash can occur when you take the address of a global variable, then store into the global indirectly via that address. What does the crashed line of code look like?


-- Greg Parker email@hidden Runtime Wrangler


_______________________________________________

Cocoa-dev mailing list (email@hidden)

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:
This email sent to email@hidden


  • Follow-Ups:
    • Re: GC crash due to being naughty
      • From: Ben Haller <email@hidden>
References: 
 >GC crash due to being naughty (From: Ben Haller <email@hidden>)

  • Prev by Date: Re: GC crash due to being naughty
  • Next by Date: Re: Subclassing a view class from an external framework
  • Previous by thread: Re: GC crash due to being naughty
  • Next by thread: Re: GC crash due to being naughty
  • Index(es):
    • Date
    • Thread