Core dump in libbulletjme.so when reading a saved RigidBodyControl

When trying to read a RigidBodyControl from a saved file I’m experimenting the next crash:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f9fc6112126, pid=16658, tid=140324194694912
#
# JRE version: Java(TM) SE Runtime Environment (8.0_77-b03) (build 1.8.0_77-b03)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.77-b03 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C  [libbulletjme.so+0x11c126]  btQuantizedBvh::reportAabbOverlappingNodex(btNodeOverlapCallback*, btVector3 const&, btVector3 const&) const+0x1c


---------------  T H R E A D  ---------------

Current thread (0x00007f9ff03f3000):  JavaThread "jME3 Main" [_thread_in_native, id=16703, stack(0x00007f9fc5b73000,0x00007f9fc5c74000)]

siginfo: si_signo: 11 (SIGSEGV), si_code: 1 (SEGV_MAPERR), si_addr: 0x0000000000000040

Registers:
RAX=0x0000000000000000, RBX=0x00007f9fc612da1c, RCX=0x00007f9fc5c71c00, RDX=0x00007f9fc5c71c10
RSP=0x00007f9fc5c71ae0, RBP=0x00007f9fc5c71b20, RSI=0x00007f9fc5c71b50, RDI=0x0000000000000000
R8 =0x00007f9fc5c71b68, R9 =0x00007f9fc5c71b6c, R10=0x0000000000000018, R11=0x00007f9ff6004648
R12=0x0000000000000000, R13=0x00007f9fb4d809d8, R14=0x00007f9fc5c71ea0, R15=0x00007f9ff03f3000
RIP=0x00007f9fc6112126, EFLAGS=0x0000000000010202, CSGSFS=0x0000000000000033, ERR=0x0000000000000004
  TRAPNO=0x000000000000000e

Top of Stack: (sp=0x00007f9fc5c71ae0)
0x00007f9fc5c71ae0:   00007f9fc5c71c00 00007f9fc5c71c10
0x00007f9fc5c71af0:   00007f9fc5c71b50 0000000000000000
0x00007f9fc5c71b00:   00007f9fc5c71c60 00007f9fc5c71b50
0x00007f9fc5c71b10:   00007f9fc612da1c 0000000000000000
0x00007f9fc5c71b20:   00007f9fc5c71bb0 00007f9fc612da6f
0x00007f9fc5c71b30:   00007f9fc5c71c00 00007f9fc5c71c10
0x00007f9fc5c71b40:   00007f9fc5c71c60 00007f9f391d2ea0
0x00007f9fc5c71b50:   00007f9fc63c6a90 00007f9f391d5fe0
0x00007f9fc5c71b60:   00007f9fc5c71c60 00007f9fc60258f7
0x00007f9fc5c71b70:   00000000dd5e0b6b 00007f9fc5c71c00
0x00007f9fc5c71b80:   dd5e0b6bc5c71d20 dd5e0b6bdd5e0b6b
0x00007f9fc5c71b90:   dd5e0b6bdd5e0b6b 00000000dd5e0b6b
0x00007f9fc5c71ba0:   00007f9fc5c71be8 00007f9fc612da1c
0x00007f9fc5c71bb0:   00007f9fc5c71cf0 00007f9fc6030968
0x00007f9fc5c71bc0:   0000000000000000 0000000000000000
0x00007f9fc5c71bd0:   00007f9fc5c71d20 00007f9f391d2ea0
0x00007f9fc5c71be0:   0000000000000000 5d5e0b6b5d5e0b6b
0x00007f9fc5c71bf0:   00007f9fb4d80900 0000000000000000
0x00007f9fc5c71c00:   5d5e0b6b5d5e0b6b 000000005d5e0b6b
0x00007f9fc5c71c10:   dd5e0b6bdd5e0b6b 00000000dd5e0b6b
0x00007f9fc5c71c20:   000000003f800000 0000000000000000
0x00007f9fc5c71c30:   3f80000000000000 0000000000000000
0x00007f9fc5c71c40:   0000000000000000 000000003f800000
0x00007f9fc5c71c50:   0000000000000000 0000000000000000
0x00007f9fc5c71c60:   00007f9fc63c4310 0000000000000000
0x00007f9fc5c71c70:   0000000000000000 000000003f800000
0x00007f9fc5c71c80:   0000000000000000 3f80000000000000
0x00007f9fc5c71c90:   0000000000000000 0000000000000000
0x00007f9fc5c71ca0:   000000003f800000 0000000000000000
0x00007f9fc5c71cb0:   0000000000000000 3f800000dd5e0b6b
0x00007f9fc5c71cc0:   0000000000000000 00007f9f00000000
0x00007f9fc5c71cd0:   00007f9fc5c71d30 00007f9fb4d809d8 

