[SOLVED] EXCEPTION_ACCESS_VIOLATION after 64 KinematicRagdollControls

In my game, the direction of gravity is different in different places, so, whenever I want to add a ragdoll, I have to attach a new BulletAppState to the AppStateManager, call setGravity on its PhysicsSpace, and then add the KinematicRagdollControl. Then, when the ragdoll has finished, I remove everything in reverse order, and finally detach the BulletAppState from the AppStateManager.

This works fine, but I’ve discovered that after precisely 64 times of doing this, I get an EXCEPTION_ACCESS_VIOLATION. It happens after I’ve added the KinematicRagdollControl to the PhysicsSpace, but before I call setRagdollMode(), which I do on the following frame. So, once I’ve added the 64th KinematicRagdollControl to a PhysicsSpace, I get an EXCEPTION_ACCESS_VIOLATION.

In the error report file, under Internal exceptions, it say this:

Event: 109.478 Thread 0x0000000056b05000 Exception <a 'java/lang/UnsatisfiedLinkError': com.jme3.bullet.joints.PhysicsJoint.finalizeNative(J)V> (0x00000000e08b04e0) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u161\10277\hotspot\src\share\vm\prims\nativeLookup.cpp, line 378]

Looking at the source code, I see that PhysicsJoint declares a native finalizeNative method, but that com_jme3_bullet_joints_PhysicsJoint.cpp doesn’t contain an implementation of finalizeNative, which certainly would explain the UnsatisfiedLinkError.

So, it seems that after 64 times, garbage collection is attempting to clean up resources, and is calling finalize on a PhysicsJoint, and finding that the implementation of the native method is missing.

I tried removing the call to finalizeNative in PhysicsJoint.finalize, but that caused an EXCEPTION_ACCESS_VIOLATION but with different internal exceptions, so I think that whatever would go on in finalizeNative must be quite necessary.

I would like to try supplying an implementation for finalizeNative. Looking at the implementations of this method in other C++ files, they all seem to follow a pattern that I can attempt to replicate. However, I don’t know how to rebuild the DLLs, which is presumably what’s required. Gradle just seems to rebuild the JARs. Assuming I’m on the right track, can someone explain to me how to rebuild the DLLs?

Should I also create an issue on GitHub?

1 Like

Just one question: Can’t you use multiple Physics Spaces with the same instance of BulletAppState?

1 Like

The DLLs and SOs are built by the jme3-bullet-native subproject. You have to set buildNativeProjects to true in gradle.properties, and you need native tools installed.

If this isn’t in the Wiki, it really ought to be.

PS: Please do open an issue at GitHub.

1 Like

OK, it looks like I’ve found a fix/workaround.

In each BulletAppState, I was setting threadingType to PARALLEL. Based on Darkchaos’s suggestion, I was perusing the BulletAppState code, and I realized that perhaps I didn’t need to be doing that. So, I updated my code, and when I ran the game, I found that not only did the ragdolls still work fine, but also that the game no longer crashes after there have been 64. Why that fixes the problem, I don’t know, but, there you go.

As for using a single BulletAppState, I think that might be possible. I’ll look into it tomorrow, and let you know. Even though my problem seems to be fixed, having only one BulletAppState would still be a nicer solution regardless.

Regarding the wiki, I was looking at this page, and the pages it links to. They explain everything, except how to build the DLLs, as far as I can see. This topic gives you some clues as to how to do it, and mentions some things you need to install, but I couldn’t tell what you’re supposed to do next.

So, even though I have solved my problem in a roundabout way, I’m pretty sure there’s still a bug there, even if, in practise, it tends not to affect most people. So, I’ll put it in an issue on GitHub tomorrow.

1 Like

I’ve created a new issue on GitHub: No native implementation for PhysicsJoint.finalizeNative · Issue #913 · jMonkeyEngine/jmonkeyengine · GitHub

I don’t think it is possible to have multiple PhysicsSpaces with the same instance of BulletAppState, because BulletAppState only has a single PhysicsSpace member variable (pSpace). While you could repeatedly call startPhysics() in order to create multiple PhysicsSpaces, BulletAppState would no longer be updating the previous PhysicsSpaces, because pSpace would always point to the latest one. If you think it is possible, let me know how.

Anyway, the original issue is fixed for me, so, I’ll mark this topic as solved.

1 Like

Why not just set the gravity on the object?

1 Like

What class and method would this be? Do you mean the Spatial? I’m only aware of PhysicsSpace.setGravity.

1 Like

