we have a Rhino 6 plugin and one of our users reported a Rhino crash when they move objects around (with gumball or otherwise). I was not able to reproduce this with Rhino 7.
I’ve tracked it down to a crash in the GC finalizer thread when we try to access mesh properties such as Vertices, Normals or Faces. The user also reported that this issue seems to get worse the bigger the project is. As the issue comes from the finalizer it’s not 100% reproducible but can definitely be triggered after moving objects around for a minute or two.
In general, what we do in our plugin is that we are subscribed to events such as RhinoDoc.AddRhinoObject. We collect all the added/changed/deleted objects and then process those changes in the next RhinoApp.Idle.
Part of that processing is reading the mesh from newly added objects and this is where the crash occurs.
The objects that we are accessing at this point are all valid (via the IsValid check) and not disposed.
Here is a mini crashdump, attach with Mixed. The exception is in the GC Finalizer Thread and our plugin is trying to access the MeshFaceList in the Main Thread.
Rhino crash after moving objects.zip (674.7 KB)
Can we avoid this crash in any way? Is this there a known issue for this case?
I am looking at the .dmp file.
Do you have a way I can repeat this?
It looks like I found the issue on our side. We did use RhinoObject.GetRenderMeshes to Precalculate the meshes but did not keep the returned references so they ended up being garbage collected. When we then later used rhinoObject.GetMeshes()…Face it ran into this crash.
- Use the code below
- Create a project in Rhino6 with a good number of 3d objects ~1000
- Move the objects until crash with a short delay between moves to trigger the idle event
The fix is to not discard the references returned by GetRenderMeshes
public class RhinoAddedObserver
private List<RhinoObject> _addedObjects;
RhinoDoc.AddRhinoObject += OnAddRhinoObject;
private void OnAddRhinoObject(object sender, RhinoObjectEventArgs rhinoObjectEventArgs)
if (_addedObjects == null)
_addedObjects = new List<RhinoObject>();
RhinoApp.Idle += RhinoAppOnIdle;
private void PrecalculateMeshes()
RhinoObject.GetRenderMeshes(_addedObjects, true, false);
private void RhinoAppOnIdle(object o, EventArgs eventArgs)
RhinoApp.Idle -= RhinoAppOnIdle;
foreach (var addedObject in _addedObjects)
foreach (var mesh in addedObject.GetMeshes(MeshType.Render))
if (mesh != null && mesh.IsValid)
var vertices = mesh.Vertices;
var normals = mesh.Normals;
var meshFaceList = mesh.Faces;
_addedObjects = null;
Rather than tracking Rhino objects, you should be tracking by Rhino object ids (Guids).
I’ve re-factored your code a bit (but have not tested).
TestHangstoerfer.cs (2.8 KB)
Rhino still crashes with your sample code. The problem is that the
ObjRef that is returned from
RhinoObject.GetRenderMeshes is unused in that separate method.
At some random point during the loop of reading the meshes from the objects in
OnIdle the finalizer cleans up those
ObjRef and causes a crash.
I don’t see, in any of the sample code above, where you use the return value of
RhinoObject.GetRenderMeshes. A code sample would be necessary.
That is exactly the cause of the crash. If I don’t use the return values, Rhino crashes. If I assign them to a local variable in the scope of the parsing logic it does not crash.
TestHangstoerferNoCrash.cs (2.8 KB)
TestHangstoerferCrash.cs (2.8 KB)
I’ve modified your sample code so that it does not crash, see the changes in Line 97, 99 and 109