Teleporting objects in 64bit Release mode (OSX)

Discuss any Chipmunk bugs here.
josephg
Posts: 29
Joined: Sat Dec 24, 2011 4:54 am
Contact:

Teleporting objects in 64bit Release mode (OSX)

Post by josephg »

I have a strange problem - if I compile libChipmunk.a in Release mode / 64bit, objects randomly teleport around, change size, and rotate. The problem goes away if I bump it back to debug mode or run the 32bit code.

I can reproduce the problem by just running any of the demos except for the logo smash.

For some reason. In my own application, the problem seems to go away if I put all of my objects in the same group (ie, turn off collisions) or replace my polygons with boxes.

I built this executable by just running 'xcodebuild' in the xcode/ directory of chipmunk:
http://dl.dropbox.com/u/2494815/ChipmunkDemo.app.zip
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Teleporting objects in 64bit Release mode (OSX)

Post by slembcke »

Bwa! What the crap? So the weird thing to me is that 95% of Chipmunk's development is done using 64 bit OSX. I usually only run other versions occasionally to test that I didn't break something.

I sort of suspect that it's using doubles for the physics and then sending floats to OpenGL. It seems like some of the demos actually run fine, but are rendered incorrectly. Did you redefine some of the types using preprocessor defines only when building the lib perhaps? Did you make any changes at all to the project or build settings? What version or Git revision did you build from, and what OS/Xcode combo are you using?
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
josephg
Posts: 29
Joined: Sat Dec 24, 2011 4:54 am
Contact:

Re: Teleporting objects in 64bit Release mode (OSX)

Post by josephg »

I know! And howcome swapping my polygons (pentagons) to boxes made the problem go away??

I ran into the problem first with graphics turned off. I made two polygons (with plenty of space between them) and left them spinning. After they'd spun 7.1 radians their angles start violently diverging. Their angle diverged at the same point in their rotation regardless of the speed they were spinning, and the problem goes away if I turn off collisions. I suspect some of the collision code is misfiring, although while their position and angle changes, their velocity and angular velocity remained neutral. I didn't look any closer at it after I realised I can just use the debug build of the library for now.

I didn't redefine anything. I did a clean git clone & xcodebuild to verify the problem:
https://gist.github.com/2382926
If you just hit cmd+B / cmd+R from xcode, by default it builds & runs in debug mode, and that works fine. As I said, it only shows up if you build it in release mode.

I'm using xcode 4.3 (which is apparently using clang version 3.1).

I assume you can't reproduce the problem on your end? I could try doing a binary search through the compiler flags to see whats triggering it, though if its a wacky memory alignment problem that might not tell us much.
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Teleporting objects in 64bit Release mode (OSX)

Post by slembcke »

Hmm. Yeah, my best guess is still that it's a type/memory size issue. Where one part is using floats and another doubles. IIRC, as long as the doubles are within some certain range they stay valid floats as well, but I don't really remember. I haven't upgraded to Xcode 4.3 yet (or Lion for that matter... Ugh) as I've been in the middle of an "almost done" project for months now. So I can't verify it at the moment.

Just a hunch, in chipmunk_types.h, try replacing this:

Code: Select all

#ifdef __APPLE__
   #import "TargetConditionals.h"
#endif

#if (TARGET_OS_IPHONE == 1) || (TARGET_OS_MAC == 1) && (!defined CP_USE_CGPOINTS)
	#define CP_USE_CGPOINTS 1
#endif

#if CP_USE_CGPOINTS == 1
	#if TARGET_OS_IPHONE
		#import <CoreGraphics/CGGeometry.h>
	#elif TARGET_OS_MAC
		#import <ApplicationServices/ApplicationServices.h>
	#endif
	
	#if defined(__LP64__) && __LP64__
		#define CP_USE_DOUBLES 1
	#else
		#define CP_USE_DOUBLES 0
	#endif
#endif

#ifndef CP_USE_DOUBLES
	// use doubles by default for higher precision
	#define CP_USE_DOUBLES 1
#endif
With just #define CP_USE_DOUBLES 1.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
josephg
Posts: 29
Joined: Sat Dec 24, 2011 4:54 am
Contact:

