[Bf-blender-cvs] [0f1ee611d44] blender-v2.93-release: Fix T85567: Crash accessing gizmo group on `__del__`

Campbell Barton noreply at git.blender.org
Sat Apr 24 15:40:44 CEST 2021


Commit: 0f1ee611d4499fbac050b7a997e50bc234a252f9
Author: Campbell Barton
Date:   Sat Apr 24 23:31:07 2021 +1000
Branches: blender-v2.93-release
https://developer.blender.org/rB0f1ee611d4499fbac050b7a997e50bc234a252f9

Fix T85567: Crash accessing gizmo group on `__del__`

- Re-order freeing so an instances __del__ method runs before the
  `ExtensionRNA` has been freed.

- "remove" functions no longer free the gizmo/gizmo-group memory,
  needed so the identifier used when freeing the extension
  doesn't use the freed identifier.

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

M	source/blender/makesrna/intern/rna_wm_gizmo.c
M	source/blender/windowmanager/gizmo/WM_gizmo_api.h
M	source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c
M	source/blender/windowmanager/gizmo/intern/wm_gizmo_group_type.c
M	source/blender/windowmanager/gizmo/intern/wm_gizmo_type.c

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

diff --git a/source/blender/makesrna/intern/rna_wm_gizmo.c b/source/blender/makesrna/intern/rna_wm_gizmo.c
index f7d139dd706..e91df38c96e 100644
--- a/source/blender/makesrna/intern/rna_wm_gizmo.c
+++ b/source/blender/makesrna/intern/rna_wm_gizmo.c
@@ -534,12 +534,16 @@ static void rna_Gizmo_unregister(struct Main *bmain, StructRNA *type)
     return;
   }
 
+  WM_gizmotype_remove_ptr(NULL, bmain, gzt);
+
+  /* Free extension after removing instances so `__del__` doesn't crash, see: T85567. */
   RNA_struct_free_extension(type, &gzt->rna_ext);
   RNA_struct_free(&BLENDER_RNA, type);
 
-  WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
+  /* Free gizmo group after the extension as it owns the identifier memory. */
+  WM_gizmotype_free_ptr(gzt);
 
-  WM_gizmotype_remove_ptr(NULL, bmain, gzt);
+  WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
 }
 
 static void **rna_Gizmo_instance(PointerRNA *ptr)
@@ -934,12 +938,16 @@ static void rna_GizmoGroup_unregister(struct Main *bmain, StructRNA *type)
     return;
   }
 
+  WM_gizmo_group_type_remove_ptr(bmain, gzgt);
+
+  /* Free extension after removing instances so `__del__` doesn't crash, see: T85567. */
   RNA_struct_free_extension(type, &gzgt->rna_ext);
   RNA_struct_free(&BLENDER_RNA, type);
 
-  WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
+  /* Free gizmo group after the extension as it owns the identifier memory. */
+  WM_gizmo_group_type_free_ptr(gzgt);
 
-  WM_gizmo_group_type_remove_ptr(bmain, gzgt);
+  WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
 }
 
 static void **rna_GizmoGroup_instance(PointerRNA *ptr)
diff --git a/source/blender/windowmanager/gizmo/WM_gizmo_api.h b/source/blender/windowmanager/gizmo/WM_gizmo_api.h
index cf1a7628267..c7a4b064d0e 100644
--- a/source/blender/windowmanager/gizmo/WM_gizmo_api.h
+++ b/source/blender/windowmanager/gizmo/WM_gizmo_api.h
@@ -146,6 +146,7 @@ void WM_gizmotype_append(void (*gtfunc)(struct wmGizmoType *));
 void WM_gizmotype_append_ptr(void (*gtfunc)(struct wmGizmoType *, void *), void *userdata);
 bool WM_gizmotype_remove(struct bContext *C, struct Main *bmain, const char *idname);
 void WM_gizmotype_remove_ptr(struct bContext *C, struct Main *bmain, struct wmGizmoType *gzt);
+void WM_gizmotype_free_ptr(struct wmGizmoType *gzt);
 void WM_gizmotype_iter(struct GHashIterator *ghi);
 
 /* wm_gizmo_group_type.c */
