I pressed alt+cmd+r and activated NSZombieEnabled in Arguments > Environment Variables. Additionally, I activated it in Diagnostics > Memory Management > Enable Zombie Objects.
However, when I built and run, at some point my app crashes giving me this useless message in the console:
*** -[CALayer retainCount]: message sent to deallocated instance 0x656b260
The stack trace is just as useless. I moved the details-level slider all the way to the right. Thread 1 simply shows me this:
Everything is system-owned and there's not a single line related to my app. So obviously NSZombiesEnabled doesn't work as it did in Xcode 3, where it halted on the dead object.
Is there any way to figure out which CALayer is deallocated too early?
Update: So after building and running about 100 more times suddenly the problem DISAPPEARED! It's completely gone! And the best part: I did not modify my code in any way! Inbetween I cleaned the build folder and project with the clean commands several times and deleted the app in the Simulator several times as well.
Update 2: Fortunately the problem re-appeared. And now it seems persistent. Fortunately, because I prefer finding the root cause rather than annoying the users by random.
Update 3: Finally found it by accident:
startButton = newBttn;
should have been:
self.startButton = newBttn;
startButton was a retaining property and in -dealloc I released it. So it got overreleased and in most (but not all) cases after the view faded out it crashed giving that weird CALayer retainCount message.
The Zombies Instrument (CMD + I) finally pointed out that it had to do with a button. Just didn't know why and where.
Clang Static Analyzer didn't complain about this obvious glitch.
If this crops up again, you can run a dedicated Zombies instrument. Hit Command+I to profile the app and select the Zombies instrument (you must be running on the simulator). If you get a zombie, you can display the entire memory history (each retain/release) for that object, which is immensely helpful in tracking down errors.
In addition to Jeff's great answer; to do almost the same thing, but without having to open Instruments or profile your App, you can set NSZombieEnabled, MallocStackLogging, and guard malloc in the debugger. Then, when your App crashes, type this in the gdb console:
(gdb) info malloc-history 0x543216
Replace 0x543216 with the address of the object that caused the crash, and you will get a much more useful stack trace and it should help you pinpoint the exact line in your code that is causing the problem.
This article has some additional info.
Related
I used Leak Instruments to find Leaks and set NSZombieEnabled to YES. When I press a button or a particular row from tableView my app crashes and I am unable to find any information in Instruments.
I followed the tutorial here:
http://www.raywenderlich.com/2696/instruments-tutorial-for-ios-how-to-debug-memory-leaks
How can I identify or get more information in Instruments when my app is crashing?
Use Zombie for finding out the Zombie message. It will show you Pink flag with message.
You can Use Zombie message by enabling from edit schema and in Run tab Checkmark Enable Zombie object and you can see released object from console
Zombies are not the only thing you can have there.
The only way to find leaks is to you profiler with "Leaks" component.
Try also running Project / Analyze for static analyze of your code about memory management errors.
For crash - I think you just have error in code - not really leak. Enable exception breakpoint in your xcode to catch a problem !
http://blog.manbolo.com/2012/01/23/xcode-tips-1-break-on-exceptions
I have some code that returns a struct containing 2 objects (declared as id).
When trying to use one of the objects I get an EXC_BAD_ACCESS and the app crashes. This only happens on the device (ipad) not in the simulator.
I have set NSZombieEnabled to YES, however no information is written to the console.
I don't know if it's a problem that I'm using a workspace in Xcode 4, one project for my app, and another that builds a library which is used in my app. The EXC_BAD_ACCESS is occurring in the second project, so I don't know if NSZombieEnabled will apply to the second project?
How do I solve this? Especially as I it only happens on the device (even goes as planned on the simulator), and it is in the second project?
EDIT: This is the method where the EXC_BAD_ACCESS occurs, on line 62, on sortRange.lower –
NSZombieEnabled only works on the simulator, not on the device, so it's probably hiding the problem. Run Product > Analyze (⇧⌘B) for clues. It's harder to say more without looking at the code. As Mihai says, your objects are probably over released, which is the most common cause of EXC_BAD_ACCESS.
It seems that one of your objects is autoreleased before you are trying to access it. As the iPad has less memory than the computer you are running it on it get's released faster so that's why it's not available. Try NSLog both objects just before the line you are getting the error and see wich one of them is the problem and than trace back to it's origin and retain it somehow. Also don't forget to release it after you are done using it. Some example code would be useful.
I am getting this error in my iPhone app.
Error : DemoApp(1874,0xb024f000) malloc: * error for object 0xc79e430: double free
* set a breakpoint in malloc_error_break to debug
In that View I am using JSON code and after parsing data displayed accordingly but after few minutes application gets crashed. Can any one help me. Thank your
For any EXC_BAD_ACCESS or double free errors, you are usually trying to send a message to a released object. The BEST way to track these down is use NSZombieEnabled.
This works by never actually releasing an object, but by wrapping it up as a "zombie" and setting a flag inside it that says it normally would have been released. This way, if you try to access it again, it still know what it was before you made the error, and with this little bit of information, you can usually backtrack to see what the issue was.
It especially helps in background threads when the Debugger sometimes craps out on any useful information.
VERY IMPORTANT TO NOTE however, is that you need to 100% make sure this is only in your debug code and not your distribution code. Because nothing is ever release, your app will leak and leak and leak. To remind me to do this, I put this log in my appdelegate:
if(getenv("NSZombieEnabled") || getenv("NSAutoreleaseFreedObjectCheckEnabled"))
NSLog(#"NSZombieEnabled/NSAutoreleaseFreedObjectCheckEnabled enabled!");
It's just an memory release issues. By mistake I have release the memory before and after that I am trying to access the values of that variable that's why I am getting error. Thanks
I am trying to access the UITextView delegates and have a problem
I have a UIViewController with the UITextViewDelegate protocol and a Nib containing the textView.
If I set the delegate inside viewDidLoad like "textView.delegate = self" and I touch the textView, the app crashes without logging errors.
If I start editing the textView with code like "[textView becomeFirstResponder]" all delegates get called.
When I set the delegate in the Nib creating a connection between the textView and the File's owner and deleting "textView.delegate = self" also no delegates get called.
What am I doing wrong here?
Regards,
Elias
It's not easy to help you without more description, posted code or a xib file.
You say application crashes without any logging errors - well, do you mean that there's no output in console's window ? That is normal, for an app that has crashed.
Anyway, you should be able to get the stack-trace to figure out where approximately the application has crashed. Open the debugger (⇧⌘Y), and see the position. That should give you an idea of what went wrong.
Here you can see an example of such debugger session (after EXC_BAD_CRASH):
First two lines doesn't give us much information, but later on we can see that application has crashed while loading user interface from a NIB file. Well, usually the only code that executes during such load are awakeFromNib methods - it's up to you to find a problem along those lines.
Often top of code's execution doesn't make any sense - for example you might see your ViewController method somewhere, but the top few function calls (those where the code crashed) are located in methods/classes which you never call in your code. In most cases that is a sign of wrong memory de-/allocation. What might happened is that you forgot to retain some of your objects, it has already been released, but you are still keeping reference (a pointer) to its memory. Because that memory has been in fact freed, another object took its place later on, usually some Apple's internal object you've never heard about. Later on your code tries to message your poor object but it sends a message to something completely different. BUMMER! That's how you get those crashes and strange stack traces.
To fix the kind of problem I've just described you can use Instruments and its Zombies instrument. Unfortunately you can't start Zombies from within Xcode, you need to start Instruments standalone, then choose the Zombies under iPhone Simulator/Memory, then Choose Target from the toolbar, you should see your application in there, or be able to navigate to it on filesystem.
What Zombies instrument does is that it never really frees memory after objects are deallocated. Instead, it will mutate those objects into NSZombie class. That class intercepts all calls to itself, and informs you when some code is trying to send a message to it.
This is how such Instruments session looks like (this is the same crash as seen in debugger above):
In the table you can see that we're trying to message UIScrollView that has already been deallocated. You can as well see the whole history of retain/release calls to this particular object. That way you can find a missing retain or wrong release/autorelease.
Remember - Zombies Instruments can only be used with Simulator, because there's not enough memory on the real device to keep all those memory blocks.
Hopefully I could help you with further analysis of your problem.
I am trying to locate leaks using instruments, but the leaks I see there are like the ones in the next picture:
leaks
As you can see there's no information of which line of code is exactly leaking. All leaks I have, around 20, are like this, or in other words, the leaks don't show any line of my code in particular.
The leak in this picture is related to "_CFAllocatorSystem" (???) on the CoreFoundation and I have others that simply say GSEvent. I have no clue of what's generating these.
How can I discover that?
thanks for any help.
I think you want to go into instruments after running under leak and select "Source View". Then you need to drag your source files into the instrument window. It will then show the lines in the code where the leak occurs along with the call stack.
Some toss off code of mine leaks a view. It looks like this in Instruments:
alt text http://img688.imageshack.us/img688/9669/screenshot20091028at131.png
The thing that Leaks shows you is, the trace to the code that allocated the object that is leaking (which means it is retained but your application has no variables left that have that address). What it does not show you is just where the object should have been released to not cause the leak, for that is impossible to know (it is possible to find where release is currently being called, but that may not be so helpful).
So what this trace is telling me, is that some bit of memory allocated by the system is being retained by you, and then the reference forgotten - one key is the "PurpleEvent" line, which is common in a thread dealing with timer events or perhaps notifications. It could be you received a notification and kept something from it, without releasing it later on.
If you know about at what point the leak occurs, you should be able to isolate what code is running during that time.
See here and especially this quote:
This list informs you about the leaked objects' types, sizes, addresses, and even their call stacks.
Then you can trace the source of leaked memories through the call stacks.
The stack trace shows you exactly which line is the culprit. Apparently line 14 in main.m in your case. Dont know what you confused about?
The guilty was the accelerometer and I am compiling for OS 3.0.
In other words, the accelerometer that Apple said its leaks were fixed, is still leaking like hell.