Page MenuHome

Reproducable crash in 2.80: bmesh.from_object / mesh_get_eval_final
Closed, ResolvedPublic

Description

System Information
Operating system: macOS 10.13.6 (High Sierra)
Graphics card: NVIDIA GeForce GT 650M

Blender Version
Broken: Blender 2.80 (sub 55), Commit date: 2019-04-10 15:33, Hash a3b88c917299

Short description of error
0 blender 0x0000000103c5a6d7 BLI_system_backtrace + 55
1 blender 0x00000001030bc5da sig_handle_crash + 362
2 libsystem_platform.dylib 0x00007fff5e836f5a _sigtramp + 26
3 ??? 0x0000000000000000 0x0 + 0
4 blender 0x000000010384d88f mesh_get_eval_final + 79
5 blender 0x00000001034f6169 bpy_bmesh_from_object + 553
6 blender 0x0000000105246a9a _PyMethodDef_RawFastCallKeywords + 746
7 blender 0x000000010524c6b2 _PyMethodDescr_FastCallKeywords + 82
8 blender 0x00000001053180a3 call_function + 659
9 blender 0x0000000105310118 _PyEval_EvalFrameDefault + 4088
10 blender 0x00000001052462f0 function_code_fastcall + 256
11 blender 0x00000001034b5811 bpy_class_call + 961
12 blender 0x0000000103bbb435 rna_operator_execute_cb + 117
13 blender 0x00000001030c1e85 wm_operator_exec + 149
14 blender 0x00000001030f2081 ED_undo_operator_repeat + 561
15 blender 0x0000000103298e9c ui_apply_but_funcs_after + 476
16 blender 0x0000000103295847 ui_handler_region_menu + 599
17 blender 0x00000001030c7a23 wm_handlers_do_intern + 659
18 blender 0x00000001030c38ff wm_handlers_do + 31
19 blender 0x00000001030c2db3 wm_event_do_handlers + 835
20 blender 0x00000001030bd050 WM_main + 32
21 blender 0x00000001030b8dd7 main + 903

Exact steps for others to reproduce the error

  1. Open a new default scene (with the cube selected).
  2. Copy and execute the following code in the python console:
import bmesh
class TestBMesh(bpy.types.Operator):
    bl_idname = 'test.bmesh'
    bl_description = bl_label = 'Test BMesh'
    bl_options = {'REGISTER', 'UNDO'}
    boom: bpy.props.IntProperty(name='Boom', description='Changing a property causes the crash')
    def execute(self, context):
        mesh = bmesh.new()
        mesh.from_object(bpy.context.object, bpy.context.depsgraph)
        mesh.free()
        return {'FINISHED'}

bpy.utils.register_class(TestBMesh)
  1. Search for the new "Test BMesh" operator and execute it.
  2. Open the operators options and change the property "Boom".
  3. Blender crashes (see backtrace above)

Details

Type
Bug

Event Timeline

Philipp Oeser (lichtwerk) triaged this task as Confirmed, Medium priority.Apr 11 2019, 11:38 AM
Philipp Oeser (lichtwerk) claimed this task.

Confirmed, checking....

At the moment, for this to work properly (and prevent the crash), you need to add option USE_EVAL_DATA to your operator, like so:

import bmesh
class TestBMesh(bpy.types.Operator):
    bl_idname = 'test.bmesh'
    bl_description = bl_label = 'Test BMesh'
    bl_options = {'REGISTER', 'UNDO', 'USE_EVAL_DATA'}
    boom: bpy.props.IntProperty(name='Boom', description='Changing a property causes the crash')
    def execute(self, context):
        mesh = bmesh.new()
        mesh.from_object(bpy.context.object, bpy.context.depsgraph)
        mesh.free()
        return {'FINISHED'}

bpy.utils.register_class(TestBMesh)

But I guess it would be good to prevent the crash as well :)
All is happening in bpy_bmesh_from_object and the root of the crash is happening because DEG_get_evaluated_scene fails to get scene_cow on redo (it is NULL then).
We could just check if scene_eval is NULL there and return, but we would still run in the assert in Debug builds...
Also would be nice to inform the user what went wrong beforehand, something like

if (scene_cow == NULL) {
   PyErr_SetString(PyExc_ValueError, "from_object(...): up-to-date depsgraph, consider using the 'USE_EVAL_DATA' operator option");
   return NULL;
}

@Sergey Sharybin (sergey): regarding the assert in DEG_get_evaluated_scene: is there a reliable way to see beforehand if DEG_get_evaluated_scene() would fail [and run in the assert]?

I've tried something like

Scene *scene = DEG_get_input_scene(depsgraph);
Scene *scene_cow = (Scene *)DEG_get_evaluated_id(depsgraph, &scene->id);

but in this case scene_cow is not NULL...

Also @Brecht Van Lommel (brecht): is this a candidate for "High" prio? Or is this not a bug at all [because with USE_EVAL_DATA it is working as expected]?

also note there was very similar T61264

Brecht Van Lommel (brecht) raised the priority of this task from Confirmed, Medium to Confirmed, High.Apr 16 2019, 12:28 AM

We discussed solutions to this type of problem, @Sergey Sharybin (sergey) will probably be the one to implement it.

Sergey Sharybin (sergey) closed this task as Resolved.Thu, May 16, 11:56 AM

The issue here is the access to the non-evaluated dependency graph. This is now not possible after rBe693918d407. So now you need to do context.evaluated_depsgraph_get() when you need to communicate to it.

After this simple change to the script the crash is fixed.

Thanks for the report, closing it now.