ID user decrement error when removing object which is referred to with a PointerProperty #81345
Labels
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
EEVEE & Viewport
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
EEVEE & Viewport
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
6 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: blender/blender#81345
Loading…
Reference in New Issue
No description provided.
Delete Branch "%!s(<nil>)"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
System Information
Operating system: Windows 10 Home 1909 (64-bit)
Graphics card: NVidia GeForce GTX 1050 Ti
Blender Version
Broken: 2.90.0
Worked: Unknown
Short description of error
I have added a PointerProperty to the EditBone type. This PointerProperty refers to an object (which is separate from the armature).
When removing the separate object, it causes the following error in the console:
Eventually this causes Blender to crash with a
Windows fatal exception: access violation
error.Exact steps for others to reproduce the error
Starting with a new General Blend file:
Press the N key to open the sidebar.
In the Item category, find the Test panel.
Click the "Test enabled" checkbox 4 or more times. This triggers the ID user decrement error.
I have also attached a simple .blend file. You can simply open it and then click the "Test enabled" checkbox 4 or more times.
Test.blend
Added subscriber: @pauanyu_blender
Added subscriber: @lichtwerk
Changed status from 'Needs Triage' to: 'Confirmed'
Can confirm a crash, will check on this.
There is one more user here than expected.
Not sure if #77557 (Python Operators that add/remove ID data without an undo step crash Blender) is related? Needs more investigation.
Added subscribers: @Sergey, @dr.sybren, @brecht, @mont29
This is actually a fairly serious issue. Root of it is that bone IDProperties are duplicated over two structures,
Bone
andEditBone
.@brecht, @Sergey, @dr.sybren,
EditBone
is defined inED_armature.h
, so we cannot access it from BKE code that deals with ID refcounting (especially the foreach looper over ID usages fromlib_query.c
and the matching callback for Armature IDs). Do you see any reason not to have that one defined inBKE_armature.h
instead?Having it in
BKE_armature.h
seems fine to me.BKE_armature.h
already has a lot of pose-related functions. Maybe theEditBone
definition could go into a new fileBKE_armature_edit.h
? That may keep things a bit better separated.@dr.sybren It could at some point, but am not convinced it would help at all currently, that would be a new header file with that single struct into it, and then having to link it in many extra places… I would rather do that later, when/if we actually add or move some armature bone editing code into BKE area?
This issue was referenced by
619e52eb82
This issue was referenced by
f393452394
Ok, in that case
BKE_armature.h
is fine too.This actually revealed a nest of bugs regarding ID management and IDProperties of bones… Fixes are now incoming.
@pauanyu_blender Please note that manipulating data-blocks from
update
callback as you do in your script is extremely discouraged, it will basically break undo/redo process, among other potential severe issues, see the API documentation .This issue was referenced by
4b36552967
This issue was referenced by
0db98b214d
Changed status from 'Confirmed' to: 'Resolved'
@mont29 Thanks!
Then what is the idiomatic way to create/remove objects in response to a property changing?
Are the problems only for creating new data blocks, or also manipulating properties on existing data blocks (e.g. changing
Object.location
)?If update callbacks are so harmful, I think the docs should clearly show what the alternative is, rather than essentially telling the developer "you can't do that", which is not helpful.
(As a meta note, I've spent many hours reading through the addons documentation, StackOverflow, and the devtalk forums, but I still find it very hard to figure out how to do even very common things with the addon API. Some more usage examples would be great, though of course I know other things have higher priority.)
Idiomatic way to handle this case is simple: you don't.
In Blender, significant changes to data should happen through operators. Any other way to do it is at best a hack that might work within certain boundaries.
If you really, really want to react to a property value change, then either you run a modal operator and check said value on each
modal
run (which will happen within the main even loop). Or you use an application handler, but this might not work always very well either.Creating or deleting data in general is a critical 'don't' in properties callbacks, be it an ID or some sub-data structure. Changing other parameters is generally fine, though it should preferably be inside the same data-block, otherwise you may break undo/redo stack.
Best usages examples are official add-ons usually… Agree this is not as friendly as a complete comprehensive set of advanced examples (you do know about our 'templates' available in the Text editor of Blender, right? ) would be nice, but this is indeed quiet a lot of work to create and maintain, and we simply do not have the man power for such thing currently.
@mont29 My add-on allows the user to create rigid body physics for bones:
https://github.com/Pauan/blender-rigid-body-bones
The user selects a bone, clicks on a checkbox to enable rigid body physics for that bone, and then changes various rigid body settings:
https://raw.githubusercontent.com/Pauan/blender-rigid-body-bones/master/Usage%2002.PNG
So when the checkbox is enabled, it must create a rigid body object, and when the checkbox is disabled, it must remove that object.
Having a checkbox to enable/disable things does not seem like an extreme case to me, it seems like a common thing to do. So it's very bizarre that you are saying that Blender does not support it.
And using a modal operator or app handler sounds terribly wasteful and bad performance, since it will run all the time, but I only need to run the code when the checkbox is changed.
It also sounds like an over-complication, since my use case is not complicated, and modal operators are clearly not intended for my use case.
If the problem is a lack of Operator, could I solve that by creating an Operator and then calling that Operator inside the update callback? That would be very easy for me to do.
If that doesn't work, then that is a failing in the Python API, and the Python API should be changed (or new APIs created). Perhaps an API that says, "run this callback on the next update tick, during a time where it is safe to create objects".
If you do not provide a correct API, people will instead abuse the current APIs. You cannot simply tell people "don't do that", because their use cases are legitimate and their goals are correct (even if their methods aren't), so they will do it no matter how much you say no. So if you don't want them using a bad API, you must instead provide a good API as an alternative.
Yes, I did see them, but none of them match my use case (which is probably intentional, since it sounds like my use case is simply not supported, which is quite odd).
Would you accept pull requests improving the Python API documentation? I am new to the Python API, but I am a quite experienced programmer in general.
You should have an operator to enable/disable this, not use a property, if you need to create objects etc.
Patches are always welcome, whether it is for documentation or code. :)
Also please do not use this tracker for that kind of discussion, we have other channels for that (blender.chat, our devltalk).
@mont29 Sorry, I will continue the discussion here:
https://devtalk.blender.org/t/proper-way-to-create-remove-objects-in-response-to-property-changes/15692