Calling cpSpaceRemoveCollisionHandler while still in contact

Discuss any Chipmunk bugs here.

Calling cpSpaceRemoveCollisionHandler while still in contact

Postby Beernutts » Sun Jul 15, 2012 10:08 pm


I'm getting a crash when I remove a collision handler while still in contact with a object. Here's what happens.

I have this call:
cpSpaceAddCollisionHandler(pSpace, pShape1->collision_type,
OnCollision, NULL, NULL, OnSeparate, NULL);

After a while, when an object collides, for certain situations, I want to remove the callback for those 2 collision types, so I call:
cpSpaceRemoveCollisionHandler(pSpace, pShape1->collision_type,

Well, i get a crash when they separate, in
contactSetFilter(), at this line:
arb->handler->separate(arb, space, arb->handler->data);
as separate is now an invalid value: 0xabababab

Any suggestions? Is this an invalid situation and it shouldn't be allowed?

BTW, I'm using v5.3.4, so you'll probably suggest I upgrade, but I'd rather not at this point.

Posts: 10
Joined: Fri May 06, 2011 9:12 pm

Re: Calling cpSpaceRemoveCollisionHandler while still in con

Postby slembcke » Mon Jul 16, 2012 8:52 am

Ah. I was going to say, I've added specific logic to handle that, but I'm not sure at which version I did it without looking through a ton of change logs.

At the moment I don't have time to get you a fully working solution, but this is how the code works in the latest code. Basically instead of calling the separate callback directly by dereferencing the dangling pointer, it calls cpArbiterCallSeparate() instead. cpArbiterCallSeparate() looks up the handler again, and then calls it. So it safely handles the case where a handler is removed while a collision is active. I don't remember offhand how much work it would take to adapt it to Chipmunk 5.x (I haven't personally worked on that in almost a year now). You might need to change some of the types

Code: Select all
static inline cpCollisionHandler *
cpSpaceLookupHandler(cpSpace *space, cpCollisionType a, cpCollisionType b)
   cpCollisionType types[] = {a, b};
   return (cpCollisionHandler *)cpHashSetFind(space->collisionHandlers, CP_HASH_PAIR(a, b), types);

static inline void
cpArbiterCallSeparate(cpArbiter *arb, cpSpace *space)
   // The handler needs to be looked up again as the handler cached on the arbiter may have been deleted since the last step.
   cpCollisionHandler *handler = cpSpaceLookupHandler(space, arb->a->collision_type, arb->b->collision_type);
   handler->separate(arb, space, handler->data);
Can't sleep... Chipmunks will eat me...
Check out our latest projects! ->
User avatar
Site Admin
Posts: 4164
Joined: Tue Aug 14, 2007 7:13 pm

Re: Calling cpSpaceRemoveCollisionHandler while still in con

Postby Beernutts » Mon Jul 16, 2012 10:34 am

OK, I can probably throw a fix in there for that.

I actually may just bite the bullet and upgrade, as I need to also upgrade SFML, and I might do it all in one go.

Regardless, thanks for the help!
Posts: 10
Joined: Fri May 06, 2011 9:12 pm

Return to Bugs

Who is online

Users browsing this forum: No registered users and 1 guest