native crash caused by dMass

I have been experiencing a native crash seemingly involved with calling Body.setMassParameters() during program execution. I now believe the problem is related to the creation of the local dMass object in the constructor of Body. The dMass object is local, and therefore goes out of scope after execution of the constructor, causing the object to be garbage collected. The dMass object being garbage collected seemingly invalidates the SWIG mass pointer. I have verified that making the dMass object global within Body (therefore preventing it from being garbage collected) solves this problem. For this reason, I think the dMass object should be a global instance variable within Body. Any thoughts? :smiley:

Yeah I think I can verify that it’s a bug alright. In ode.odejava.Body constructor you see the creation of a little intermediate object called mass:

dMass mass = new dMass();

That object is a native proxy class holding a pointer (as a long) to a native object. When dMass is instantiated in this way it creates a native object by making a call to Ode.new_dMass() and it sets an internal flag swigMemOwn=true. That indicates that the object was created within the scope of that dMass instance and should therefore be destroyed when the instance is garbage collected.

Here’s a snippet from dMass showing what happens when the GC
calls finalize():

protected void finalize() {
delete();
}

public void delete() {
if(swigCPtr != 0 && swigCMemOwn) {
System.out.println("DELETING dMass! "+swigCPtr);
swigCMemOwn = false;
OdeJNI.delete_dMass(swigCPtr);
}
swigCPtr = 0;
}

Normally this works great and prevents memory leaks. However, in this case (as you pointed out), the dMass instance has no references outside the scope of that class so the GC sees it as fair game for disposal as soon as the method returns. This can create some nasty bugs since the app might seem to work normally for awhile and then bam!

I think the dMass instance should definitely be a private class-level field variable (as you have done), just to prevent it from getting GC’d.

This issue is now fixed in CVS.