When deploying the application to the device, the program will quit after a few cycles with the following error:
Program received signal: \"EXC_BAD_ACCESS\".
A major cause of EXC_BAD_ACCESS is from trying to access released objects.
To find out how to troubleshoot this, read this document: DebuggingAutoReleasePool
Even if you don't think you are "releasing auto-released objects", this will apply to you.
This method works extremely well. I use it all the time with great success!!
In summary, this explains how to use Cocoa's NSZombie debugging class and the command line "malloc_history" tool to find exactly what released object has been accessed in your code.
Sidenote:
Running Instruments and checking for leaks will not help troubleshoot EXC_BAD_ACCESS. I'm pretty sure memory leaks have nothing to do with EXC_BAD_ACCESS. The definition of a leak is an object that you no longer have access to, and you therefore cannot call it.
UPDATE: I now use Instruments to debug Leaks. From Xcode 4.2, choose Product->Profile and when Instruments launches, choose "Zombies".
Not a complete answer, but one specific situation where I've received this is when trying to access an object that 'died' because I tried to use autorelease:
netObjectDefinedInMyHeader = [[[MyNetObject alloc] init] autorelease];
So for example, I was actually passing this as an object to 'notify' (registered it as a listener, observer, whatever idiom you like) but it had already died once the notification was sent and I'd get the EXC_BAD_ACCESS. Changing it to [[MyNetObject alloc] init]
and releasing it later as appropriate solved the error.
Another reason this may happen is for example if you pass in an object and try to store it:
myObjectDefinedInHeader = aParameterObjectPassedIn;
Later when trying to access myObjectDefinedInHeader you may get into trouble. Using:
myObjectDefinedInHeader = [aParameterObjectPassedIn retain];
may be what you need. Of course these are just a couple of examples of what I've ran into and there are other reasons, but these can prove elusive so I mention them. Good luck!
Just to add another situation where this can happen:
I had the code:
NSMutableString *string;
[string appendWithFormat:@"foo"];
Obviously I had forgotten to allocate memory for the string:
NSMutableString *string = [[NSMutableString alloc] init];
[string appendWithFormat:@"foo"];
fixes the problem.
Don't forget the @
symbol when creating strings, treating C-strings
as NSStrings
will cause EXC_BAD_ACCESS
.
Use this:
@"Some String"
Rather than this:
"Some String"
PS - typically when populating contents of an array
with lots of records.
I've been debuging, and refactoring code to solve this error for the last four hours. A post above led me to see the problem:
Property before:
startPoint = [[DataPoint alloc] init] ;
startPoint= [DataPointList objectAtIndex: 0];
.
.
.
x = startPoint.x - 10; // EXC_BAD_ACCESS
Property after: startPoint = [[DataPoint alloc] init] ; startPoint = [[DataPointList objectAtIndex: 0] retain];
Goodbye EXC_BAD_ACCESS
NSAssert() calls to validate method parameters is pretty handy for tracking down and avoiding passing nils as well.