Maniphest T60553

Crash. Script changing values of a prop attached to object by an operator popup crashes the app
Confirmed, NormalKNOWN ISSUE

Assigned To
None
Authored By
Evgeniy Skvortsov (ChieVFX)
Jan 16 2019, 6:57 AM
Tags
  • BF Blender
  • Python API
Subscribers
Campbell Barton (campbellbarton)
Evgeniy Skvortsov (ChieVFX)
Jacques Lucke (JacquesLucke)
Radu Popovici (rpopovici)

Description

System Information
Operating system: Windows 10 Pro
Graphics card: NVidia GTX 1070 Ti

Blender Version
Broken:
(example: 2.80, edbf15d3c044, blender2.8, 2018-11-28, as found on the splash screen)
Worked: (optional)

Short description of error
When used from a plugin, operator that uses wm.invoke_props_popup(self, event) to draw(and change) properties from a property group attached to an object (constantly) crashes the app.
When same code is used from the blender scripting area, the app does not crash, but after initial change of the param, the property is grayed out(seems like a bug as well).
Error : EXCEPTION_ACCESS_VIOLATION
Address : 0x00007FF7DDBEA080
Module : c:\Blender28\program\blender.exe
The terminal process terminated with exit code: 11

Exact steps for others to reproduce the error

  1. Create a testing_grounds.py file
  2. Fill it with code provided below
  3. Install as an addon
  4. Select an object
  5. Launch the operator(through space, typing "TEZZT")
  6. Change the value of the property by clicking and dragging the value;
  7. Repeat step (6) a few times if the app hasn't crashed yet
bl_info = {
    "name" : "TestingGrounds",
    "author" : "ChieVFX",
    "description" : "",
    "blender" : (2, 80, 0),
    "location" : "",
    "warning" : "",
    "category" : "Generic"
}

import bpy

class SomeParams(bpy.types.PropertyGroup):
    float_value : bpy.props.FloatProperty()

class TestOp(bpy.types.Operator):
    bl_idname="testing_ground.tezzt"
    bl_label="TEZZT"
    bl_options={'REGISTER', 'UNDO'}

    def invoke(self, context, event):
        wm = context.window_manager
        return wm.invoke_props_popup(self, event)
    
    def execute(self, context):
        print("Im fine")
        return {'FINISHED'}
    
    def draw(self, context):
        layout : bpy.types.UILayout = self.layout
        obj = context.object
        some_params = obj.some_params
        layout.prop(some_params, "float_value", text="Prop popup test")
        
classes = [
    SomeParams,
    TestOp
]

def register():
    for cls in classes:
        bpy.utils.register_class(cls)
    
    bpy.types.Object.some_params = bpy.props.PointerProperty(type=SomeParams)


def unregister():
    for cls in classes:
        bpy.utils.unregister_class(cls)
    
if __name__ == "__main__":
    register()
    bpy.ops.testing_ground.tezzt('INVOKE_DEFAULT')

Event Timeline

Evgeniy Skvortsov (ChieVFX) created this task.Jan 16 2019, 6:57 AM
Evgeniy Skvortsov (ChieVFX) updated the task description.
Evgeniy Skvortsov (ChieVFX) added a comment.Jan 16 2019, 7:18 AM

I realize that it might be intentional and is not a deal-breaker.
Using duplicating props in the operator whose values are then set on execute to the object's prop seems to work fine.

Jacques Lucke (JacquesLucke) lowered the priority of this task from 90 to 50.Jan 16 2019, 12:35 PM
Jacques Lucke (JacquesLucke) added a subscriber: Jacques Lucke (JacquesLucke).

It's certainly not typical to show properties that don't belong to the operator in this place. However, I don't see why this should crash.
Note: you can reproduce this without creating an addon. Just execute the code in Blenders Text editor.

