Reputation: 45
When a selector is called in Objective-C, and the app crashes, resulting in the debug stack pointing to a selector, what is the cause of this? From what I understand, this happens as a result of a memory error. However, both the object I am sending the command to, and the parameter (an array) are valid. I can tell because these two objects reveal memory locations as well as other info when moused over in Xcode.
Since the trace ends at this selector, I am at a loss. I have never seen this error when the stack points to a selector with valid object parameters.
Furthermore, this selector is called frequently. It always deals with the same types of objects, and there is nothing to suggest abnormal behaviour before my crash.
This crash is infrequent, happening every 10 minutes or less.
Since I am a novice programmer, there is likely something wrong with the code inside the selector. Often I compare object pointers like so:
if (thisObject.pointerToSomeObject == nil) { //do stuff...
I am beginning to doubt this is proper Objective-C programming, but then again, the code works most of the time. Is there a corner case I am not aware of?
Additional Info: I am using cocos2d version 1.0.0, Xcode 4.1. Testing on the iPad simulator.
Any help is appreciated, even links to relevant debugging articles would be helpful.
EDIT
Developments:
A default debug thread pointing to a selector, with a bad access error can mean that the bad access is happening within that selector's execution. It is possible to turn on further debugging with NSZombies to find the exact line.
So, after turning on NSZombies, The problem is revealed in greater detail. (Thanks @Lou Franco for that bad access tutorial)
Now, what would cause:
if ([thisZombie target] == nil)
to evaluate NO, but throw a bad access when accessing an integer in [thisZombie target]
?
The target
is a pointer to an NSObject (zombified)
else {
int diffx = [thisZombie x] - [[thisZombie target] x];
// ^^ ----- bad access here
** EDIT 2 **
There must be something wrong with the syntax, or the short-circuit evaluation:
if (!thisZombie.target && thisZombie.leader && !thisZombie.leader.dead)
thisZombie.leader.dead stops the thread with: " * -[Zombie dead]: message sent to deallocated instance 0x2108f0"
I suppose I should mention that this game has "Zombies" which are not to be confused with the "NSZombie"
So, the program evaluates "thisZombie.target" as "true" but when I go to access "thisZombie.target.x" the program ceases execution.
Why?
EDIT 3
Hi Everyone, I'd like to thank you all again for your helpful comments and suggestions. I decided to solve this by completely changing how my zombies follow their leaders.
I still have no Idea what would cause evaluation as described above, but the answer is no longer required.
Upvotes: 0
Views: 3159
Reputation: 89172
I wrote this blog to help understand and debug EXC_BAD_ACCESS
http://loufranco.com/blog/files/Understanding-EXC_BAD_ACCESS.html
In order of easiness
Run a Build and Analyze -- do you get a clean build? Look at what it's saying, but you can ignore leak problems for now -- look for problems of sending messages to released objects
Run with NSZombiesEnabled -- this makes objects never deallocate, and then complain if a message is sent to an object with retainCount of 0.
Enable Guard Malloc and then use the special GDB commands to inspect the integrity of the heap. The problem is that you need to step through and do this before you crash to find the real problem. It might crash somewhere else closer to your problem though
EDIT: based on your information above. You deallocated thisZombie.leader
, but you didn't set it to nil. Probably, you forgot to have thisZombie retain it, so it got deallocated early.
This could be tricky if there are circular references (zombies point to leaders and leaders point back). If it isn't circular, remember to retain any object you set a property to point to (automatic if you use retained properties and remember to always use the property syntax)
Upvotes: 1
Reputation: 1655
You need to check if your array or some other variable has been initialized or not. Using NSLog or breakpoints can help you find the exact variable causing this error. In case it is because of some parameter passed or returned, then the reason suggested by Max is also valid.
It would help to find the exact problem if you can post the code.
Upvotes: 0
Reputation: 16719
Even if object reveal memory location doesn't mean it is valid. It maybe freed and you're just holding pointer to the garbage.
Upvotes: 0