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.
This commit is contained in:
Campbell Barton 2021-04-24 23:31:07 +10:00
parent aa95f8019e
commit 0f1ee611d4
Notes: blender-bot 2023-02-14 05:16:25 +01:00
Referenced by issue #85567, Crash when accessing a 'GizmoGroup' attribute on '__del__'
5 changed files with 25 additions and 15 deletions

View File

@ -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)

View File

@ -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,

View File

@ -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)
{

View File

@ -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;
}

View File

@ -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)