Page 1 of 1

cpSpaceRemoveShape / cpSpaceRemoveBody order sleeping compon

Posted: Sat Sep 25, 2010 5:40 am
by pat
Hey, I've been getting a exception/crash in my program. It seems to be related to the order of removal of shape, bodies, and bodies resting on bodies.

I'm not using cpShape_New/ cpBodyNew functions, and allocating things with my own with wrapper structs holding a cpBody / cpShape (non pointer). So i'm not relying on cpSpaceFreeChildren.

The crash occurs when the game is shutting down a level (removing stuff) and seems to only happen when i have a sleeping body. It happens in cpSpaceRemoveShape where then it calls cpBodyActivate and somewhere in

Code: Select all

static inline cpBody *
componentNodeRoot(cpBody *body)
where cpBody *parent gets set to like 0xFEFEFEFE ( maybe not that but it looked like a freed address ). So that makes me think its a removal order thing.


actually just now going over this i took a look at cpSpaceFreeChildren and notice that it starts off with

Code: Select all

	cpArray *components = space->sleepingComponents;
	while(components->num) cpBodyActivate((cpBody *)components->arr[0]);
putting that code infront of my level shutdown function seems to have fixed it.

So i guess I'm wondering if that's the best approach?

Also i'm removing the shapes from the space prior to the body i figure that's how to go about it. But maybe that's the problem?

Re: cpSpaceRemoveShape / cpSpaceRemoveBody order sleeping compon

Posted: Thu Sep 30, 2010 4:27 am
by pat
So i guess that didn't fix it. But it happens less now.

It seems like activating the node doesn't clear out parent?

Heres the call stack, of where the crash begins as far as i can tell
Image

Re: cpSpaceRemoveShape / cpSpaceRemoveBody order sleeping compon

Posted: Thu Sep 30, 2010 11:06 am
by slembcke
Ok. Sorry it took me a while to get back to you on this. Today is entirely a Chipmunk work day however. \o/

The reason why cpSpaceFreeChildren() wakes everything up is so that the bodies and shapes lists get reset back to normal. Sleeping bodies are removed from the bodies list, and shapes are moved between the active/static hashes. The easiest way to reset all of that was just to wake everything up.

Activating a group of sleeping bodies should definitely should have been clearing out body.node.parent. I must have missed that. Normally it wouldn't matter as it would get cleared the next time cpSpaceStep() is called, but I could see how this would cause problems when finalizing things. This should be fixed in trunk.

I'm guessing what was happening is that you are waking them all up, then doing something like this:

Code: Select all

for each object {
  cpSpaceRemoveShape(object.shape)
  cpSpaceRemoveBody(object.body)
  free(object)
}
Which is correct, but means that it might be attempting to activate the root body for a sleeping group of bodies that has already been freed because I forgot to null out body.node.parent.

Anyway. It should be fixed now.

Re: cpSpaceRemoveShape / cpSpaceRemoveBody order sleeping compon

Posted: Thu Sep 30, 2010 12:18 pm
by pat
\o/

I'll give it a shot, I tried doing it on my own by checking if the parent was in the bodies array or not. but then i ended up getting things in the body array twice.

And yea your right about the whats happening, the body is a data member, not a pointer. So yea it gets freed with the object (after getting removed appropriately of course)

Thanks for taking the time to look at this though, really appreciate it.

Re: cpSpaceRemoveShape / cpSpaceRemoveBody order sleeping compon

Posted: Fri Oct 01, 2010 10:19 am
by pat
Just a follow up, This fixed it. Though now i can't point query sensor shapes lol, i saw the other thread though. Really only need this for editor, so when in editor mode ill just set things that should be sensors as not sensors.

Re: cpSpaceRemoveShape / cpSpaceRemoveBody order sleeping compon

Posted: Fri Oct 01, 2010 1:36 pm
by slembcke
I was hoping that I was the only one that did that. Also... I just realized that I made cpSpacePointQuery() skip sensors instead of just cpSpacePointQueryFirst(). Fixed that.

Anyway, its easy enough to make a point query first function that doesn't skip sensors.

Code: Select all

static void rememberLastPointQuery(cpShape *shape, cpShape **outShape){
	*outShape = shape;
}

cpShape *
cpSpacePointQueryFirst(cpSpace *space, cpVect point, cpLayers layers, cpGroup group)
{
	cpShape *shape = NULL;
	cpSpacePointQuery(space, point, layers, group, (cpSpacePointQueryFunc)rememberLastPointQuery, &shape);
	
	return shape;
}

Re: cpSpaceRemoveShape / cpSpaceRemoveBody order sleeping compon

Posted: Fri Oct 01, 2010 6:46 pm
by pat
Cool, I'll use that then in the editor. Thanks