Program received signal: "EXC_BAD_ACCESS".
#0 0x00007fff825df445 in +[NSLayoutManager(NSPrivate) _doSomeBackgroundLayout] ()
#1 0x00007fff825df23f in _NSPostBackgroundLayout ()
#2 0x00007fff84cfe437 in __CFRunLoopDoObservers ()
#3 0x00007fff84cda6e4 in __CFRunLoopRun ()
#4 0x00007fff84cda03f in CFRunLoopRunSpecific ()
#5 0x00007fff86e50c4e in RunCurrentEventLoopInMode ()
#6 0x00007fff86e50a53 in ReceiveNextEventCommon ()
#7 0x00007fff86e5090c in BlockUntilNextEventMatchingListInMode ()
#8 0x00007fff824a5570 in _DPSNextEvent ()
#9 0x00007fff824a4ed9 in -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] ()
#10 0x00007fff8246ab29 in -[NSApplication run] ()
#11 0x00007fff82463844 in NSApplicationMain ()
#12 0x000000010000342c in main (argc=1, argv=0x7fff5fbff380) at /Users/jwz/src/xscreensaver/OSX/main.m:16
I'm not even using NSLayoutManager (as far as I know), so presumably this is some random memory corruption that happened somewhere else entirely, but turning on the MallocCheckHeap and related environment variables doesn't reveal anything. Any ideas how to debug this?
None of the XCode "Performance Tools" seem even remotely useful for tracking down memory corruption, but maybe I just don't understand them. Anyway, I thought the garbage collector was supposed to make everything sweetness and light?
The browser vendors have been funding valgrind for the mac. I think we use it already. Looks like you might need to build it from their svn repo though.
% port install valgrind
...
configure: error: Valgrind works on Darwin 9.x (Mac OS X 10.5)
These days when I hear "build it from svn" you might as well be saying "try it under Windows".
Build it from svn isn't going to magically fix valgrind on 10.6:
http://blog.mozilla.com/nnethercote/2009/09/02/valgrind-and-mac-os-10-6/
However evan is right... valgrind is exactly the right tool for memory corruption bugs. Some modicum of patience may be in order, or if thats unavailable you could go old school and strip the code down to the bare minimum "hello world" and see if that works, then gradually comment back in more bits of code till you isolate the problem. Coders love throwing tools at problems but sometimes it comes down to ye olde hard yards :(
Valgrind 10.6 support is almost ready - give us a couple of weeks.
I'm pretty sure the XCode "Performance Tools" are just a GUI slapped over some trival DTrace scripts. While I'm as big a DTrace fanboy as anyone (a Turing-complete tracing tool is really, really nifty) I'm not sure it actually buys you much for this.
Ordinarily I'd suggest MallocDebug.app, but it looks as though that's 32-bit only. Ugh. :(
Try the MallocGuardEdges environment variables. It's not as elegant as valgrand, but as long as your program doesn't allocate loads of memory, it should do the trick.
MallocGuardEdges If set, add a guard page before and after
each large block.
check 'man malloc' for details of this and other fun malloc options.
Yes, I set every one of those malloc variables. That's what the "and related" was. It caught nothing.
Is is possible the packagers of the Really Slick Screensavers, or maybe the Electric Sheep team, could offer you advice on how to handle this bug?
NSLayoutManager will be used by all text drawing in a Cocoa process; it's how the text system decides where to place glyphs.
Given that this is a crash in some code you don't actually call, I suspect that your code needs to be adapted to GC and won't just magically work with it. autozone is not just a malloc replacement like the Boehm collector; the GC heap and the malloc heap are separate and have distinct rules. There's a Programming Guide that discusses what needs to be done to be done to make Objective-C code GC-compatible, especially in situations where it's being mixed with C code.
For example, if you have a malloc'd struct with a void * field, and you store a pointer to an Objective-C object into it, you need to CFRetain that object so the collector knows there's an additional reference to the object. (Stores into Objective-C objects get write barriers generated by the compiler, not so for stores into C structs.) Otherwise the collector may think there are no more references to the object, collect it, and sooner or later you're writing through a wild pointer.
Doh! I hadn't thought of that. Your theory appears to be correct, because the crashes go away if I do [[NSGarbageCollector defaultCollector] disable] in initWithFrame. But without that, even after adding some CFRetain calls to the few places I store ObjC objects into C structs, I still get the crashes. Are there any tools for debugging GC lossage like this?