if you say you got different gravity in different places, dont you already have your different physicsspaces for the different gravities?
you could just replace your rigidbodycontrol or whatever you used to physically represent your character/whatever with the ragdoll and assuming you set different gravities on these different physicsspaces, that gravity would be applied to everything added to this physicsspace.

but aside from that if i understand your situation, you can use a single physicsspace (and thus a single bulletappstate) even if you want different objects to have different gravity (to make it feel like gravity doesnt depend on the object but instead depend on location you can set your objects gravity dependant on their locations)
PhysicsRigidBody.java:

     /**
     * Set the local gravity of this PhysicsRigidBody<br/>
     * Set this after adding the node to the PhysicsSpace,
     * the PhysicsSpace assigns its current gravity to the physics node when its added.
     * @param gravity the gravity vector to set
     */
    public void setGravity(Vector3f gravity) {
        setGravity(objectId, gravity);
    }

(Note the comment above the method)
Since i have not yet done anything with ragdolls im not sure how to do that but looking at the code of KinematicRagdollControl.java that you are using i find

    protected final Set<String> boneList = new TreeSet<String>();
    protected final Map<String, PhysicsBoneLink> boneLinks = new HashMap<String, PhysicsBoneLink>();

and a method

    public PhysicsRigidBody getBoneRigidBody(String boneName) {
        PhysicsBoneLink link = boneLinks.get(boneName);
        if (link != null) {
            return link.rigidBody;
        }
        return null;
    }

you could either play around with that or since these attributes are marked protected you could write something like

public class GravityKinematicRagdollControl extends KinematicRagdollControl {
   
   //some constructors here

   public void setGravity(Vector3f grav) {
      for (PhysicsBoneLink boneLink : boneLinks.values()) {
         boneLink.getRigidBody().setGravity(grav);
      }
   }
}

havent tried it and since i dont know how ragdolls exactly work that might mess something up but might still be worth a try

I didn’t realize this didn’t have a setGravity… most other physics controls do… but note: the physics space setGravity is only setting the gravity that will be applied when the object is added to the space. For most people, this trips them up because they set the gravity on their object, add it to the physics space, and then wonder why their gravity was reset. In your case, you can probably take advantage of this.

You should be able to set the physics space gravity and then add your object. Set the gravity different for the next object, etc… Each object will have its own gravity.

2 Likes

Isn’t this a real issue then?
I think that especially server side you might have different physics spaces for different zones which is especially important for the performance (e.g. no unnecessary objects which will never collide).

Honestly I think I read some posts where people were using different physics spaces for exact that situation (different zones).
Maybe we should work towards this or is this a limitation from bullet itself maybe @sgold?

1 Like

OK, so, I understand what you’re saying: call PhysicsRigidBody.setGravity instead of PhysicsSpace.setGravity. I didn’t realize that PhysicsRigidBody had a setGravity method. Although KinematicRagdollControl doesn’t have a setGravity method, I’ve already subclassed KinematicRagdollControl (as Samwise also suggests), so I can easily call PhysicsRigidBody.setGravity after the KinematicRagdollControl has been added to the PhysicsSpace. This works, and means that I am able to have just one BulletAppState and one PhysicsSpace, if I want to.

I find that this solution also fixes my original EXCEPTION_ACCESS_VIOLATION problem, even if the single PhysicsSpace uses parallel threading.

However, I find that I get best performance using multiple PhysicsSpaces (by having multiple BulletAppStates) and parallel threading. So, I think I’ll keep my original multiple BulletAppStates solution as it is, and just use sequential threading until issue 913 is fixed. I see that Stephen has already fixed it in his fork, so, as soon as it’s in the main repo, and the CI has updated the DLLs, I’ll give it a test.

1 Like

I’ve never tried multiple physics spaces in the same application. If I did, I would probably instantiate multiple BulletAppStates to manage them.

Or perhaps I wouldn’t use BulletAppState at all. No reason you can’t instantiate PhysicsSpace directly.

1 Like

Well using multiple BulletAppStates sucks as AppStates aren’t designed to have multiple instances of them, if I am not wrong.
And I guess most people aren’t knowledged enough to use their physics spaces directly.

i guess they are neither explicitly designed to have multiple instances nor not to have multiple instances, you can do it the way you want. the appStateManagers getState(class) method as well as the spatials getControl(class) method are more like convenience methods that assume you most most usually only got a single instance of each different state/control but dont forbid you to have several instances attached. You will only ever get the first instance of the requested class attched though when doing such get(class)-call. so i guess you would have to keep the references to the states around somewhere. for controls on the other hand, spatials offer a getNumControls() and a getControl(int index) method that allow you to get all controls added to this spatial (they only got a single list of controls, as opposed to the appStateManager that has lists for initiailzing, fully attached and terminating states to ensure proper lifecycles and also initialization and so on happen on the jME Main thread)

