I´ve been having some problems with a bug that causes my game to crash. First it just gave me a "BAD_ACCESS" but by enabling Zombie objects the debugger said this:
-[CCSprite setPosition:]: message sent to deallocated instance xxxx
The crash happens when object A and B collides, but ONLY if the collision takes place at the same moment as object B is created.
Both A and B should be destroyed at collision, this works just fine except in the situation described above. I´m using Box2D for what it´s worth.
Is there any way to track the error in a more specific way? Like if it´s A or B that´s giving me trouble.
If you are using the simulator, enable MallocStackLogging and NSDebugEnabled. Then when you get this message, make note of the process id and memory address of the offending object. Then in your terminal, use malloc_history <pid> <memory_address> to see the history of allocs and deallocs of this address. It will give you a stack trace of each alloc and dealloc. The most recent alloc is probably the place where you've allocated something that you possibly didn't retain, or the most recent dealloc is the place where you dealloc'd it accidentally.
Heres the man page for malloc_history:
https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man1/malloc_history.1.html
Related
I'm developing an iOS5 App using ARC, and I started to get some random EXEC_BAD_ACCESS crashes that I cannot figure out.. By random I mean it is very unpredictable: sometimes it may take a long time to crash, sometimes short. and there is also no one specific button/tablecell/etc. that trigger the crash. Every user interaction can possibly crash the app, but you cannot repeat the crash.
I have tried to turn on NSZombie and also some malloc debugger tools. In Instruments the crash error reads: An Objective-C message was sent to a deallocated object (zombie) at address: 0x10bd1b40. And the last part of the reference count log looks like this:
475 CoursesFirstViewController Release 2 02:23.253.631 0 UIKit -[UINibDecoder finishDecoding]
476 CoursesFirstViewController Release 1 02:23.253.838 0 Foundation -[NSAutoreleasePool drain]
477 CoursesFirstViewController Zombie -1 02:35.752.420 0 Foundation objectHash
The 2, 1, -1 thing are the reference counts. I have no idea why it skips 0 and drop to -1, crashing the program (all entries but the last have continuous ref counts). Also I have no idea what objectHash is.
My app comprises of multiple functions, accessible as icons on my main screen. CoursesFirstViewController is one of the functions. Always, it is CoursesFirstViewController and objectHash that crash the app, even if I am at somewhere else. (This is the case for the log above: I went out of CoursesFirstViewController (thus returning to the main screen of my app) at 02:23, but after 12 sec, when I was in some other function, the app crashed) I only need to enter CourseFirstViewController, mess around with it for a bit, and then go elsewhere to continue using the app, and after a while it will just crash.
I'm really mad of this problem now. I have searched SO and Google for quite a while but cannot find a solution. Any help will be greatly greatly appreciated. Thanks!!
#robmayoff yea I already checked that but didn't see anything especially useful there. the last few calls are objectHash, hashProbe, [NSConcreteHashTable rehashAround], [NSConcreteHashTable removeItem] etc.
This is actually somewhat useful. This is telling us that a collection, probably an NSDictionary, but possibly an NSSet is being destroyed. From your earlier information it seems to be an autoreleased collection that is created during the nib instantiation process (so probably an ivar of CoursesFirstViewController). That's where I'd be looking anyway given the symptoms, but the crash seems to confirm it.
General recommendations are auditing any __bridge casts or unsafe_unretained properties.
Another hunch is that you've named a method in a way that violates Cocoa memory management. The most likely misnaming would be that you have a property that starts with new or copy. This would definitely be an issue if you have ARC code call misnamed non-ARC code.
I suspect one of your properties is marked "weak" when it should be "strong" and is going out of scope and getting released before you access it. ARC can't save you in that case and you will get the above random crash behavior.
If you don't have any luck finding it I would resort to doing a global search for "weak" properties on your project and double-check each one to make sure it isn't something you expect to hang around. It's tedious but honestly doesn't take that long to do and sometimes turns up more than the one bug.
I gather from your Instruments output that the zombie object is of type CoursesFirstViewController. We often use a view controller as the delegate for some other object, and most objects that have delegates do not retain their delegates.
I am assuming that you aren't using any unsafe_unretained properties or variables, or any retain-type properties. So I assume that none of your objects is keeping a dangling reference to the CoursesFirstViewController zombie.
Since the system libraries have to work with non-ARC code, they do not use ARC's weak references. So if some system object has a CoursesFirstViewController as its delegate, and the CoursesFirstViewController is destroyed but the system object is not, then the system object is left with a dangling reference to the destroyed object.
So, check whether you're using the CoursesFirstViewController as the delegate for any system objects. If so, are you sure those objects don't outlive the CoursesFirstViewController?
I'm trying to track down some bugs, and one of them is related to a memory leak. It's an object that I can tell that something still has a reference to, since Instruments still shows it as being alive, but Instruments does not register it as a leak.
Is there anyway to look at an instance of an object in Objective-C and see what other objects still have a reference to that object?
I would recommend using the Allocations/ObjectAllocations Instruments template and then in the top right corner type the class name of your object (in the Category field).
You can then see the allocations increasing as you suggest and by viewing the extended detail you can see where they were allocated.
All content below this point was added by the OP (joshbuhler)
In the screenshot below, change the filter to "Objects List", and then by clicking on the little arrow to the right of the object's address, the history of memory events (alloc/retain/release/dealloc) will be show for that object. It won't show you exactly what is hanging onto that object, but it will give you some very useful info for tracking it down.
Cautionary Tail: :)
In the process of searching for a memory leak, I set a breakpoint (really a logpoint) in Xcode that would log the value of self when it was triggered troublesome logpoint image. Meanwhile I found the leak and patched it, but the memory usage wasn't leveling out, and my de-init was never getting called. The logpoint I set earlier was actually causing the retain count of my object to increase, and in turn that prevented de-init from ever getting called. I happened to discover this after several hours of wild goose chases which culminated in me stepping through my object's methods line by line, issuing p CFGetRetainCount(self) from debug console. When I stepped over the line with the logpoint, the retain count went up. At first I assumed it was some strange side effect of my code. I moved that logpoint so that I could set a normal breakpoint on that line, and my problem moved with it. I disabled the logpoint and the leak was gone. Hopefully this can help someone else.
If you're using xCode you can use the Performance tools to find the memory leaks. That will give you a nice graph of ALL memory allocation and if they are released or leaked.
xcode -> run -> Start with Performance Tools -> Leaks.
Memory leak detection tools
Further to this question: NSRunLoop is receiving a strange selector; possible race condition tomfoolery? - where it was discovered that a UIGestureRecognizer was being deallocated and then receiving a message, I printed out the address of one of my GRs in order to see if it was the one being reported by zombies.
With the print message in the code, I can no longer cause the crash I was originally looking for. Removing the print message, it seems I can cause it again.
Since we're dealing with a deallocation/retain/release problem, can anyone tell me if it's possible that printing out this object is causing it to be referenced, thus sparing it from deallocation? And if so, what does that tell me about my original problem? Too many release's? Release too early?
If the call to NSLog is from a background thread, then that could well be changing the sequence of events. NSLog synchronizes writes to stderr in some way -- I am not sure exactly how, but it's not far-fetched to think that one consequence could be an alteration in your object's lifetime.
As to what that tells you about the original problem, well it sounds like it confirms Dave DeLong's diagnosis: you're attempting to use a stale pointer. Which in turn means either the bit of code making the call is not retaining appropriately, or some other bit is over-releasing.
In 10 years of Mac and iOS development, it never happened to me that NSLog did something bad to reference counts. That's all I can say for sure.
I get this message. The thing is, I want to be able to tell cocoa to just not send the notification if the object no longer exists. Is there a way to do that?
The broader picture:
I'm sending requests to a server, but while that request is going on, maybe the user has done something to destroy the object expecting the request. When the response comes back, the object that requested it is no longer around, so I just want to have the notification center not handle the message.
Right now, I'm retaining the object when it requests a message, and releasing it when it receives the response. This way, I don't send messages to deallocated instances. But if it never gets the response, then it may not be freed, which leads to memory leaks. Hence my reasoning for trying to gracefully handle messages to deallocated instances.
Any ideas?
There is no "failing gracefully" when you message a deallocated object.
An allocated object is backed by a bit of memory allocated on the heap. It may have many references to that allocation; many pointers that contain the address of said allocation. When the object is deallocated, all those pointers are still pointing to it unless explicitly reset to some other value. And, of course, once de-allocated that bit o' memory can be re-allocated.
That is to say that, no, there is no magic -- no efficient magic anyway [see NSZombie] -- for turning all pointers to a particular object into something that magically eats all messages without error.
In other words, you need to architect your app such that objects that are no longer viable are really no longer viable across all layers of your app.
As bbum says, you can't send messages to deallocated objects. It's simply invalid. There isn't even such a thing as a "deallocated object" — once an object is deallocated, it's just gone. It's not a thing anymore and doesn't exist anywhere. Its old bit pattern might remain, or an unrelated object might be put in its place, or absolute garbage — that's where the crashes come from, not some magical "deallocated object" handler.
The correct thing to do if you don't want an object to be sent notifications anymore is just to unregister it from receiving them.
If the object no longer exists and you don't want it to crash on sending a message to garbage (that is, if you have a pointer to a deallocated object and you send that pointer a message, resulting in a nasty crash), if you want to avoid that, set your pointer to nil after you release it. This signifies you are done with the object. Sending messages to nil is perfectly acceptable, but sending messages to pointed-at-garbage is not.
[iVar release];
iVar = nil; // done with this reference.
I have a crash taking place when an NSAutoreleasePool drains. Presumably the pool is trying to deallocate an object that has been prematurely released by another piece of code. The crash I have is in the midst of objc_msgSend as it is trying to send a message to an object that doesn't exist anymore.
Given the stack state, what tips/tricks/processes/gdb commands do I have at my disposal to get information about the object in question and/or the point at which the illegitimate deallocation took place?
If you have a hunch that it is a premature deletion, enable zombies to confirm your hypothesis and then debug what is going on. When you enable zombies, objects are not really destroyed, but set to a zombie state, which helps you to detect when they are accessed after they dealloc is called. Read more from NSZombieEnabled
The definitive article on this kind of crash: http://www.sealiesoftware.com/blog/archive/2008/09/22/objc_explain_So_you_crashed_in_objc_msgSend.html
If you use NSZombieEnabled you can at least figure out what class the object is.
I came across what appeared to be a crash in objc_msgSend. What was even stranger was application:didFinishLaunchingWithOptions: was not even getting reached before the so called crash occured!
In my case the crash turned out to be a breakpoint that I had inadvertantly set on a memory address that was getting called before any of my code was even reached.
After the hour or so of trying to figure this out, I unchecked the breakpoint, ran the code, face palmed and then continued my day pretending it had never happened…