views:

438

answers:

4

As the title says, my app crashes when garbage collection is not enabled. The app pops up for a few seconds and then it just crashes, with nothing but this in the debugger console:

[Session started at 2009-08-17 15:03:20 -0600.]
GNU gdb 6.3.50-20050815 (Apple version gdb-966) (Tue Mar 10 02:43:13 UTC 2009)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-apple-darwin".sharedlibrary apply-load-rules all
Attaching to process 12535.
unable to read unknown load command 0x22
unable to read unknown load command 0x22
unable to read unknown load command 0x22
unable to read unknown load command 0x22

I don't know why its happening. I think its probably a memory management issue. I used AnalysisTool (front-end to Clang Static Analyzer) to check for leaks and memory management issues, and I fixed the issues it found. Running the app through Instruments however reveals a memory leak around the time it starts. I have no idea where this leak is coming from...With garbage collection enabled the app runs fine, but Instruments still finds a leak.

Source code is available upon request

Thanks

+2  A: 

XCode has a bunch of memory profiling support built in - turning those on might reveal more information. I found these links particularly helpful:

http://developer.apple.com/technotes/tn2004/tn2124.html#SECMALLOC

http://www.cocoadev.com/index.pl?NSZombieEnabled

http://www.cocoadev.com/index.pl?DebuggingTechniques

http://www.cocoadev.com/index.pl?DebuggingAutorelease

psychotik
None of those have anything to do with Xcode. They are features of the libraries, debugger, and other tools.
Peter Hosey
+2  A: 

You're probably releasing an object when you shouldn't, then sending it a subsequent message. unfortunately, the crash (where the subsequent message is sent) isn't where the problem is - it's where you are releasing (or worse, deallocing) where you shouldn't. The clang static analyser isn't foolproof, and blindingly following the advice won't necessarily have helped.

AlBlue
You're right, after setting NSZombieEnabled and NSDebugEnabled I found this in the Console right before it crashes: *** -[CFArray countByEnumeratingWithState:objects:count:]: message sent to deallocated instance 0x15e04b90I'm unsure on where its occuring though.
macatomy
OK, so somewhere you're allocating an array, and then releasing/deallocing it whilst still holding a reference to it. You need to trace back to all references to that array when you're doing a 'release' message and find out why. You should never send an object the 'dealloc' message unless you're in the dealloc call, in which you can do [super dealloc] only.
AlBlue
The alternative (one which I didn't consider before :-) is that the array is fine, but that one of the objects in the array has been released before its time.
AlBlue
+1  A: 

If it crashes after showing something for a few seconds, it may indicate that something that needed to be retained was released by the autorelease pool at the end of the run loop. Have a look at places where you assign variables with objects returned by other methods. Any method without "new", "copy", "alloc" (there's a few others I think) in the name usually indicates that you'll need to retain it if you want to keep using it.

It could also mean that you have released something that you shouldn't have and it was released again by the autorelease pool. Have a look at all the places you are releasing objects and make sure that you are only releasing objects that you have either retained yourself, or releasing objects returned by methods that explicitly state ownership, such as "new", "alloc", "copy", "mutableCopy" and so on.

dreamlax
Thanks, the problem seems to be this: * -[CFArray countByEnumeratingWithState:objects:count:]: message sent to deallocated instance 0x15e04b90 . I used shell malloc_history and I get this:http://pastebin.com/m4ba1d576I don't know where to start looking for the problem though.
macatomy
A: 

Since the error says it occurs when calling [CFArray countByEnumeratingWithState:objects:count:] on a deallocated object, that gives you a fairly good idea of where to look. That method is part of part of NSFastEnumeration, so unless you're calling that method directly (highly unlikely), it is being invoked from within a for (... in ...) loop on your array object. If you can figure out where that is, you can set a breakpoint on (or just before) the for loop and check whether your object has been deallocated. The most likely cause of the problem is failing to properly retain the array, and it is probably released by the run loop draining an NSAutoReleasePool.

Quinn Taylor
Hi, yeah I have several of the for loops. After I set breakpoints, how do I check if the object has been deallocated?
macatomy
Set BPs on malloc_printf and malloc_debug_error.That should take you right to where you need.
psychotik
Thanks, I found the issue :)
macatomy