Instructions: (pc=0x00007f9fc6112126)
0x00007f9fc6112106:   ff c9 c3 90 55 48 89 e5 48 83 ec 40 48 89 7d d8
0x00007f9fc6112116:   48 89 75 d0 48 89 55 c8 48 89 4d c0 48 8b 45 d8
0x00007f9fc6112126:   0f b6 40 40 84 c0 0f 84 d0 00 00 00 48 8b 55 c8
0x00007f9fc6112136:   48 8d 75 e0 48 8b 45 d8 b9 00 00 00 00 48 89 c7 

Register to memory mapping:

RAX=0x0000000000000000 is an unknown value
RBX=0x00007f9fc612da1c: <offset 0x137a1c> in /home/NemesisMate/jmonkeyprojects/BasicGame/libbulletjme.so at 0x00007f9fc5ff6000
RCX=0x00007f9fc5c71c00 is pointing into the stack for thread: 0x00007f9ff03f3000
RDX=0x00007f9fc5c71c10 is pointing into the stack for thread: 0x00007f9ff03f3000
RSP=0x00007f9fc5c71ae0 is pointing into the stack for thread: 0x00007f9ff03f3000
RBP=0x00007f9fc5c71b20 is pointing into the stack for thread: 0x00007f9ff03f3000
RSI=0x00007f9fc5c71b50 is pointing into the stack for thread: 0x00007f9ff03f3000
RDI=0x0000000000000000 is an unknown value
R8 =0x00007f9fc5c71b68 is pointing into the stack for thread: 0x00007f9ff03f3000
R9 =0x00007f9fc5c71b6c is pointing into the stack for thread: 0x00007f9ff03f3000
R10=0x0000000000000018 is an unknown value
R11=0x00007f9ff6004648: <offset 0xfb5648> in /home/NemesisMate/jmonkeyplatform/jdk/jre/lib/amd64/server/libjvm.so at 0x00007f9ff504f000
R12=0x0000000000000000 is an unknown value
R13={method} {0x00007f9fb4d809d8} 'setLocalScaling' '(JLcom/jme3/math/Vector3f;)V' in 'com/jme3/bullet/collision/shapes/CollisionShape'
R14=0x00007f9fc5c71ea0 is pointing into the stack for thread: 0x00007f9ff03f3000
R15=0x00007f9ff03f3000 is a thread

And it continues with the java stack trace:

Stack: [0x00007f9fc5b73000,0x00007f9fc5c74000],  sp=0x00007f9fc5c71ae0,  free space=1018k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C  [libbulletjme.so+0x11c126]  btQuantizedBvh::reportAabbOverlappingNodex(btNodeOverlapCallback*, btVector3 const&, btVector3 const&) const+0x1c
C  [libbulletjme.so+0x137a6f]  btBvhTriangleMeshShape::processAllTriangles(btTriangleCallback*, btVector3 const&, btVector3 const&) const+0x53
C  [libbulletjme.so+0x3a968]  btTriangleMeshShape::localGetSupportingVertex(btVector3 const&) const+0x10c
C  [libbulletjme.so+0x3a545]  btTriangleMeshShape::recalcLocalAabb()+0x8f
C  [libbulletjme.so+0x3a699]  btTriangleMeshShape::setLocalScaling(btVector3 const&)+0x33
C  [libbulletjme.so+0x137b16]  btBvhTriangleMeshShape::setLocalScaling(btVector3 const&)+0x78
C  [libbulletjme.so+0xa6d2f]  Java_com_jme3_bullet_collision_shapes_CollisionShape_setLocalScaling+0x9b
j  com.jme3.bullet.collision.shapes.CollisionShape.setLocalScaling(JLcom/jme3/math/Vector3f;)V+0
j  com.jme3.bullet.collision.shapes.CollisionShape.setScale(Lcom/jme3/math/Vector3f;)V+15
j  com.jme3.bullet.collision.shapes.MeshCollisionShape.createShape(Z)V+103
j  com.jme3.bullet.collision.shapes.MeshCollisionShape.read(Lcom/jme3/export/JmeImporter;)V+131
J 1367 C1 com.jme3.export.binary.BinaryImporter.readObject(I)Lcom/jme3/export/Savable; (347 bytes) @ 0x00007f9fe105643c [0x00007f9fe1054b20+0x191c]
J 1358 C1 com.jme3.export.binary.BinaryInputCapsule.readSavable(Ljava/lang/String;Lcom/jme3/export/Savable;)Lcom/jme3/export/Savable; (111 bytes) @ 0x00007f9fe105046c [0x00007f9fe104fa60+0xa0c]
j  com.jme3.bullet.collision.PhysicsCollisionObject.read(Lcom/jme3/export/JmeImporter;)V+38
j  com.jme3.bullet.objects.PhysicsRigidBody.read(Lcom/jme3/export/JmeImporter;)V+2
j  com.jme3.bullet.control.RigidBodyControl.read(Lcom/jme3/export/JmeImporter;)V+2
J 1367 C1 com.jme3.export.binary.BinaryImporter.readObject(I)Lcom/jme3/export/Savable; (347 bytes) @ 0x00007f9fe105643c [0x00007f9fe1054b20+0x191c]
j  com.jme3.export.binary.BinaryImporter.load(Ljava/io/InputStream;Lcom/jme3/export/ReadListener;Ljava/io/ByteArrayOutputStream;)Lcom/jme3/export/Savable;+631
j  com.jme3.export.binary.BinaryImporter.load(Ljava/io/InputStream;)Lcom/jme3/export/Savable;+4
j  com.jme3.export.binary.BinaryImporter.load(Lcom/jme3/asset/AssetInfo;)Ljava/lang/Object;+17
j  com.jme3.asset.DesktopAssetManager.loadLocatedAsset(Lcom/jme3/asset/AssetKey;Lcom/jme3/asset/AssetInfo;Lcom/jme3/asset/AssetProcessor;Lcom/jme3/asset/cache/AssetCache;)Ljava/lang/Object;+21
j  com.jme3.asset.DesktopAssetManager.loadAsset(Lcom/jme3/asset/AssetKey;)Ljava/lang/Object;+189
j  com.jme3.asset.DesktopAssetManager.loadAsset(Ljava/lang/String;)Ljava/lang/Object;+9

If I’m not wrong, the problem comes when in MeshCollisionShape.class the read method tries to set the native scale:

private void createShape(boolean buildBvt) {
    this.meshId = NativeMeshUtil.createTriangleIndexVertexArray(this.triangleIndexBase, this.vertexBase, this.numTriangles, this.numVertices, this.vertexStride, this.triangleIndexStride);
    Logger.getLogger(this.getClass().getName()).log(Level.FINE, "Created Mesh {0}", Long.toHexString(this.meshId));
    this.objectId = createShape(memoryOptimized, buildBvt, this.meshId);
    Logger.getLogger(this.getClass().getName()).log(Level.FINE, "Created Shape {0}", Long.toHexString(this.objectId));
    this.setScale(this.scale);
    this.setMargin(this.margin);
}

The saved scale is: (2.813861, 2.813861, 2.3507693), or at least that is what I print just before writing it to file. I’m not sure what can be causing the crash.

Anyone has any idea about what can be the root cause of the crash?, thanks in advance.

Note: It works for lots of physics objects but this one.
Note: the scale printing is done with physicsControl.getCollisionShape().getScale().

It doesn’t support scaling :frowning: you have this error when your scale is not 1,1,1

Well maybe there is a difference between setScale and setLocalScaling?
Apart from that what you write as scale does not actually help, maybe the import is broken so that the Scale Value points to null (For this, com.jme3.bullet.collision.shapes.CollisionShape.setLocalScaling would be the best bet, maybe you can set a breakpoint there?).

