calling space.bodies crashes

Discuss any Chipmunk bugs here.
Post Reply
omnius
Posts: 16
Joined: Sat Nov 26, 2011 1:09 pm
Contact:

calling space.bodies crashes

Post by omnius »

Seems like this shouldn't be possible under any circumstances, but I think it might be threading related. I'm not deliberately setting up any threads, and the crash is on Thread 1, but the crash reminds me of thread crashes I've seen in the past (referencing variables which are being changed elsewhere).

I'm asking my "space" to remove a body, using:

Code: Select all

		if ( [space.bodies containsObject:self.body] ) {
			[space addPostStepRemoval:self.body];
		}
		[space addPostStepRemoval:self.shape];
It crashes on the call to space.bodies, with only cp and Chipmunk code after that call.

First stack is
0x000b5cae <+0042> mov r0, r6

calls to
cpSpaceEachBody
cpSpaceUnlock
cpHashSetEach
cpSpacePostStepCallbackSetlter
postStepPerform
NSObject performSelector
ChipmunkSpace remove:
ChipmunkSpace removeFromSpace:
ChipmunkSpace removeShape:
cpSpaceRemoveShape
cpBBTreeRemove
SubtreeRemove

The main curiosity is, why on earth is querying bodies leading to a remove? Aha, but if you look at my code, you'll see that I am in fact removing a body and a shape, in a postStepRemoval.

Therefore, my theory is that the callback is mutating the array while that array is being queried in a close subsequent call (the code I posted above can get called many times in rapid succession).

I am going to work on my end to see if I can't lock the code, but I think the underlying issue is that accessing bodies is not safe when a postStepRemoval has been queued but not completed. That strikes me as a bug. Apologies if I am wrong.
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: calling space.bodies crashes

Post by slembcke »

Hmm, not sure what to tell you without seeing more code, but I can explain that stack trace to you. Chipmunk spaces are not thread safe at all, so it's very possible that could be causing the problems.

So you can't modify a space while a callback (called from cpSpaceStep), callback based queries (like cpSpaceSegmentQuery) or iterator (cpSpaceEachBody) is running. Each time Chipmunk enters one of those functions it increments the lock count on the space, and each time it exits one of them it decrements the lock count. If the lock count is decremented to 0, it knows that it's now safe to remove objects and runs the post-step callbacks that have been queued. If you have multiple calls to cpSpaceStep(), queries or iterators running at the same time on the same space on different threads, that can be VERY bad. space.bodies calls cpSpaceEachBody to build the list of bodies.

From the stack trace, you have a post-step callback queued up when space.bodies exits. So when it unlocks the space it's running that callback. That callback was either added when the space was not locked at some point before you called space.bodies or added on a second thread while space.bodies was executing. If you have the Chipmunk library compiled in debug mode, it will give you warnings about adding post-step callbacks when the space is not locked. If you use the iphonestatic.command script to build your library, it's only compiled in debug mode on the simulator however.

My personal advice is never ever to use threads unless you have a really good reason, something that is trivially parallelizable and know exactly which libraries you use that are thread safe. Threading related bugs are the hardest to debug issues that I've ever dealt with. They happen randomly, can be nearly impossible to reproduce and generally make it look like the problem is caused by something else in the program. As the old saying goes, "If you think you have a problem that you can solve using threads, now you have two problems."
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
omnius
Posts: 16
Joined: Sat Nov 26, 2011 1:09 pm
Contact:

Re: calling space.bodies crashes

Post by omnius »

I was only surmising that threading was the issue - I don't think that it is after reading your feedback (thank you for your speedy and thoughtful responses, as always).

I think the almost-certain culprit is that I was in fact calling addPostStepRemoval from outside the space's event loop, so the space was not "locked".

The reason I did this was because I was initially using -remove: and getting intermittent crashes because the removal was could happen during a collision step, so I switched to addPostStepRemoval and never looked back (it worked till today). This was clearly in error - at least as far as "not the way the kit is designed" is an error.

Personally, I hoped to avoid having to distinguish between when to use "remove" and "addPostStepRemoval". I just want to tell the space to remove a shape/body and have the space figure it out. I saw on a search that there is some kind of smartAdd method but I don't see it in the docs.

My recommendation (if not already implemented): make -safeAdd: and -safeRemove: operations. If the space is locked, call remove:; if it's locked, call addPostStepRemoval:. The technical implementation details should be insulated from the user (stated with all the certainty of someone who's on week 2 of using the system).
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: calling space.bodies crashes

Post by slembcke »

Hmm. I'm not quite sure sure why that would cause a crash though unless it was causing it to retain a dangling pointer somehow.

As far as safeAdd/safeRemove, look at smartAdd/smartRemove. ;) I was going to mention that, but forgot. They should be perfectly safe to call all the time, inside a callback or not. Just keep in mind that they create post-step callbacks with the object you are removing as the key. That's why I didn't change the default add/remove implementations to do it for you.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
omnius
Posts: 16
Joined: Sat Nov 26, 2011 1:09 pm
Contact:

Re: calling space.bodies crashes

Post by omnius »

Is smartAdd in the ObjC bridge? I just searched and don't see it. That would be a very fast update cycle if it's already improved since I downloaded it 2 weeks ago.
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: calling space.bodies crashes

Post by slembcke »

Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
Post Reply

Who is online

Users browsing this forum: No registered users and 4 guests