Re: Teleporting objects in 64bit Release mode (OSX)

Post by josephg »

No luck.

I did a binary search over the space of compile-time options and (bad news) the relevant option is -O3. The problem goes away if I turn off optimization (or drop down to -O1). Switching back to gcc also fixes the problem.

If you can find a copy of clang 3.1 for snow leopard, you should be able to make your own broken chipmunk library like this:

Code: Select all

sephsmac:src josephg$ clang -c *.c constraints/*.c -I../include/chipmunk/ -O2
sephsmac:src josephg$ libtool -static -arch_only x86_64 *.o -o libChipmunk.a
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Teleporting objects in 64bit Release mode (OSX)

Post by slembcke »

Hmm. I wonder if it's another Clang bug. :-\

There was a known bug in Clang 2.something that caused Chipmunk to run incorrectly. Actually just code that did sqrt(x*x + y*y). That's not common at all right? -_- I wouldn't be completely surprised if it was broken again.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
shoggoth
Posts: 4
Joined: Sat Aug 13, 2011 6:56 am
Contact:

Re: Teleporting objects in 64bit Release mode (OSX)

Post by shoggoth »

Hai there

Just wondered if there'd been any progress on this as I have a similar problem with 64-bit release mode OSX only. The dynamics work OK but there are no collisions at all. Switching to debug build or 32 bit build or iOS build and all the collisions return.

Was happening in 6.0.2, upgraded to 6.0.3 but the same problem.

Using XCode 4.3.2 with Apple LLVM compiler 3.1.

As joseph said, switching the optimisation down to -O1 makes the collisions work correctly.

Hope this helps.

Cheers
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Teleporting objects in 64bit Release mode (OSX)

Post by slembcke »

Unfortunately no, I looked into it a little bit before reinstalling Xcode 4.2 so I could actually get close to finishing Chipmunk 6.1. Like Clang 2.1, Clang 3.1 seems to be a buggy pile of garbage that was rushed out the door. The armv6 code generator often spits out assembly code that can't even be assembled... (Maybe that's Apple's subtle way of telling people to stop supporting the iPhone 3G)

I'm almost certain that it's caused by a compiler bug, which would mean debugging the assembly code or randomly poking around until a fix is found. I don't want to hold up the 6.1 release too long if it really is a compiler bug, so I might have to postpone a workaround until later.
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: Teleporting objects in 64bit Release mode (OSX)

Post by slembcke »

Hmm. So this got my curiosity piqued again. It only happens when using doubles, compiled with optimizations on x86-64. Digging a bit further, the rotation vectors on the bodies are garbage.

This is a little odd since the only place in the entire Chipmunk source where it should be set looks like this:

Code: Select all

static inline void
setAngle(cpBody *body, cpFloat angle)
{
	body->a = angle;//fmod(a, (cpFloat)M_PI*2.0f);
	body->rot = cpvforangle(angle);
}
cpvforangle() is similarly simple:

Code: Select all

cpVect
cpvforangle(const cpFloat a)
{
	return cpv(cpfcos(a), cpfsin(a));
}
So I added a print statement to cpvforangle() to see what was what.

Code: Select all

cpVect
cpvforangle(const cpFloat a)
{
	cpVect v = cpv(cpfcos(a), cpfsin(a));
	printf("v: %s\n", cpvstr(v));
	return v;
}
Not only does it print the correct value, but it causes it to return the correct value as well... Comment out the printf() and it breaks again. Now time to dig into the assembly or see if I can do a magical incantation of alternative but equivalent syntax.

-_-

Dear Apple, please test your damn compilers.
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: Teleporting objects in 64bit Release mode (OSX)

Post by slembcke »

Ok! That was easy to verify. It immediately makes a tail call to sin() and doesn't call cos() at all. Also, I'd have to look up the ABI, but I thought returning a struct is supposed to write to a pointer passed in on the stack.

https://gist.github.com/2712996

I've been unsuccessful so far at tricking Clang into generating the right code. It keeps unsmarting me. -_-
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 7 guests