Blender Crashes when multiple Data Transfer modifiers are used #46672

Closed
opened 2015-11-02 11:39:27 +01:00 by Gaia Clary · 8 comments
Member

Blender Version
Broken: development version (after 2.76)

Short description of error

I have 3 objects A, B, C
data transfer modifier on A transfers data from B
data transfer modifier on C transfers data from B

When i move one of the objects around in object mode then occasionally Blender crashes.
I can reproduce this behavior when all addons are disabled.
And the problem goes away when i disable the data transfer modifiers.

Exact steps for others to reproduce the error

Open the included blend file data_transfer_normals.blend
select the middle object and move it around a bit.
what seems to work "best" is:

G z then move the mouse frantically on your desk.

Sometimes the crash happens right away, sometimes it takes minutes to get it to appear.

The crash takes longer to show up when blender is in debug mode,
but i can get it to break there within a minuite.
The crash happens always here:

  static void customData_update_offsets(CustomData *data)
  {
      const LayerTypeInfo *typeInfo;
      int i, offset = 0;
      for (i = 0; i < data->totlayer; ++i) {
          typeInfo = layerType_getInfo(data->layers[i].type);
          data->layers[i].offset = offset;
          offset += typeInfo->size;   /*<== Crash because typeinfo is NULL */
      }
      data->totsize = offset;
      CustomData_update_typemap(data);
  }

The reason for this is the last data layer (5) is not initialized or contains broken data.
Here is the content of data->layers- [x] when the crash happens:

data->layers[5]	{type=-33686019 offset=72 flag=-1414812757 ...}	CustomDataLayer
type	-33686019	int 
offset	72	int
flag	-1414812757	int
active	-1414812757	int
active_rnd	-1414812757	int
active_clone	-17891602	int
active_mask	-17891602	int
uid	-17891602	int
name	0x000000001f551330 ""	char[64]
data	0x0000000000000000	void *

The Main thread works on Object A (which has a data transfer modifier defined with source Object B)
The Stack of the Blender Main Thread is:

 blender-app.exe!customData_update_offsets(CustomData * data) Line 1619	C
 blender-app.exe!customData_add_layer__internal(CustomData * data, ...) Line 1925	C
 blender-app.exe!CustomData_add_layer(CustomData * data, int type, int alloctype, void * layerdata, int totelem) Line 1935	C
 blender-app.exe!dm_getLoopArray(DerivedMesh * dm) Line 155	C
 blender-app.exe!CDDM_calc_loop_normals_spacearr(DerivedMesh * dm, ...) Line 2620	C
 blender-app.exe!CDDM_calc_loop_normals(DerivedMesh * dm, ...) Line 2611	C
 blender-app.exe!data_transfer_dtdata_type_preprocess(Object * UNUSED_ob_src, ...) Line 279	C
 blender-app.exe!BKE_object_data_transfer_dm(Scene * scene, Object * ob_src, ...) Line 1171	C
 blender-app.exe!applyModifier(ModifierData * md, Object * ob, ...) Line 211	C
 blender-app.exe!modwrap_applyModifier(ModifierData * md, ...) Line 745	C
 blender-app.exe!mesh_calc_modifiers(Scene * scene, Object * ob, ...) Line 2037	C
 blender-app.exe!mesh_build_data(Scene * scene, Object * ob, ...) Line 2582	C
 blender-app.exe!makeDerivedMesh(Scene * scene, Object * ob, BMEditMesh * em, ...) Line 2676	C
 blender-app.exe!BKE_object_handle_data_update(EvaluationContext * eval_ctx, Scene * scene, ...) Line 203	C
 blender-app.exe!BKE_object_handle_update_ex(EvaluationContext * eval_ctx, Scene * scene, Object * ob, ...) Line 3144	C
 blender-app.exe!scene_update_object_func(TaskPool * pool, ...) Line 1471	C
 blender-app.exe!task_scheduler_thread_run(void * thread_p) Line 164	C

Besides this there is another concurrent thread that currently executes BKE_mesh_calc_normals_poly()
This thread works on object C (which has a data transfer modifier defined with source Object B)

The Stack of the concurrent Thread is:

blender-app.exe!BKE_mesh_calc_poly_normal(const MPoly * mpoly, ...) Line 1797
blender-app.exe!BKE_mesh_calc_normals_poly$omp$1() Line 242
blender-app.exe!BKE_mesh_calc_normals_poly(MVert * mverts, ...) Line 244
blender-app.exe!CDDM_calc_loop_normals_spacearr(DerivedMesh * dm, ...) Line 2652
blender-app.exe!CDDM_calc_loop_normals(DerivedMesh * dm, ...) Line 2611
blender-app.exe!data_transfer_dtdata_type_preprocess(Object * UNUSED_ob_src, ...) Line 279
blender-app.exe!BKE_object_data_transfer_dm(Scene * scene, Object * ob_src, ...) Line 1171
blender-app.exe!applyModifier(ModifierData * md, Object * ob, ...) Line 211
blender-app.exe!modwrap_applyModifier(ModifierData * md, ...) Line 745
blender-app.exe!mesh_calc_modifiers(Scene * scene, Object * ob, ...) Line 2037
blender-app.exe!mesh_build_data(Scene * scene, Object * ob, ...) Line 2582
blender-app.exe!makeDerivedMesh(Scene * scene, Object * ob, BMEditMesh * em, ...) Line 2676
blender-app.exe!BKE_object_handle_data_update(EvaluationContext * eval_ctx, ...) Line 203
blender-app.exe!BKE_object_handle_update_ex(EvaluationContext * eval_ctx, ...) Line 3144
blender-app.exe!scene_update_object_func(TaskPool * pool, ...) Line 1471
blender-app.exe!task_scheduler_thread_run(void * thread_p) Line 164

