[Bf-blender-cvs] [21ea4995585] blender-v3.3-release: Fix T100286: Crash accessing freed depsgraph object instances

Campbell Barton noreply at git.blender.org
Tue Aug 23 15:05:21 CEST 2022


Commit: 21ea4995585931ad54f51c1878c06c526c3355a5
Author: Campbell Barton
Date:   Tue Aug 23 22:56:54 2022 +1000
Branches: blender-v3.3-release
https://developer.blender.org/rB21ea4995585931ad54f51c1878c06c526c3355a5

Fix T100286: Crash accessing freed depsgraph object instances

Invalidate depsgraph.object_instances when freed, this resolves a crash
when accessing the object instances after iteration has finished.

Unlike most other collections, object_instances is only valid while the
iterator is in-memory.

The Python/RNA API needs to inline int/string collection lookups so the
Python instance can be created before the iterator ends.

Reviewed By: mont29, sergey

Ref D15755

===================================================================

M	source/blender/makesrna/RNA_access.h
M	source/blender/makesrna/intern/rna_access.c
M	source/blender/makesrna/intern/rna_depsgraph.c
M	source/blender/python/intern/bpy_rna.c

===================================================================

diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index de9fa60aa5d..ddc010f27a1 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -430,6 +430,10 @@ int RNA_property_collection_lookup_string(PointerRNA *ptr,
                                           PointerRNA *r_ptr);
 int RNA_property_collection_lookup_string_index(
     PointerRNA *ptr, PropertyRNA *prop, const char *key, PointerRNA *r_ptr, int *r_index);
+
+bool RNA_property_collection_lookup_int_has_fn(PropertyRNA *prop);
+bool RNA_property_collection_lookup_string_has_fn(PropertyRNA *prop);
+
 /**
  * Zero return is an assignment error.
  */
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 04707c01d6b..56cbcb2a7f2 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -4080,6 +4080,20 @@ int RNA_property_collection_lookup_index(PointerRNA *ptr,
   return -1;
 }
 
