Crashes whenever calling [body data] (5.3.3 or 5.3.4)

Discuss any Chipmunk bugs here.
horseshoe7
Posts: 36
Joined: Fri Feb 19, 2010 11:58 am
Contact:

Crashes whenever calling [body data] (5.3.3 or 5.3.4)

Post by horseshoe7 »

I updated my cocos2D code to the latest branch (using Chipmunk 5.3.3) and the recent testing build of Objective-Chipmunk (5.3.4b ?). The first call to my updatePositionFunc and my app crashed. Before it worked ok so I'm trying to figure out what's wrong.

My code:

Code: Select all

static void
discUpdatePosition(cpBody *body, cpFloat dt)
{
	cpBodyUpdatePosition(body, dt);  // update disc stuff normally.
	
	Disc *me = (Disc*)[body->data data];  // THIS IS WHERE I GET A EXC_BAD_ACCESS
	if([me isFalling]){
		cpFloat oldPos = [me zPos];
		[me setZPos: oldPos + [me zVel]*dt];
	}
}
Thing is, one wouldn't suspect the chipmunk code, but rather data that doesn't exist. But before, it did exist and it did work ok. Furthermore, I can't place a breakpoint on that line to inspect that disc object because I get one of those debugger errors (cannot unwind past frame).

Any thoughts/suggestions?

EDIT: It's not just there. I think with respect to data pointers in general. I also had it freeze here:

Code: Select all

if ([mouseJoint.bodyB.data isKindOfClass:[FakeFingerSimple class]]) {
	[self disableFakeFinger];
}  
Is there something I haven't set up correctly? In XCode I just drag the Objective-Chipmunk folder into my project (noticing that that .a file gets added to the target's list of linked libraries, and also noticing that libChipmunk.a, presumably from the cocos2D source, is also in that list.)
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Crashes whenever calling [body data] (5.3.3 or 5.3.4)

Post by slembcke »

The bad access has to be happening when calling the method as the body pointer would have been dereferenced already in cpBodyUpdatePosition(). 99% of the time when that happens it means that you are calling a method on an object that has been deallocated. My best guess is that

The 5.3.3 update mostly just fixed a memory leak for spaces. It's possible that with that fixed

First things first, try running with "Enable Guard Malloc" option enabled from the "Run" menu in Xcode. This makes things run extremely slowly as it performs a lot of extra checks to help catch memory handling errors. If that doesn't give you anything helpful try adding a symbolic breakpoint for [ChipmunkBody dealloc] which you can add from the breakpoints window or just by typing "break [ChipmunkBody dealloc]" into the debugger console. This allows you to check when bodies are being deallocated and what the release call that triggered it.

Hopefully that helps. I'll keep looking in the Chipmunk source for an accidental release call, but I haven't found anything yet.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
horseshoe7
Posts: 36
Joined: Fri Feb 19, 2010 11:58 am
Contact:

Re: Crashes whenever calling [body data] (5.3.3 or 5.3.4)

Post by horseshoe7 »

A few things:

- Enable Guard malloc simply wouldn't 'engage' and wouldn't work. No idea why as I also have no idea what that is...

- The issue with the custom updatePosition function seemed to go away, leaving only the issue of a crash on that mouseJoint stuff. Looks like the bug you fixed was saving me before.

So, I changed my code to:

Code: Select all

- (void)ccTouchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
		
	if(mouseJoint){
		
		//[space remove:mouseJoint];  // HOW IT WAS.  Line below was crashing because mouseJoint wasn't retained anywhere. (I think)		

		if ([mouseJoint.bodyB.data isKindOfClass:[FakeFingerSimple class]]) {
			[self disableFakeFinger];
		}		
		[space remove:mouseJoint];  // doing this fixed it.
		
		mouseJoint = nil;  // TODO - before assigning to nil, might have to manage memory here differently.
	}
}
Regarding mouseJoints, I initialize him like this, assuming the touch touched the shape you wanna grab (is that correct?)

Code: Select all

mouseJoint = [space add:[ChipmunkPivotJoint pivotJointWithBodyA:mouseBody bodyB:body anchr1:cpvzero anchr2:cpvzero]];
I'm not retaining him anywhere, so as soon as I remove him from the space he gets released, correct? That would make my code there ok, right?

2 MORE THINGS:
The game is just unstable now. I often can't get my game started because upon entering the scene, the debugger stops everything and reports:

Code: Select all

Previous frame inner to this frame (gdb could not unwind past this frame)
If you could help me de-mystify what that actually implies, i'd be grateful.

Before that started happening, a collision separate callback was not firing which is critical to the gameplay. I'm still looking into this but the above issue is stopping me on that front.

I'm getting a little nervous that my game has just become totally unstable, and its errors of this nature that just have me feeling I'm WAY over my head.
horseshoe7
Posts: 36
Joined: Fri Feb 19, 2010 11:58 am
Contact:

Re: Crashes whenever calling [body data] (5.3.3 or 5.3.4)

Post by horseshoe7 »

So, without debugging capabilities, I've gone back to my tried and true method of NSLog to trace the code steps.

And it would appear the callback for collisions works, but in my collision handler, a post-step callback doesn't work:

Code: Select all

