What does EXC_BAD_ACCESS mean? EXC_BAD_ACCESS is an exception raised as a result of accessing bad memory. We're constantly working with pointers to memory in Swift that link to a specific memory address. An application will crash whenever we try to access a pointer that is invalid or no longer exists.
To debug an EXC_BAD_ACCESS, you can generally find out the where the dangling pointer is by enabling zombie objects. Choose edit scheme, then Diagnostics tab in the Run section, then click the 'Zombie Objects' option. Another cause for EXC_BAD_ACCESS can be infinite recursion, which can be found by adding some logging.
From your description I suspect the most likely explanation is that you have some error in your memory management. You said you've been working on iPhone development for a few weeks, but not whether you are experienced with Objective C in general. If you've come from another background it can take a little while before you really internalise the memory management rules - unless you make a big point of it.
Remember, anything you get from an allocation function (usually the static alloc method, but there are a few others), or a copy method, you own the memory too and must release it when you are done.
But if you get something back from just about anything else including factory methods (e.g. [NSString stringWithFormat]
) then you'll have an autorelease reference, which means it could be released at some time in the future by other code - so it is vital that if you need to keep it around beyond the immediate function that you retain it. If you don't, the memory may remain allocated while you are using it, or be released but coincidentally still valid, during your emulator testing, but is more likely to be released and show up as bad access errors when running on the device.
The best way to track these things down, and a good idea anyway (even if there are no apparent problems) is to run the app in the Instruments tool, especially with the Leaks option.
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".
An EXC_BAD_ACCESS signal is the result of passing an invalid pointer to a system call. I got one just earlier today with a test program on OS X - I was passing an uninitialized variable to pthread_join()
, which was due to an earlier typo.
I'm not familiar with iPhone development, but you should double-check all your buffer pointers that you're passing to system calls. Crank up your compiler's warning level all the way (with gcc, use the -Wall
and -Wextra
options). Enable as many diagnostics on the simulator/debugger as possible.
In my experience, this is generally caused by an illegal memory access. Check all pointers, especially object pointers, to make sure they're initialized. Make sure your MainWindow.xib file, if you're using one, is set up properly, with all the necessary connections.
If none of that on-paper checking turns anything up, and it doesn't happen when single-stepping, try to locate the error with NSLog() statements: sprinkle your code with them, moving them around until you isolate the line that's causing the error. Then set a breakpoint on that line and run your program. When you hit the breakpoint, examine all the variables, and the objects in them, to see if anything doesn't look like you expect.I'd especially keep an eye out for variables whose object class is something you didn't expect. If a variable is supposed to contain a UIWindow but it has an NSNotification in it instead, the same underlying code error could be manifesting itself in a different way when the debugger isn't in operation.
I just spent a couple hours tracking an EXC_BAD_ACCESS and found NSZombies and other env vars didn't seem to tell me anything.
For me, it was a stupid NSLog statement with format specifiers but no args passed.
NSLog(@"Some silly log message %@-%@");
Fixed by
NSLog(@"Some silly log message %@-%@", someObj1, someObj2);
The 2010 WWDC videos are available to any participants in the apple developer program. There's a great video: "Session 311 - Advanced Memory Analysis with Instruments" that shows some examples of using zombies in instruments and debugging other memory problems.
For a link to the login page click HERE.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With