+bool RNA_property_collection_lookup_int_has_fn(PropertyRNA *prop)
+{
+  BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
+  CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)rna_ensure_property(prop);
+  return cprop->lookupint != NULL;
+}
+
+bool RNA_property_collection_lookup_string_has_fn(PropertyRNA *prop)
+{
+  BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
+  CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)rna_ensure_property(prop);
+  return cprop->lookupstring != NULL;
+}
+
 int RNA_property_collection_lookup_int(PointerRNA *ptr,
                                        PropertyRNA *prop,
                                        int key,
diff --git a/source/blender/makesrna/intern/rna_depsgraph.c b/source/blender/makesrna/intern/rna_depsgraph.c
index 6196f8d1ca0..f0d26362cad 100644
--- a/source/blender/makesrna/intern/rna_depsgraph.c
+++ b/source/blender/makesrna/intern/rna_depsgraph.c
@@ -43,23 +43,41 @@
 
 /* **************** Object Instance **************** */
 
+typedef struct RNA_DepsgraphIterator {
+  BLI_Iterator iter;
+#  ifdef WITH_PYTHON
+  /**
+   * Store the Python instance so the #BPy_StructRNA can be set as invalid iteration is completed.
+   * Otherwise accessing from Python (console auto-complete for e.g.) crashes, see: T100286. */
+  void *py_instance;
+#  endif
+} RNA_DepsgraphIterator;
+
+#  ifdef WITH_PYTHON
+void **rna_DepsgraphIterator_instance(PointerRNA *ptr)
+{
+  RNA_DepsgraphIterator *di = ptr->data;
+  return &di->py_instance;
+}
+#  endif
+
 static PointerRNA rna_DepsgraphObjectInstance_object_get(PointerRNA *ptr)
 {
-  BLI_Iterator *iterator = ptr->data;
-  return rna_pointer_inherit_refine(ptr, &RNA_Object, iterator->current);
+  RNA_DepsgraphIterator *di = ptr->data;
+  return rna_pointer_inherit_refine(ptr, &RNA_Object, di->iter.current);
 }
 
 static int rna_DepsgraphObjectInstance_is_instance_get(PointerRNA *ptr)
 {
-  BLI_Iterator *iterator = ptr->data;
-  DEGObjectIterData *deg_iter = (DEGObjectIterData *)iterator->data;
+  RNA_DepsgraphIterator *di = ptr->data;
+  DEGObjectIterData *deg_iter = (DEGObjectIterData *)di->iter.data;
   return (deg_iter->dupli_object_current != NULL);
 }
 
 static PointerRNA rna_DepsgraphObjectInstance_instance_object_get(PointerRNA *ptr)
 {
-  BLI_Iterator *iterator = ptr->data;
-  DEGObjectIterData *deg_iter = (DEGObjectIterData *)iterator->data;
+  RNA_DepsgraphIterator *di = ptr->data;
+  DEGObjectIterData *deg_iter = (DEGObjectIterData *)di->iter.data;
   Object *instance_object = NULL;
   if (deg_iter->dupli_object_current != NULL) {
     instance_object = deg_iter->dupli_object_current->ob;
@@ -69,24 +87,24 @@ static PointerRNA rna_DepsgraphObjectInstance_instance_object_get(PointerRNA *pt
 
 static bool rna_DepsgraphObjectInstance_show_self_get(PointerRNA *ptr)
 {
-  BLI_Iterator *iterator = ptr->data;
-  DEGObjectIterData *deg_iter = (DEGObjectIterData *)iterator->data;
-  int ob_visibility = BKE_object_visibility(iterator->current, deg_iter->eval_mode);
+  RNA_DepsgraphIterator *di = ptr->data;
+  DEGObjectIterData *deg_iter = (DEGObjectIterData *)di->iter.data;
+  int ob_visibility = BKE_object_visibility(di->iter.current, deg_iter->eval_mode);
   return (ob_visibility & OB_VISIBLE_SELF) != 0;
 }
 
 static bool rna_DepsgraphObjectInstance_show_particles_get(PointerRNA *ptr)
 {
-  BLI_Iterator *iterator = ptr->data;
-  DEGObjectIterData *deg_iter = (DEGObjectIterData *)iterator->data;
-  int ob_visibility = BKE_object_visibility(iterator->current, deg_iter->eval_mode);
+  RNA_DepsgraphIterator *di = ptr->data;
+  DEGObjectIterData *deg_iter = (DEGObjectIterData *)di->iter.data;
+  int ob_visibility = BKE_object_visibility(di->iter.current, deg_iter->eval_mode);
   return (ob_visibility & OB_VISIBLE_PARTICLES) != 0;
 }
 
 static PointerRNA rna_DepsgraphObjectInstance_parent_get(PointerRNA *ptr)
 {
-  BLI_Iterator *iterator = ptr->data;
-  DEGObjectIterData *deg_iter = (DEGObjectIterData *)iterator->data;
+  RNA_DepsgraphIterator *di = ptr->data;
+  DEGObjectIterData *deg_iter = (DEGObjectIterData *)di->iter.data;
   Object *dupli_parent = NULL;
   if (deg_iter->dupli_object_current != NULL) {
     dupli_parent = deg_iter->dupli_parent;
@@ -96,8 +114,8 @@ static PointerRNA rna_DepsgraphObjectInstance_parent_get(PointerRNA *ptr)
 
 static PointerRNA rna_DepsgraphObjectInstance_particle_system_get(PointerRNA *ptr)
 {
-  BLI_Iterator *iterator = ptr->data;
-  DEGObjectIterData *deg_iter = (DEGObjectIterData *)iterator->data;
+  RNA_DepsgraphIterator *di = ptr->data;
+  DEGObjectIterData *deg_iter = (DEGObjectIterData *)di->iter.data;
   struct ParticleSystem *particle_system = NULL;
   if (deg_iter->dupli_object_current != NULL) {
     particle_system = deg_iter->dupli_object_current->particle_system;
@@ -107,8 +125,8 @@ static PointerRNA rna_DepsgraphObjectInstance_particle_system_get(PointerRNA *pt
 
 static void rna_DepsgraphObjectInstance_persistent_id_get(PointerRNA *ptr, int *persistent_id)
 {
-  BLI_Iterator *iterator = ptr->data;
-  DEGObjectIterData *deg_iter = (DEGObjectIterData *)iterator->data;
+  RNA_DepsgraphIterator *di = ptr->data;
+  DEGObjectIterData *deg_iter = (DEGObjectIterData *)di->iter.data;
   if (deg_iter->dupli_object_current != NULL) {
     memcpy(persistent_id,
            deg_iter->dupli_object_current->persistent_id,
@@ -121,8 +139,8 @@ static void rna_DepsgraphObjectInstance_persistent_id_get(PointerRNA *ptr, int *
 
 static unsigned int rna_DepsgraphObjectInstance_random_id_get(PointerRNA *ptr)
 {
-  BLI_Iterator *iterator = ptr->data;
-  DEGObjectIterData *deg_iter = (DEGObjectIterData *)iterator->data;
+  RNA_DepsgraphIterator *di = ptr->data;
+  DEGObjectIterData *deg_iter = (DEGObjectIterData *)di->iter.data;
   if (deg_iter->dupli_object_current != NULL) {
     return deg_iter->dupli_object_current->random_id;
   }
@@ -133,23 +151,23 @@ static unsigned int rna_DepsgraphObjectInstance_random_id_get(PointerRNA *ptr)
 
 static void rna_DepsgraphObjectInstance_matrix_world_get(PointerRNA *ptr, float *mat)
 {
-  BLI_Iterator *iterator = ptr->data;
-  DEGObjectIterData *deg_iter = (DEGObjectIterData *)iterator->data;
+  RNA_DepsgraphIterator *di = ptr->data;
+  DEGObjectIterData *deg_iter = (DEGObjectIterData *)di->iter.data;
   if (deg_iter->dupli_object_current != NULL) {
     copy_m4_m4((float(*)[4])mat, deg_iter->dupli_object_current->mat);
   }
   else {
     /* We can return actual object's matrix here, no reason to return identity matrix
      * when this is not actually an instance... */
-    Object *ob = (Object *)iterator->current;
+    Object *ob = (Object *)di->iter.current;
     copy_m4_m4((float(*)[4])mat, ob->obmat);
   }
 }
 
 static void rna_DepsgraphObjectInstance_orco_get(PointerRNA *ptr, float *orco)
 {
-  BLI_Iterator *iterator = ptr->data;
-  DEGObjectIterData *deg_iter = (DEGObjectIterData *)iterator->data;
+  RNA_DepsgraphIterator *di = ptr->data;
+  DEGObjectIterData *deg_iter = (DEGObjectIterData *)di->iter.data;
   if (deg_iter->dupli_object_current != NULL) {
     copy_v3_v3(orco, deg_iter->dupli_object_current->orco);
   }
@@ -160,8 +178,8 @@ static void rna_DepsgraphObjectInstance_orco_get(PointerRNA *ptr, float *orco)
 
 static void rna_DepsgraphObjectInstance_uv_get(PointerRNA *ptr, float *uv)
 {
-  BLI_Iterator *iterator = ptr->data;
-  DEGObjectIterData *deg_iter = (DEGObjectIterData *)iterator->data;
+  RNA_DepsgraphIterator *di = ptr->data;
+  DEGObjectIterData *deg_iter = (DEGObjectIterData *)di->iter.data;
   if (deg_iter->dupli_object_current != NULL) {
     copy_v2_v2(uv, deg_iter->dupli_object_current->uv);
   }
@@ -321,7 +339,7 @@ static PointerRNA rna_Depsgraph_objects_get(CollectionPropertyIterator *iter)
  * so that previous one remains valid memory for python to access to. Yuck.
  */
 typedef struct RNA_Depsgraph_Instances_Iterator {
-  BLI_Iterator iterators[2];
+  RNA_DepsgraphIterator iterators[2];
   DEGObjectIterData deg_data[2];
   DupliObject dupli_object_current[2];
   int counter;
@@ -337,9 +355,9 @@ static void rna_Depsgraph_object_instances_begin(CollectionPropertyIterator *ite
   data->flag = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET |
                DEG_ITER_OBJECT_FLAG_VISIBLE | DEG_ITER_OBJECT_FLAG_DUPLI;
 
-  di_it->iterators[0].valid = true;
-  DEG_iterator_objects_begin(&di_it->iterators[0], data);
-  iter->valid = di_it->iterators[0].valid;
+  di_it->iterators[0].iter.valid = true;
+  DEG_iterator_objects_begin(&di_it->iterators[0].iter, data);
+  iter->valid = di_it->iterators[0].iter.valid;
 }
 
 static void rna_Depsgraph_object_instances_next(CollectionPropertyIterator *iter)
@@ -348,12 +366,12 @@ static void rna_Depsgraph_object_instances_next(CollectionPropertyIterator *iter
                                                 iter->internal.custom;
 
   /* We need to copy current iterator status to next one being worked on. */
-  di_it->iterators[(di_it->counter + 1) % 2] = di_it->iterators[di_it->counter % 2];
+  di_it->iterators[(di_it->counter + 1) % 2].iter = di_it->iterators[di_it->counter % 2].iter;
   di_it->deg_data[(di_it->counter + 1) % 2] = di_it->deg_data[di_it->counter % 2];
   di_i

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list