Crashing Blender with a wrong scene setup sequence?

I am using Blender to render some data visualization in a batch mode, i.e. by using:

blender.exe --background --python <myscript.py>

where my script is basically:

  • completely removing all the default objects (Cube+its mesh, Camera, Light, Material)
  • building everything from the scratch from the data supplied in the script
  • rendering the scene to the file

Now, from time to time, Blender crashes with something like this:

Error   : EXCEPTION_ACCESS_VIOLATION
Address : 0x00007FFC0116D530
Module  : C:\WINDOWS\SYSTEM32\ntdll.dll

I am rendering several different images (the complexity is basically the same, but the sizes and positions of the objects differ) and it just happens in one, two or three of them (out of 17) randomly i.e. not even in the same files.

Needless to say that when running the same script directly in Blender, it always works. So I am a bit lost how to debug this.

By blindly trying to pinpoint the troubled code I noticed following behavior:

  1. When I do not remove the objects, cameras and lights (materials and meshes seems to be fine) at the beginning of the scene setup, it is likely not crashing anymore.

  2. When I do remove everything at the beginning, but do not link the newly created objects by using bpy.context.scene.collection.objects.link(obj), it is likely not crashing (but the objects are not in scene then).

  3. When I do remove everything and then before adding any new objects call bpy.context.view_layer.update(), it is likely not crashing.

The crash happens when adding objects based on meshes from Python data, using this function (but I cannot confirm it is actually in this function):

def add_mesh_obj(name, verts, edges, faces):
    mesh = bpy.data.meshes.new(name)
    mesh.from_pydata(verts, edges, faces)
    obj = bpy.data.objects.new(name, mesh)
    bpy.context.scene.collection.objects.link(obj)
    return obj

and it happens before I get to creating the cameras or the lights. So it seems to be related to mesh objects.

While it seems I have kind of fixed the problem (currently by doing bpy.context.view_layer.update()), I am not sure I understand the cause and if it is a problem in my code, or if it is a bug in Blender, in which case I would report it.

I have been trying to reproduce it on simple testcase, but did not succeed so far, so if anyone has an idea, or an explanation, I will appreciate it.

While blender is starting up, objects are very volatile. You are accessing objects that have been removed or moved (in memory), which leads to the access violation. What happens if you manually run your process when blender has finished loading? Does it work then?

If I run the same script(s) inside Blender through the UI (i.e. from ‘Scripting’) it never crashes. Also the random nature of the manifestation seems to suggest what you are saying.

My interpretation is there is some kind of garbage collection (either in Blender, or in Python) in action (after I remove all the objects) and when it is delayed and my script is faster trying to add new objects it crashes.

Adding the call to bpy.context.view_layer.update() might be enough to have the GC complete and making the scene safe again (kind of ‘data memory barrier’).

But then I guess it is a bug in Blender, as it should ensure the objects are consistent, and should block any manipulation, if they are not?

I would be curious if this actually works (in the long term), be sure to let us know.

If it doesn’t work though, you might just register a timer and delay your addon’s initialization by however many seconds you think is reasonable. Unfortunately it won’t be an exact science, and we could avoid this whole ordeal if we could only get a callback for when Blender was actually ready

I figured this out. Or, at least, I figured out a workaround.

I was running into pretty much exactly the same problem, but running on MacOS. But I was launching a script with the blender binary, exactly as how OP is doing. And I had a function very similar to add_mesh_obj. I identified the specific line that was crashing blender. See below, my old code.

def create_mesh_object(verts, edges, faces, name):
    mesh = bpy.data.meshes.new(name)
    obj = bpy.data.objects.new(mesh.name, mesh)
    col = bpy.data.collections["Collection"]
    col.objects.link(obj) # this is the line that crashes blender
    bpy.context.view_layer.objects.active = obj # maybe this one too, prob not
    mesh.from_pydata(verts, edges, faces)
    mesh.update()

Creating the new object and linking it to the scene was creating the issue. Because I do not need to create many specific objects, but rather just swap out the data, I resulted to modifying the data on the default cube, thus never creating a new object and linking it to the scene. Here’s what I changed the code to.

def create_mesh_object(verts, edges, faces, name):
    # Note: we just edit the default cube, not create a new object
    # for every new surface. This crashes blender significantly less.
    # ********* the old, crash prone code ************
    # col = bpy.data.collections["Collection"]
    # col.objects.link(obj)  # this line crashes blender a lot
    # # bpy.context.view_layer.objects.active = obj
    # ******* end of crashing code ********
    obj = bpy.data.objects["Shape"]
    mesh = bpy.data.meshes.new(name)
    mesh.from_pydata(verts, [], faces)
    obj.data = mesh
    mesh.update()

Hopefully this helps someone. I struggled on this for more than 4 hours.
If you really do need to create multiple objects in blender, perhaps you could create all of them at once, and then link them to the scene after they are created. This may reduce crash liklihood.

1 Like