__GI_raise(int sig) (/build/glibc-OTsEL5/glibc-2.27/sysdeps/unix/sysv/linux/raise.c:51)
__GI_abort() (/build/glibc-OTsEL5/glibc-2.27/stdlib/abort.c:79)
BKE_idcode_to_index(const short idcode) (/home/jacques/blender-git/blender/source/blender/blenkernel/intern/idcode.c:315)
DEG_id_type_tag(Main * bmain, short id_type) (/home/jacques/blender-git/blender/source/blender/depsgraph/intern/depsgraph_tag.cc:658)
DEG::(anonymous namespace)::deg_graph_id_tag_update(Main * bmain, DEG::Depsgraph * graph, ID * id, int flag) (/home/jacques/blender-git/blender/source/blender/depsgraph/intern/depsgraph_tag.cc:462)
DEG::(anonymous namespace)::deg_id_tag_update(Main * bmain, ID * id, int flag) (/home/jacques/blender-git/blender/source/blender/depsgraph/intern/depsgraph_tag.cc:488)
DEG_id_tag_update_ex(Main * bmain, ID * id, int flag) (/home/jacques/blender-git/blender/source/blender/depsgraph/intern/depsgraph_tag.cc:632)
DEG_id_tag_update(ID * id, int flag) (/home/jacques/blender-git/blender/source/blender/depsgraph/intern/depsgraph_tag.cc:623)
rna_property_update(bContext * C, Main * bmain, Scene * scene, PointerRNA * ptr, PropertyRNA * prop) (/home/jacques/blender-git/blender/source/blender/makesrna/intern/rna_access.c:2200)
RNA_property_update(bContext * C, PointerRNA * ptr, PropertyRNA * prop) (/home/jacques/blender-git/blender/source/blender/makesrna/intern/rna_access.c:2233)
ui_apply_but_funcs_after(bContext * C) (/home/jacques/blender-git/blender/source/blender/editors/interface/interface_handlers.c:782)
ui_popup_handler(bContext * C, const wmEvent * event, void * userdata) (/home/jacques/blender-git/blender/source/blender/editors/interface/interface_handlers.c:9939)
wm_handler_ui_call(bContext * C, wmEventHandler * handler, const wmEvent * event, int always_pass) (/home/jacques/blender-git/blender/source/blender/windowmanager/intern/wm_event_system.c:573)
wm_handlers_do_intern(bContext * C, wmEvent * event, ListBase * handlers) (/home/jacques/blender-git/blender/source/blender/windowmanager/intern/wm_event_system.c:2374)
wm_handlers_do(bContext * C, wmEvent * event, ListBase * handlers) (/home/jacques/blender-git/blender/source/blender/windowmanager/intern/wm_event_system.c:2607)
wm_event_do_handlers(bContext * C) (/home/jacques/blender-git/blender/source/blender/windowmanager/intern/wm_event_system.c:2997)
WM_main(bContext * C) (/home/jacques/blender-git/blender/source/blender/windowmanager/intern/wm.c:427)
main(int argc, const char ** argv) (/home/jacques/blender-git/blender/source/creator/creator.c:523)
Jacques Lucke (JacquesLucke) assigned this task to Campbell Barton (campbellbarton).Mar 20 2019, 3:35 PM

Looks like the following is happening:

  1. The draw function of the popover is called. This stores the pointer to the active object in the uibut (?) somewhere.
  2. Then, when undo is executed (because of operator redo), the pointer to the active object changes. The problem is that the now-invalid pointer is still used.

Some printf debugging output:

context.active_object in draw:       0x7fffaa139838
ptr->id.data in rna_property_update: 0x7fffaa139838
name: OBCube
context.active_object in execute:    0x7fffaa139838
ptr->id.data in rna_property_update: 0x7fffaa139838
name: OBCube
redo_cb: operator redo TEZZT
context.active_object in execute:    0x7fffaa142838     <- new active object pointer after undo
ptr->id.data in rna_property_update: 0x7fffaa139838     <- still the old pointer
name: <crash>
Dalai Felinto (dfelinto) removed Campbell Barton (campbellbarton) as the assignee of this task.Dec 23 2019, 4:35 PM
Dalai Felinto (dfelinto) added a project: Tracker Curfew.
Dalai Felinto (dfelinto) added a subscriber: Campbell Barton (campbellbarton).
Richard Antalik (ISS) edited projects, added Add-ons (BF-Blender); removed Tracker Curfew.Jan 22 2020, 8:09 PM
Richard Antalik (ISS) changed the subtype of this task from "Report" to "Known Issue".
Radu Popovici (rpopovici) added a subscriber: Radu Popovici (rpopovici).EditedMay 30 2020, 3:07 PM

I had a similar issue. Adding a redo handler with a view_layer.update() inside fixed the crash in my case.

@persistent
def redo_update_handler_post(scene):
    # fix crash in redo
    bpy.context.view_layer.update()
Campbell Barton (campbellbarton) edited projects, added Python API; removed Add-ons (BF-Blender).Jun 19 2020, 10:38 AM
Campbell Barton (campbellbarton) moved this task from Backlog to Known Issues on the Python API board.Jun 19 2020, 11:07 AM