From 0367c73026bf41adcfe478417a75673651a41f80 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 22 Jun 2018 20:49:19 +0200 Subject: [PATCH] py_panda: fix leak of reference counted class with inaccessible dtor If a class inherits from ReferenceCount, it can be destructed by downcasting to ReferenceCount, so it should not be an obstacle to properly clean it up when such a class is returned from C++. This issue comes up when a CycleData is returned via MemoryUsagePointers, which is not exposed so is wrapped as NodeReferenceCount instead, which has a protected destructor. --- dtool/src/interrogatedb/py_panda.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/dtool/src/interrogatedb/py_panda.h b/dtool/src/interrogatedb/py_panda.h index 4025b965d5..258ff66484 100644 --- a/dtool/src/interrogatedb/py_panda.h +++ b/dtool/src/interrogatedb/py_panda.h @@ -158,6 +158,16 @@ static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\ Py_TYPE(self)->tp_free(self);\ } +#define Define_Dtool_FreeInstanceRef_Private(CLASS_NAME,CNAME)\ +static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\ + if (DtoolInstance_VOID_PTR(self) != nullptr) {\ + if (((Dtool_PyInstDef *)self)->_memory_rules) {\ + unref_delete((ReferenceCount *)(CNAME *)DtoolInstance_VOID_PTR(self));\ + }\ + }\ + Py_TYPE(self)->tp_free(self);\ +} + #define Define_Dtool_Simple_FreeInstance(CLASS_NAME, CNAME)\ static void Dtool_FreeInstance_##CLASS_NAME(PyObject *self) {\ ((Dtool_InstDef_##CLASS_NAME *)self)->_value.~##CLASS_NAME();\ @@ -292,7 +302,7 @@ Define_Dtool_Class(MODULE_NAME,CLASS_NAME,PUBLIC_NAME) #define Define_Module_ClassRef_Private(MODULE_NAME,CLASS_NAME,CNAME,PUBLIC_NAME)\ Define_Module_Class_Internal(MODULE_NAME,CLASS_NAME,CNAME)\ Define_Dtool_new(CLASS_NAME,CNAME)\ -Define_Dtool_FreeInstance_Private(CLASS_NAME,CNAME)\ +Define_Dtool_FreeInstanceRef_Private(CLASS_NAME,CNAME)\ Define_Dtool_Class(MODULE_NAME,CLASS_NAME,PUBLIC_NAME) #define Define_Module_ClassRef(MODULE_NAME,CLASS_NAME,CNAME,PUBLIC_NAME)\