if (b.data == [game currentDisc]) {
	NSLog(@"DID I EVEN GET HERE?");  // yes I did.
	[space addPostStepCallback:[game controller] selector:@selector(shotTaken:) context:nil];  // this worked before but no more.
 
        // in the shotTaken method I put another NSLog, which didn't appear in the console output.               
}
Again, before the upgrades, this code worked, so I think we can eliminate things like typos, etc.
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Crashes whenever calling [body data] (5.3.3 or 5.3.4)

Post by slembcke »

First off, you are correct about the mouseJoint bug. The space's reference to the joint was the only thing keeping it from being deallocated. As soon as you removed it from the space, it was being deallocated. Keep in mind that while you can fix the crash by moving the [space remove:] call later, you are still storing the joint to an instance variable without retaning it. Always retain objects when storing a reference in a global or instance variable and release it when you set the variable to something else. Otherwise you are going to run into more issues like this where you end up freeing something by accident.

What do you mean it wouldn't engage? Any errors? Did you check Console.app for any logged error messages? Most days I want to strangle Xcode for being so buggy.

The update function issue probably didn't fix itself. Memory bugs aren't always consistent. Your program will only crash when it releases memory and returns the entire page it was located on back to the OS. Your application might reuse the same deallocated memory for another allocation instead. If that is the case the program might not crash at all until reading/writing to the wrong memory causes some other problem.

"Previous frame inner to this frame (gdb could not unwind past this frame)" GDB generally says this when the stack gets mangled and it can't figure out where the stack frames for functions are. obj_msg_send() isn't a normal compiler generated function for performance reasons. It doesn't play nicely with the stack, and crashing in it due to calling a method on a deallocated object often makes the debugger very confused. (I'm still guessing that is what the problem is.)

If objc_msgSend is the top function on the stack you can find out what method was called and on what object by tying this into the debugger console window:

Code: Select all

p (id)$edx
p (char*)sel_getName($eax)
This works only on the simulator though. I've never looked at how it works on ARM. Even if the debugger doesn't show that it crashed in obj_msgSend(), it's probably the case (from what you've said) and the console snippet should still work.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
horseshoe7
Posts: 36
Joined: Fri Feb 19, 2010 11:58 am
Contact:

Re: Crashes whenever calling [body data] (5.3.3 or 5.3.4)

Post by horseshoe7 »

Any ideas as to why the postStepCallback isn't working? That's really slowing me down now.
horseshoe7
Posts: 36
Joined: Fri Feb 19, 2010 11:58 am
Contact:

Re: Crashes whenever calling [body data] (5.3.3 or 5.3.4)

Post by horseshoe7 »

OK, first of all, the Enable Guard Malloc only works in the simulator, and then runs at like 4 FPS. I tried to see if it would tell me anything interesting w.r.t the postStepCallback issue, and it didn't seem to tell me anything.

that with the 'could not unwind previous frame' is an issue related to using the LLVM compiler, which my project isn't using, but by default the Cocos2D reference project is. (I refer to it rather than link the source directly). So I cracked that open, changed its compiler back to GCC 4.2 and now that issue goes away.

With that updatePosition issue, it was happening pretty much on the very first call to the very first object that uses it. So, I wasn't tracking the issue much before it went away. It could have been related to another issue that i was having that memory warnings when switching scenes were killing objects and sometimes crashing, sometimes not. When not, maybe this thing was a side effect, not sure.

but really the issue now is that with the postStepCallback. I'm thinking it must have something to do with the Chipmunk code, since I have no other way to debug it. I put an NSLog statement in the method it should be calling, and that never fires.
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Crashes whenever calling [body data] (5.3.3 or 5.3.4)

Post by slembcke »

horseshoe7 wrote:And it would appear the callback for collisions works, but in my collision handler, a post-step callback doesn't work:
That's my bad. There are 2 fixes in the 5.3.4 dev build I sent you. One was a performance issue with static bodies and the other was a minor issue I randomly stumbled into in addPostStepCallback.

The underlying Chipmunk post-step callbacks use a key value, and you can only register a callback once for each key. This prevents you from registering a removal for the same object more than once. The wrapper was using the target instead of the context object as the key. If you are registering more than one post-step callback using nil for the context, only the last callback will be called. Try passing the colliding shape as the context, you just need something unique.

I can't believe I missed this before but I never noticed because I rarely register more than one callback per step in my code. It also wasn't documented as well as it should be unless you read the C docs for cpSpaceAddPostStepCallback() too. :oops:
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Crashes whenever calling [body data] (5.3.3 or 5.3.4)

Post by slembcke »

horseshoe7 wrote:OK, first of all, the Enable Guard Malloc only works in the simulator, and then runs at like 4 FPS. I tried to see if it would tell me anything interesting w.r.t the postStepCallback issue, and it didn't seem to tell me anything.
I guess I never tried it for the device, not too surprising I guess. Yeah, guard malloc makes things super slow. It does memory checksumming and such to verify your memory usage. For a larger CoreData heavy application I was working on once, it took over 30 minutes just to load up my app to get past the splash screen. O_o
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
horseshoe7
Posts: 36
Joined: Fri Feb 19, 2010 11:58 am
Contact:

Re: Crashes whenever calling [body data] (5.3.3 or 5.3.4)

Post by horseshoe7 »

Great! That got it. Not only that, passing something in as a context actually saved me from getting it in the callback method. ;-)
Post Reply

Who is online

Users browsing this forum: No registered users and 3 guests