though the most straight forward solution if one doesnt want to handle physicsspaces themselves - maybe not the most efficient, not sure - probably is to just write a MultiBulletAppStates class that only holds a list of BulletAppStates you can add or remove, which are added to the stateManager also as soon and as long as the MultiBulletAppState is attached. instead of stateManager.getState(BulletAppState.class).fancyMethod() you would go for stateManager.getState(MultiBulletAppState.class).getBulletState(index).fancyMethod()

i guess though that figuring out how to manage physicsspaces (thats usually handled by bulletAppState that only has ~300 lines) is far easier than figuring out how to efficiently write that complex-online-multiPlayer-multiPhysics-multiFancyStuff-multiEverythingSynchronized-game and might be worth the investigation just to understand whats happening there

@pspeed talking about it i looked into the code, is there a reason PhysicsSpaces collisionListener-list is not a SafeArrayList? if i got it right thats one of the cases that class was written for: repeatedly (is that a word?) calling some method of all objects in that list, while the amount of objects in the list only change every now and then

1 Like

You “can”… they work just fine as long as you don’t need to look them up anymore.

1 Like

Yes, basically the class was written for two reasons that plagued JME all over the place:

  1. repeatedly iterating over mostly static lists inefficiently.
  2. iterating over lists of listeners where a child might want to remove itself during iteration.

Probably this was just never converted.

1 Like

ah well @pspeed hit the nail on the head i guess, bunch of words wasted from my side :smiley:

To be thorough, you would also have to setGravity on the baseRigidBody of the KinematicRagdoll.

If you think the list of collision listeners is worth upgrading, open an issue, and I’ll handle it.

1 Like

I just had a go with the DLL containing the implementation of finalizeNative. When the 64th KinematicRagdollControl gets added to a PhysicsSpace (using parallel threading) I still get an EXCEPTION_ACCESS_VIOLATION, but it’s no longer complaining about UnsatisfiedLinkErrors. It’s now complaining about PrivilegedActionExceptions and something called “implicit null exceptions”:

Event: 3.219 Thread 0x0000000059d7b000 Exception <a 'java/security/PrivilegedActionException'> (0x00000000e1774410) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u161\10277\hotspot\src\share\vm\prims\jvm.cpp, line 1390]
Event: 3.220 Thread 0x0000000059d7b000 Exception <a 'java/security/PrivilegedActionException'> (0x00000000e1775038) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u161\10277\hotspot\src\share\vm\prims\jvm.cpp, line 1390]
Event: 19.476 Thread 0x0000000059d7b000 Implicit null exception at 0x00000000031f4e36 to 0x00000000031f5819
Event: 25.686 Thread 0x0000000059d7b000 Implicit null exception at 0x00000000036b48b1 to 0x00000000036b4b9d
Event: 25.686 Thread 0x0000000059d7b000 Implicit null exception at 0x00000000035ca612 to 0x00000000035caa12
Event: 25.686 Thread 0x0000000059d7b000 Implicit null exception at 0x00000000036b0afc to 0x00000000036b0d39
Event: 25.687 Thread 0x0000000059d7b000 Implicit null exception at 0x000000000361f030 to 0x000000000361f6cd
Event: 25.702 Thread 0x0000000059d7b000 Implicit null exception at 0x00000000036e9ab4 to 0x00000000036ea4d9
Event: 26.006 Thread 0x0000000059d7b000 Implicit null exception at 0x000000000370e5c5 to 0x0000000003710e25
Event: 28.600 Thread 0x0000000059d7b000 Implicit null exception at 0x00000000035ec0cf to 0x00000000035ed525

I don’t know whether that’s due to an error in the implementation of finalizeNative, or something completely different.