Apart from that the conversation to btVector could be flawed and also jme doesn’t like non-uniform scaling either, so maybe it works when you adjust your z component

Edit: [quote=“javasabr, post:2, topic:37883”]
It doesn’t support scaling :frowning: you have this error when your scale is not 1,1,1
[/quote]
Bullet does not support scaling? In that case maybe we should throw an Exception there

I had the same exception when I have a scale which isn’t 1,1,1

What jme version? At least one has a bug in the save and write stuff.

I can reproduce this issue on master branch of jME.

if you make a switch to jbullet for the testing, what happens there?
Also, can you create me a simple testcase? I will take a look then.

Well, the strange thing is that it doesn’t crash if it isn’t read from a file. And about not being supported… I would say it is working for me in many cases, maybe Is just my imagination?? O.o, I’ll check it out.

I’m working on supporting working with physics in my Editor now and your issue is easy to reproduce for me on master branch.

1 Like

Someone has offered to look into it if someone else posts a test case. Someone should post a test case… since it’s apparently easy to create one.

When dividing up the work between people who work for free, it’s important to let the work trickle down to the folks who can do it. So since anyone (nearly) can create a test case then they should. Then the ‘subject matter expert’ can focus his time on the actual problem rather than wasting time recreating test cases that anyone could do.

Plus, there is always the chance (not in this case but in 99% of the cases) that it’s a user error and can be spotted in the test case… saving a super amount of time.

1 Like

I’m sorry, I though @javasabr was creating the test-case as he seems pretty familiar with the bug.

Internally, setScale is calling to native setLocalScaling so I don’t think so.[quote=“javasabr, post:4, topic:37883”]
I had the same exception when I have a scale which isn’t 1,1,1
[/quote]

That seems to be true, but only if the scale is loaded from a file.

Here the test-case:

public class BulletSigsevOnScaleTestCase extends SimpleApplication {
    
    public static void main(String[] args) {
        BulletSigsevOnScaleTestCase app = new BulletSigsevOnScaleTestCase();
        app.start();
    }
    
    @Override
    public void simpleInitApp() {
        Box box = new Box(1, 1, 1);
        Geometry geom = new Geometry("box", box);
        
        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        mat.setColor("Color", ColorRGBA.Blue);
        
        geom.setMaterial(mat);
        
        
        File saveFile = new File(System.getProperty("user.home") + File.separatorChar + "testRigidBody.j3o");
        
        CollisionShape collisionShape = CollisionShapeFactory.createMeshShape(geom);
        RigidBodyControl rigidBodyControl = new RigidBodyControl(collisionShape, 0f);
        
        collisionShape.setScale(Vector3f.UNIT_XYZ.mult(2f));
        
        try {
            BinaryExporter.getInstance().save(rigidBodyControl, saveFile);
        } catch (IOException ex) {
            Logger.getLogger(BulletSigsevOnScaleTestCase.class.getName()).log(Level.SEVERE, null, ex);
        }        

        assetManager.registerLocator(System.getProperty("user.home"), FileLocator.class);
        assetManager.loadAsset("testRigidBody.j3o");
    }
}

I had no time for this :frowning:

Well this seems to be more obscure.

At least on linux with master it does work without a crash, I will test it over the weekend with windows

As you can see in the report, I’m using linux (64-bits) too :S. About the jme version, the 3.1.0-beta2, but @javasabr said he could reproduce it in master too, maybe it is with a different use case?

right, I use ubuntu 16.04 and I can reproduce this issue.

hm, what happens if you compile the native bullet files yourself for jme? maybee the one distributed is not as uptodate as we might think? (I use selfbuild files)

What do I need to compile to test it?

best case, you clone jme switch native build on in
-PbuildNativeProjects=‘true’ or edit gradle.properties
and run ./gradlew build, it will quite likely than give errors if you are missing g++,ect. (buildessentials in ubuntu apt)

This will btw. also give you the ability to try to pinpoint the crash (if necessary), by spraying system out equivalents in the cpp files related to loading.

Ok, I will do it later :slight_smile:

/jme3-bullet-native/build/libs/jme3-bullet-native-3.2.0-SNAPSHOT.jar is then the file you want to use, just do a short check inside and validate the modification date for linux. I will try to get the windows build running for comparison.