PyAPI: report unreleased ID's with WITH_PYTHON_SAFETY enabled
This would have made T88033 more straightforward to track down.
This commit is contained in:
@@ -417,9 +417,6 @@ void BPy_init_modules(struct bContext *C)
|
||||
PyDict_SetItemString(PyImport_GetModuleDict(), "_bpy", mod);
|
||||
Py_DECREF(mod);
|
||||
|
||||
/* run first, initializes rna types */
|
||||
BPY_rna_init();
|
||||
|
||||
/* needs to be first so bpy_types can run */
|
||||
PyModule_AddObject(mod, "types", BPY_rna_types());
|
||||
|
||||
|
||||
@@ -502,7 +502,10 @@ void BPY_python_start(bContext *C, int argc, const char **argv)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* bpy.* and lets us import it */
|
||||
/* Run first, initializes RNA types. */
|
||||
BPY_rna_init();
|
||||
|
||||
/* Defines `bpy.*` and lets us import it. */
|
||||
BPy_init_modules(C);
|
||||
|
||||
pyrna_alloc_types();
|
||||
@@ -541,6 +544,8 @@ void BPY_python_end(void)
|
||||
/* free other python data. */
|
||||
pyrna_free_types();
|
||||
|
||||
BPY_rna_exit();
|
||||
|
||||
/* clear all python data from structs */
|
||||
|
||||
bpy_intern_string_exit();
|
||||
|
||||
@@ -181,23 +181,13 @@ static PyMethodDef id_free_weakref_cb_def = {
|
||||
/* Adds a reference to the list, remember to decref. */
|
||||
static GHash *id_weakref_pool_get(ID *id)
|
||||
{
|
||||
GHash *weakinfo_hash = NULL;
|
||||
|
||||
if (id_weakref_pool) {
|
||||
weakinfo_hash = BLI_ghash_lookup(id_weakref_pool, (void *)id);
|
||||
}
|
||||
else {
|
||||
/* First time, allocate pool. */
|
||||
id_weakref_pool = BLI_ghash_ptr_new("rna_global_pool");
|
||||
weakinfo_hash = NULL;
|
||||
}
|
||||
|
||||
GHash *weakinfo_hash = BLI_ghash_lookup(id_weakref_pool, (void *)id);
|
||||
if (weakinfo_hash == NULL) {
|
||||
/* We use a ghash as a set, we could use libHX's HXMAP_SINGULAR, but would be an extra dep. */
|
||||
/* This could be a set, values are used to keep a reference back to the ID
|
||||
* (all of them are the same). */
|
||||
weakinfo_hash = BLI_ghash_ptr_new("rna_id");
|
||||
BLI_ghash_insert(id_weakref_pool, id, weakinfo_hash);
|
||||
}
|
||||
|
||||
return weakinfo_hash;
|
||||
}
|
||||
|
||||
@@ -283,14 +273,6 @@ static void id_release_weakref_list(struct ID *id, GHash *weakinfo_hash)
|
||||
|
||||
BLI_ghash_remove(id_weakref_pool, (void *)id, NULL, NULL);
|
||||
BLI_ghash_free(weakinfo_hash, NULL, NULL);
|
||||
|
||||
if (BLI_ghash_len(id_weakref_pool) == 0) {
|
||||
BLI_ghash_free(id_weakref_pool, NULL, NULL);
|
||||
id_weakref_pool = NULL;
|
||||
# ifdef DEBUG_RNA_WEAKREF
|
||||
printf("id_release_weakref freeing pool\n");
|
||||
# endif
|
||||
}
|
||||
}
|
||||
|
||||
static void id_release_weakref(struct ID *id)
|
||||
@@ -310,7 +292,8 @@ void BPY_id_release(struct ID *id)
|
||||
#endif
|
||||
|
||||
#ifdef USE_PYRNA_INVALIDATE_WEAKREF
|
||||
if (id_weakref_pool) {
|
||||
/* Check for NULL since this may run before Python has been started. */
|
||||
if (id_weakref_pool != NULL) {
|
||||
PyGILState_STATE gilstate = PyGILState_Ensure();
|
||||
|
||||
id_release_weakref(id);
|
||||
@@ -7776,6 +7759,32 @@ void BPY_rna_init(void)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_PYRNA_INVALIDATE_WEAKREF
|
||||
BLI_assert(id_weakref_pool == NULL);
|
||||
id_weakref_pool = BLI_ghash_ptr_new("rna_global_pool");
|
||||
#endif
|
||||
}
|
||||
|
||||
void BPY_rna_exit(void)
|
||||
{
|
||||
#ifdef USE_PYRNA_INVALIDATE_WEAKREF
|
||||
/* This can help track down which kinds of data were not released.
|
||||
* If they were in fact freed by Blender, printing their names
|
||||
* will crash giving a useful error with address sanitizer. The likely cause
|
||||
* for this list not being empty is a missing call to: #BKE_libblock_free_data_py. */
|
||||
const int id_weakref_pool_len = BLI_ghash_len(id_weakref_pool);
|
||||
if (id_weakref_pool_len != id_weakref_pool_len) {
|
||||
printf("Found %d unreleased ID's\n", id_weakref_pool_len);
|
||||
GHashIterator gh_iter;
|
||||
GHASH_ITER (gh_iter, id_weakref_pool) {
|
||||
ID *id = BLI_ghashIterator_getKey(&gh_iter);
|
||||
printf("ID: %s\n", id->name);
|
||||
}
|
||||
}
|
||||
BLI_ghash_free(id_weakref_pool, NULL, NULL);
|
||||
id_weakref_pool = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* 'bpy.data' from Python. */
|
||||
|
||||
@@ -181,6 +181,7 @@ StructRNA *srna_from_self(PyObject *self, const char *error_prefix);
|
||||
StructRNA *pyrna_struct_as_srna(PyObject *self, const bool parent, const char *error_prefix);
|
||||
|
||||
void BPY_rna_init(void);
|
||||
void BPY_rna_exit(void);
|
||||
PyObject *BPY_rna_module(void);
|
||||
void BPY_update_rna_module(void);
|
||||
// PyObject *BPY_rna_doc(void);
|
||||
|
||||
Reference in New Issue
Block a user