Before I created this topic, and tried to write a simple app to reproduce the EXCEPTION_ACCESS_VIOLATION I was getting. I was intending it to add a KinematicRagdollControl to a PhysicsSpace 64 times. However, instead, I found that I got an EXCEPTION_ACCESS_VIOLATION just trying to do one ragdoll. The body of the app is given below.

    private Spatial model;
    private BulletAppState bulletAppState;
    
    @Override
    public void simpleInitApp() {
        cam.setLocation(new Vector3f(0, 4, 18));
        
        /** A white ambient light source. */ 
        AmbientLight ambient = new AmbientLight();
        ambient.setColor(ColorRGBA.White);
        rootNode.addLight(ambient);
        
        /** A white, directional light source */ 
        DirectionalLight sun = new DirectionalLight();
        sun.setDirection((new Vector3f(-0.5f, -0.5f, -0.5f)).normalizeLocal());
        sun.setColor(ColorRGBA.White);
        rootNode.addLight(sun); 
        
        loadModel();
        createBulletAppState();
        addFloor();
        startRagdoll();
    }
    
    private void loadModel() {
        model = assetManager.loadModel("Models/Sinbad/Sinbad.mesh.xml");
        
        model.setLocalTranslation(0, 10, 0);
        
        rootNode.attachChild(model);
    }
    
    private void createBulletAppState() {
        bulletAppState = new BulletAppState();
        
        stateManager.attach(bulletAppState);
    }
    
    private void addFloor() {
        Plane plane = new Plane(Vector3f.UNIT_Y, 0);
        CollisionShape shape = new PlaneCollisionShape(plane);
        PhysicsRigidBody floor = new PhysicsRigidBody(shape, 0);
        
        bulletAppState.getPhysicsSpace().add(floor);
    }
    
    private void startRagdoll() {
        KinematicRagdollControl control = new KinematicRagdollControl();
        
        model.addControl(control);
        
        bulletAppState.getPhysicsSpace().add(control);
        
        control.setRagdollMode();
    }

Running this, if I use native Bullet, I get an EXCEPTION_ACCESS_VIOLATION; if I use jBullet, it works absolutely fine. Does that fall over with native Bullet for anyone else? The funny thing is, my game has ragdolls, so it’s not as if my computer is too old to do ragdolls or something (although it is old). The internal exceptions I get in this case are:

Event: 0.438 Thread 0x00000000024b8000 Exception <a 'java/lang/NoSuchFieldError': method resolution failed> (0x00000000e04e7798) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u161\10277\hotspot\src\share\vm\prims\methodHandles.cpp, line 1167]
Event: 0.441 Thread 0x00000000024b8000 Exception <a 'java/lang/NoSuchFieldError': method resolution failed> (0x00000000e04f4ae8) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u161\10277\hotspot\src\share\vm\prims\methodHandles.cpp, line 1167]
Event: 0.546 Thread 0x0000000059ca5000 Exception <a 'java/io/FileNotFoundException'> (0x00000000e0679a58) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u161\10277\hotspot\src\share\vm\prims\jni.cpp, line 709]
Event: 0.688 Thread 0x0000000059ca5000 Exception <a 'java/lang/NoClassDefFoundError'> (0x00000000e07195c8) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u161\10277\hotspot\src\share\vm\prims\jvm.cpp, line 1394]
Event: 3.104 Thread 0x0000000059fdc000 Exception <a 'java/security/PrivilegedActionException'> (0x00000000e17018a8) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u161\10277\hotspot\src\share\vm\prims\jvm.cpp, line 1390]
Event: 3.104 Thread 0x0000000059fdc000 Exception <a 'java/security/PrivilegedActionException'> (0x00000000e1703418) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u161\10277\hotspot\src\share\vm\prims\jvm.cpp, line 1390]
Event: 3.104 Thread 0x0000000059fdc000 Exception <a 'java/security/PrivilegedActionException'> (0x00000000e1704538) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u161\10277\hotspot\src\share\vm\prims\jvm.cpp, line 1390]
Event: 3.105 Thread 0x0000000059fdc000 Exception <a 'java/security/PrivilegedActionException'> (0x00000000e1709658) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u161\10277\hotspot\src\share\vm\prims\jvm.cpp, line 1390]
Event: 3.105 Thread 0x0000000059fdc000 Exception <a 'java/security/PrivilegedActionException'> (0x00000000e170a2b0) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u161\10277\hotspot\src\share\vm\prims\jvm.cpp, line 1390]
Event: 3.105 Thread 0x0000000059fdc000 Exception <a 'java/security/PrivilegedActionException'> (0x00000000e170aed8) thrown at [C:\re\workspace\8-2-build-windows-amd64-cygwin\jdk8u161\10277\hotspot\src\share\vm\prims\jvm.cpp, line 1390]

Again, they include PrivilegedActionExceptions. So, when I run my game with the latest bulletjme.dll, and get an EXCEPTION_ACCESS_VIOLATION caused by PrivilegedActionExceptions, unfortunately I’m not in a position to say whether that’s because there’s something wrong with the implementation of finalizeNative, or whether it’s due to whatever causes that test app to not work for me either.

1 Like