AndresTraks / BulletSharpPInvoke

.NET wrapper for the Bullet physics library using Platform Invoke
http://andrestraks.github.io/BulletSharp/
150 stars 97 forks source link

Native code crash inside btRigidBody_btRigidBodyConstructionInfo_new2 #57

Open smlehbleh opened 5 years ago

smlehbleh commented 5 years ago

Hi, I'm getting a crash when I construct a RigidBodyConstructionInfo with the localInertia value value passed in.

From looking at: libbulletc/src/btRigidBody_wrap.cpp, it looks like that last parameter is coming in as a pointer but the C# wrapper isn't using ref.

I am for now working around it by avoiding that constructor and setting localInertia with the property interface.

AndresTraks commented 5 years ago

It should work whether or not the wrapper class uses ref.

Did you compile libbulletc yourself? I haven't tested extensively except for x64 and the MSVC compiler.

I suspect that there is something wrong with memory alignment. If Bullet is compiled with SSE support (BT_USE_SSE defined), then SSE instructions are used to copy values from one place to another. SSE instructions require both source and destination memory to be aligned to 16 bytes.

.NET does not guarantee that the localInertia parameter is aligned to 16 bytes in memory, so libbulletc copies the parameter to a temporary aligned variable (conversion.h). The destination will be btRigidBodyConstructionInfo, which should also be aligned to 16 bytes with the ALIGNED_NEW macro.

I'm not sure if the ALIGNED_NEW definition should have the BT_USE_SIMD_VECTOR3 condition. Can you try removing it in main.h?

...
#if defined(BT_USE_SSE)
#define ALIGNED_NEW(targetClass) ALIGNED_NEW_FORCE(targetClass)
...
smlehbleh commented 5 years ago

Hi Andres, Thanks for the response. I've tried commenting out the BT_USE_SIMD_VECTOR3 condition in main.h Unfortunately it doesn't fix it - also according to my git client, the end libbulletc dll was identical. I can't figure out where the BT_USE_SSE define is set/unset.

I am compiling libbulletc myself - i ran cmake on the libbulletc root, which generated a makefile which I just called - but I didn't specify any options so I'm not sure if its building with the correct defines.

I've just added some code which calls: btRigidBody_applyCentralForce and this suffers the same native crash.

AndresTraks commented 5 years ago

BT_USE_SSE is defined in bullet3\src\LinearMath\btScalar.h, but only if Bullet thinks that the compiler and the target platform support SSE.

There is this comment in btScalar.h:

//BT_USE_SSE_IN_API is enabled on Mac OSX by default, because memory is automatically aligned on 16-byte boundaries
//if apps run into issues, we will disable the next line
#define BT_USE_SSE_IN_API

If you are on a Mac, you could try commenting out that line. This should make Bullet use SSE internally, but disable SSE at the API boundary. I don't have an Apple environment available to test.

If that doesn't work, try forcing alignment in BulletSharp's main.h:

#if 1 // defined(BT_USE_SSE)
#define ALIGNED_NEW(targetClass) ALIGNED_NEW_FORCE(targetClass)
AndresTraks commented 5 years ago

There was an alignment fix in Bullet just before your issue: https://github.com/bulletphysics/bullet3/commit/448f0b8befb2f3c6ae2a5f59a5d39dce6841398f

Maybe that broke something. Or if you happen to have an older version of bullet3, maybe it fixed this problem.

thatcosmonaut commented 3 years ago

I can confirm this issue is still a problem on OSX. I tried all the solutions listed in this thread and none of them work, I get a native crash as soon as I call a Rigidbody method that takes a Vector3.

AndresTraks commented 3 years ago

I still don't have an OSX environment to develop on. Maybe you can get more detailed information with a debug build?

thatcosmonaut commented 3 years ago

Unfortunately mono native traces are not particularly detailed... I will try to rig up an xcode project at some point and see if the debugger can tell us anything.