@@ -154,8 +155,6 @@ struct wmGizmoGroupType *WM_gizmogrouptype_append(void (*wtfunc)(struct wmGizmoG
 struct wmGizmoGroupType *WM_gizmogrouptype_append_ptr(void (*wtfunc)(struct wmGizmoGroupType *,
                                                                      void *),
                                                       void *userdata);
-bool WM_gizmogrouptype_free(const char *idname);
-void WM_gizmogrouptype_free_ptr(struct wmGizmoGroupType *gzgt);
 void WM_gizmogrouptype_iter(struct GHashIterator *ghi);
 
 struct wmGizmoGroupTypeRef *WM_gizmogrouptype_append_and_link(
@@ -378,6 +377,9 @@ void WM_gizmo_group_unlink_delayed_ptr_from_space(struct wmGizmoGroupType *gzgt,
                                                   struct wmGizmoMapType *gzmap_type,
                                                   struct ScrArea *area);
 
+void WM_gizmo_group_type_free_ptr(wmGizmoGroupType *gzgt);
+bool WM_gizmo_group_type_free(const char *idname);
+
 /* Has the result of unlinking and linking (re-initializes gizmo's). */
 void WM_gizmo_group_type_reinit_ptr_ex(struct Main *bmain,
                                        struct wmGizmoGroupType *gzgt,
diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c
index ca1684811d5..062731dfb3d 100644
--- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c
+++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c
@@ -1058,12 +1058,14 @@ bool WM_gizmo_group_type_ensure(const char *idname)
   return WM_gizmo_group_type_ensure_ptr(gzgt);
 }
 
+/**
+ * Call #WM_gizmo_group_type_free_ptr after to remove & free.
+ */
 void WM_gizmo_group_type_remove_ptr_ex(struct Main *bmain,
                                        wmGizmoGroupType *gzgt,
                                        wmGizmoMapType *gzmap_type)
 {
   WM_gizmomaptype_group_unlink(NULL, bmain, gzmap_type, gzgt);
-  WM_gizmogrouptype_free_ptr(gzgt);
 }
 void WM_gizmo_group_type_remove_ptr(struct Main *bmain, wmGizmoGroupType *gzgt)
 {
diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group_type.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group_type.c
index ab5a265547d..6ebeb5a76b6 100644
--- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group_type.c
+++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group_type.c
@@ -154,7 +154,7 @@ static void gizmogrouptype_free(wmGizmoGroupType *gzgt)
   MEM_freeN(gzgt);
 }
 
-void WM_gizmogrouptype_free_ptr(wmGizmoGroupType *gzgt)
+void WM_gizmo_group_type_free_ptr(wmGizmoGroupType *gzgt)
 {
   BLI_assert(gzgt == WM_gizmogrouptype_find(gzgt->idname, false));
 
@@ -165,7 +165,7 @@ void WM_gizmogrouptype_free_ptr(wmGizmoGroupType *gzgt)
   /* XXX, TODO, update the world! */
 }
 
-bool WM_gizmogrouptype_free(const char *idname)
+bool WM_gizmo_group_type_free(const char *idname)
 {
   wmGizmoGroupType *gzgt = BLI_ghash_lookup(global_gizmogrouptype_hash, idname);
 
@@ -173,7 +173,7 @@ bool WM_gizmogrouptype_free(const char *idname)
     return false;
   }
 
-  WM_gizmogrouptype_free_ptr(gzgt);
+  WM_gizmo_group_type_free_ptr(gzgt);
 
   return true;
 }
diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_type.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_type.c
index 185854b1ca0..1523246d08b 100644
--- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_type.c
+++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_type.c
@@ -121,7 +121,7 @@ void WM_gizmotype_append_ptr(void (*gtfunc)(struct wmGizmoType *, void *), void
 /**
  * Free but don't remove from ghash.
  */
-static void gizmotype_free(wmGizmoType *gzt)
+void WM_gizmotype_free_ptr(wmGizmoType *gzt)
 {
   if (gzt->rna_ext.srna) { /* python gizmo, allocs own string */
     MEM_freeN((void *)gzt->idname);
@@ -169,8 +169,6 @@ void WM_gizmotype_remove_ptr(bContext *C, Main *bmain, wmGizmoType *gzt)
   BLI_ghash_remove(global_gizmotype_hash, gzt->idname, NULL, NULL);
 
   gizmotype_unlink(C, bmain, gzt);
-
-  gizmotype_free(gzt);
 }
 
 bool WM_gizmotype_remove(bContext *C, Main *bmain, const char *idname)
@@ -186,9 +184,9 @@ bool WM_gizmotype_remove(bContext *C, Main *bmain, const char *idname)
   return true;
 }
 
-static void wm_gizmotype_ghash_free_cb(wmGizmoType *mt)
+static void wm_gizmotype_ghash_free_cb(wmGizmoType *gzt)
 {
-  gizmotype_free(mt);
+  WM_gizmotype_free_ptr(gzt);
 }
 
 void wm_gizmotype_free(void)



More information about the Bf-blender-cvs mailing list