I'm stuck with a problem in emulator. The emulator occasionally stops with
Program received signal: "EXC_BAD_ACCESS" .
as console output. No further info provided. Is there a chance to come closer to the problem?
I see that NSZombie already has been proposed, but the link doesn't seem to work anymore, so here's instructions on how to use it.
To activate NSZombie do the following:
Get info of the executable.
Go to the arguments tab.
In the "Variables to be set in the environment:" section add:
Name: NSZombieEnabled
Value: YES
Then run your app as usual and when it crashes it should tell you which deallocated object received the release message.
This often is caused by sending a message to an object that is no longer in memory. There is no error message because there is nothing on the stack when the error occurs. You can set breakpoints and step through your application until you find where the crash occurs, or you can use nszombie.
http://howtomakeiphoneapps.com/2009/02/nszombie-and-xcode-oh-my/
Related
This is a piece of code I had written in xcode
Foo * myFoo = [[Foo alloc] init] ;
[myFoo release] ;
[myFoo printMessage] ;
If I am right, it should give a runtime error when printmessage function is called as myFoo gets deallocated by that time. But in xcode , the code is working and print message is getting called, is it a problem due to setting on xcode?
Regards
Abhijit
You're invoking undefined behaviour by accessing freed memory.
It might crash, it might work fine, it might result in dancing unicorns spewing forth from your nose.
To detect memory errors whilst you're developing code, you should enable NSZombie's, see instructions here:
http://www.cocoadev.com/index.pl?NSZombieEnabled
Update
You might wonder why it works like this - surely the OS should always throw an error when you try to access memory that isn't valid?
The reason why you don't always get an error (and why the behaviour is undefined) is that checking the memory is valid on every access would result in a performance penalty - ie. the code would run slower, just to check for something that shouldn't ever happen.
Hence you must be careful to trap all these errors during development, so that they never happen for an end user. NSZombies is the best tool for finding them.
One other point - if you do "build and analyze" in xcode, it might also find this error at build time. Certainly the static analyzer will detect some memory errors at build time.
Releasing an object is not instantaneous, the object will be released, but one can't be sure that it's when one sends a release message. The behavior you're experiencing is normal.
-[CFString respondsToSelector:]: message sent to deallocated instance 0x4b9e720
I don't where to start, tried static analyzer and stepped through each line of code but still no help.
It means you are trying to use an object which has been deallocated - i.e. sent release or removeFromSuperview:
Check this page to see how to enable a debug feature called NSZombie - it keeps objects alive even when released, and lets you know which one you are accessing. The downside is that the program uses much more memory (since nothing is truly released) but you only use it until you have found the problem then turn it off.
Adam is right. But you should also enable MallocStackLogging.
Let's assume you have this output:
2003-03-18 13:01:38.644 yourApp[**<pid>**] *** *** Selector 'release'
sent to dealloced instance **<address>** of class NSConcreteData.
Type the following command into gdb (swap and with your values):
malloc_history <pid> <address>
This will tell you where and what has been allocated.
Run it in the debugger and look at the stack trace.
Is there a more detailed error to be found other than the console's EXC_BAD_ACCESS? Where/how can I see it?
When my app crashes, I see the error in thE XCode status bar, but the console shows nothing else. Where do I see more info about what causes the crash?
The application will have a stack trace, typically in the crash logs. Definitely look there for a bit more detail. Look under ~/Library/Logs/CrashReporter for those details. In general, run the application "Console.app" in your Utilities folder, and click on the button "Show Log List". It gives a detailed view into all the logs available that you'd likely want to check out in your system
If it's code you have written, the debugger (gdb) is the "how" to go to look for more detail. That's typically a "you overreleased" some object if you're working in Objective-C. There's a good set of notes on using the technique "NSZombieEnabled" to find what you're blowing up on.
From times to times, while debugging an Application, I see this error on Xcode:
Program received signal: “EXC_BAD_ACCESS”.
and the debugger does not stop on the problematic line. In fact the debugger just shows me a page with a bunch assembly language code and that's it.
I have to have paranormal powers to figure out where the exact problem is.
Is there a way to force Xcode to give me more "nutritive" error messages – that can detail the problem – and stop on the offending line when such errors occur?
thanks for any help.
When the crash happens, open the Debugger in Xcode (Run -> Debugger). There should be 3 to 4 panes like this:
http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/XcodeDebugging/art/debugger_disassembly.jpg
On the top-left pane (the "stack trace"), select the topmost row which is not gray.
(Note: Sometimes the stack trace can only find internal functions because of bad memory management triggered in the run loop. Try to Build -> Build and Analyze to eliminate all potential memory management bugs first.)
You can enable NSZombies see here and I've found a good way to see where the actual problem is, is to run and debug the program with the debugger open.
This way when the program stops executing it more often then shows the line that was executing when the program crashed.
I wrote up a blog that tells you how to use some compiler switches that help a lot in finding crashes that are the result of releasing objects before you are done with them.
http://loufranco.com/blog/files/debugging-memory-iphone.html
Build and Analyze is ok, but not as good as scan-build (which it is based on). Instructions for installing that are here:
http://loufranco.com/blog/files/scan-build-better-than-build-analyze.html
When over freeing a pointer you may see an error such as
"pointer being freed was not allocated"
When debugging with the simulator, I add a build argument MallocStackLogging = YES - this allows me to use malloc_history in the terminal to track down where I have over freed a pointer.
If I debug on the device with this build argument I get all sorts of console errors "cannot create stack log files" etc.
Oddly, I get some over freed pointer errors appearing on the device, but not on the simulator.
Has anyone had any experience tracking these down using the device itself?
Thanks!
Another way to do this. Make sure to turn NSZombie on so it reports the memory address of the object that is getting the extra release. Then Run with Performance Tool->Object Allocations. This will bring up instruments. Look at the Console log as provided by Xcode organizer. Once you get the crash lookup the memory address in instruments. You will see the entire history of mallocs/frees on that object, as well as links straight into your code.
I generally use NSZombie for such things, check this out
You need to set the MallocStackLogging env variables on the target executable...
To access these settings, select your executable from the Groups & Files pane in XCode, then Get Info.
Go to the Arguments tab and add the following entries into the “Variables to be set in the environment” box:
Please test the program for memory leaks,Also check autoreleases and whether you are releasing objects properly or not.Also we need to check whether a released object has a memory allocated or not.You also need to be careful regarding autorelease,because accidentally we might release an array or a string or any object that is already autoreleased...hope it helps and works!
Tip: You can test for leaks by analyzing your project(click shift+command+k)