I hope this is enough to reproduce the issue.

**Blender Version** Broken: development version (after 2.76) **Short description of error** I have 3 objects A, B, C data transfer modifier on A transfers data from B data transfer modifier on C transfers data from B When i move one of the objects around in object mode then occasionally Blender crashes. I can reproduce this behavior when all addons are disabled. And the problem goes away when i disable the data transfer modifiers. **Exact steps for others to reproduce the error** Open the included blend file [data_transfer_normals.blend](https://archive.blender.org/developer/F249844/data_transfer_normals.blend) select the middle object and move it around a bit. what seems to work "best" is: G z then move the mouse frantically on your desk. Sometimes the crash happens right away, sometimes it takes minutes to get it to appear. The crash takes longer to show up when blender is in debug mode, but i can get it to break there within a minuite. The crash happens always here: ``` static void customData_update_offsets(CustomData *data) { const LayerTypeInfo *typeInfo; int i, offset = 0; ``` ``` for (i = 0; i < data->totlayer; ++i) { typeInfo = layerType_getInfo(data->layers[i].type); ``` ``` data->layers[i].offset = offset; offset += typeInfo->size; /*<== Crash because typeinfo is NULL */ } ``` ``` data->totsize = offset; CustomData_update_typemap(data); } ``` The reason for this is the last data layer (5) is not initialized or contains broken data. Here is the content of data->layers- [x] when the crash happens: ``` data->layers[5] {type=-33686019 offset=72 flag=-1414812757 ...} CustomDataLayer type -33686019 int offset 72 int flag -1414812757 int active -1414812757 int active_rnd -1414812757 int active_clone -17891602 int active_mask -17891602 int uid -17891602 int name 0x000000001f551330 "" char[64] data 0x0000000000000000 void * ``` The Main thread works on Object A (which has a data transfer modifier defined with source Object B) The Stack of the Blender Main Thread is: ``` blender-app.exe!customData_update_offsets(CustomData * data) Line 1619 C blender-app.exe!customData_add_layer__internal(CustomData * data, ...) Line 1925 C blender-app.exe!CustomData_add_layer(CustomData * data, int type, int alloctype, void * layerdata, int totelem) Line 1935 C blender-app.exe!dm_getLoopArray(DerivedMesh * dm) Line 155 C blender-app.exe!CDDM_calc_loop_normals_spacearr(DerivedMesh * dm, ...) Line 2620 C blender-app.exe!CDDM_calc_loop_normals(DerivedMesh * dm, ...) Line 2611 C blender-app.exe!data_transfer_dtdata_type_preprocess(Object * UNUSED_ob_src, ...) Line 279 C blender-app.exe!BKE_object_data_transfer_dm(Scene * scene, Object * ob_src, ...) Line 1171 C blender-app.exe!applyModifier(ModifierData * md, Object * ob, ...) Line 211 C blender-app.exe!modwrap_applyModifier(ModifierData * md, ...) Line 745 C blender-app.exe!mesh_calc_modifiers(Scene * scene, Object * ob, ...) Line 2037 C blender-app.exe!mesh_build_data(Scene * scene, Object * ob, ...) Line 2582 C blender-app.exe!makeDerivedMesh(Scene * scene, Object * ob, BMEditMesh * em, ...) Line 2676 C blender-app.exe!BKE_object_handle_data_update(EvaluationContext * eval_ctx, Scene * scene, ...) Line 203 C blender-app.exe!BKE_object_handle_update_ex(EvaluationContext * eval_ctx, Scene * scene, Object * ob, ...) Line 3144 C blender-app.exe!scene_update_object_func(TaskPool * pool, ...) Line 1471 C blender-app.exe!task_scheduler_thread_run(void * thread_p) Line 164 C ``` Besides this there is another concurrent thread that currently executes BKE_mesh_calc_normals_poly() This thread works on object C (which has a data transfer modifier defined with source Object B) The Stack of the concurrent Thread is: ``` blender-app.exe!BKE_mesh_calc_poly_normal(const MPoly * mpoly, ...) Line 1797 blender-app.exe!BKE_mesh_calc_normals_poly$omp$1() Line 242 blender-app.exe!BKE_mesh_calc_normals_poly(MVert * mverts, ...) Line 244 blender-app.exe!CDDM_calc_loop_normals_spacearr(DerivedMesh * dm, ...) Line 2652 blender-app.exe!CDDM_calc_loop_normals(DerivedMesh * dm, ...) Line 2611 blender-app.exe!data_transfer_dtdata_type_preprocess(Object * UNUSED_ob_src, ...) Line 279 blender-app.exe!BKE_object_data_transfer_dm(Scene * scene, Object * ob_src, ...) Line 1171 blender-app.exe!applyModifier(ModifierData * md, Object * ob, ...) Line 211 blender-app.exe!modwrap_applyModifier(ModifierData * md, ...) Line 745 blender-app.exe!mesh_calc_modifiers(Scene * scene, Object * ob, ...) Line 2037 blender-app.exe!mesh_build_data(Scene * scene, Object * ob, ...) Line 2582 blender-app.exe!makeDerivedMesh(Scene * scene, Object * ob, BMEditMesh * em, ...) Line 2676 blender-app.exe!BKE_object_handle_data_update(EvaluationContext * eval_ctx, ...) Line 203 blender-app.exe!BKE_object_handle_update_ex(EvaluationContext * eval_ctx, ...) Line 3144 blender-app.exe!scene_update_object_func(TaskPool * pool, ...) Line 1471 blender-app.exe!task_scheduler_thread_run(void * thread_p) Line 164 ``` I hope this is enough to reproduce the issue.
Author
Member

Changed status to: 'Open'

Changed status to: 'Open'
Bastien Montagne was assigned by Gaia Clary 2015-11-02 11:39:27 +01:00
Author
Member

Added subscriber: @GaiaClary

Added subscriber: @GaiaClary
Author
Member

Added subscriber: @ideasman42

Added subscriber: @ideasman42

Seems 2+ modifiers will try to recalculate data on the source mesh at once.

https://developer.blender.org/diffusion/B/browse/master/source/blender/blenkernel/intern/data_transfer.c$277

Solutions could be...

  • Put a lock around calcLoopNormals call.
  • Have calcLoopNormals to take a data argument, so the data layers dm_src of aren't manipulated by multiple threads.
Seems 2+ modifiers will try to recalculate data on the source mesh at once. https://developer.blender.org/diffusion/B/browse/master/source/blender/blenkernel/intern/data_transfer.c$277 Solutions could be... - Put a lock around `calcLoopNormals` call. - Have `calcLoopNormals` to take a data argument, so the data layers `dm_src` of aren't manipulated by multiple threads.

Added subscriber: @Sergey

Added subscriber: @Sergey

Pfff… This actually ends up being a nice can of worms… :(

I spent some time this afternoon implementing idea we discussed with Campbell (making some kind of dm->getLoopNormals() which would take array of lnors as output arg, instead of modifying own CDlayers.

This is easy to add to DM, the problem here is data transfer code - it means we'll have to pass around poly_nors_src and loop_nors_src around in a bunch of functions, making even more complicated a piece of code that does not really need it. Even worse, it breaks the generic CDLayer interpolation system, which means we'd have to implement own handling for clnors, triple yuck. I’m really not inclined to keep going in that direction…

We could go to the quick and dirty solution (mutex lock for those DM functions that can modify internal CDlayers - I think we could have same kind of issues with even calcNormals() itself e.g., since it may create a vertex layer in case it's using orig mesh data...). But again finding all possible broken case will probably turn into can of you-know-what.

So, my idea currently would simply be to make a copy of source dm. That one would be local, so there should be no problem adding data layers to it… Not that nice for performances, but…

@ideasman42, @Sergey, what do you think?

Pfff… This actually ends up being a nice can of worms… :( I spent some time this afternoon implementing idea we discussed with Campbell (making some kind of `dm->getLoopNormals()` which would take array of lnors as output arg, instead of modifying own CDlayers. This is easy to add to DM, the problem here is data transfer code - it means we'll have to pass around `poly_nors_src` and `loop_nors_src` around in a bunch of functions, making even more complicated a piece of code that does not really need it. Even worse, it breaks the generic CDLayer interpolation system, which means we'd have to implement own handling for clnors, **triple yuck**. I’m really not inclined to keep going in that direction… We could go to the quick and dirty solution (mutex lock for those DM functions that can modify internal CDlayers - I think we could have same kind of issues with even `calcNormals()` itself e.g., since it may create a vertex layer in case it's using orig mesh data...). But again finding all possible broken case will probably turn into can of you-know-what. So, my idea currently would simply be to make a copy of source dm. That one would be local, so there should be no problem adding data layers to it… Not that nice for performances, but… @ideasman42, @Sergey, what do you think?

This issue was referenced by e43b6e2f97

This issue was referenced by e43b6e2f9725edd8cbe1ca8538c8a2bbdf1b45cd

Changed status from 'Open' to: 'Resolved'

Changed status from 'Open' to: 'Resolved'
Sign in to join this conversation.
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
5 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender#46672
No description provided.