[Python] Fix memory leak.
SWIG python objects were being freed after the corresponding SWIG module information was destroyed in Python 3, causing leaks when as a result the object destructor could not be invoked. To prevent this misordering, SWIG python objects now obtain a reference to the Python capsule wrapping the module information, so that the module information is correctly destroyed after all SWIG python objects have been freed (and corresponding destructors invoked). Fixes #2154 Fixes #2208
This commit is contained in:
parent
f822bbf382
commit
e5996be10c
2 changed files with 22 additions and 2 deletions
|
|
@ -154,6 +154,17 @@ Version 4.1.0 (in progress)
|
||||||
things like `%std::vector<std::string>` now give an error rather
|
things like `%std::vector<std::string>` now give an error rather
|
||||||
than being quietly ignored.
|
than being quietly ignored.
|
||||||
|
|
||||||
|
2022-02-11: adr26
|
||||||
|
[Python] #2154 Fix memory leak.
|
||||||
|
|
||||||
|
SWIG python objects were being freed after the corresponding SWIG
|
||||||
|
module information was destroyed in Python 3, causing leaks when as
|
||||||
|
a result the object destructor could not be invoked. To prevent this
|
||||||
|
misordering, SWIG python objects now obtain a reference to the
|
||||||
|
Python capsule wrapping the module information, so that the module
|
||||||
|
information is correctly destroyed after all SWIG python objects
|
||||||
|
have been freed (and corresponding destructors invoked).
|
||||||
|
|
||||||
2022-02-10: olly
|
2022-02-10: olly
|
||||||
[Tcl] https://sourceforge.net/p/swig/bugs/1207/
|
[Tcl] https://sourceforge.net/p/swig/bugs/1207/
|
||||||
https://sourceforge.net/p/swig/bugs/1213/
|
https://sourceforge.net/p/swig/bugs/1213/
|
||||||
|
|
|
||||||
|
|
@ -719,6 +719,8 @@ SwigPyObject_Check(PyObject *op) {
|
||||||
SWIGRUNTIME PyObject *
|
SWIGRUNTIME PyObject *
|
||||||
SwigPyObject_New(void *ptr, swig_type_info *ty, int own);
|
SwigPyObject_New(void *ptr, swig_type_info *ty, int own);
|
||||||
|
|
||||||
|
static PyObject* Swig_Capsule_global = NULL;
|
||||||
|
|
||||||
SWIGRUNTIME void
|
SWIGRUNTIME void
|
||||||
SwigPyObject_dealloc(PyObject *v)
|
SwigPyObject_dealloc(PyObject *v)
|
||||||
{
|
{
|
||||||
|
|
@ -769,6 +771,7 @@ SwigPyObject_dealloc(PyObject *v)
|
||||||
printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown"));
|
printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown"));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Py_XDECREF(Swig_Capsule_global);
|
||||||
}
|
}
|
||||||
Py_XDECREF(next);
|
Py_XDECREF(next);
|
||||||
#ifdef SWIGPYTHON_BUILTIN
|
#ifdef SWIGPYTHON_BUILTIN
|
||||||
|
|
@ -994,6 +997,9 @@ SwigPyObject_New(void *ptr, swig_type_info *ty, int own)
|
||||||
#ifdef SWIGPYTHON_BUILTIN
|
#ifdef SWIGPYTHON_BUILTIN
|
||||||
sobj->dict = 0;
|
sobj->dict = 0;
|
||||||
#endif
|
#endif
|
||||||
|
if (own == SWIG_POINTER_OWN) {
|
||||||
|
Py_XINCREF(Swig_Capsule_global);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return (PyObject *)sobj;
|
return (PyObject *)sobj;
|
||||||
}
|
}
|
||||||
|
|
@ -1663,6 +1669,7 @@ SWIG_Python_DestroyModule(PyObject *obj)
|
||||||
Swig_Globals_global = NULL;
|
Swig_Globals_global = NULL;
|
||||||
Py_DECREF(SWIG_Python_TypeCache());
|
Py_DECREF(SWIG_Python_TypeCache());
|
||||||
Swig_TypeCache_global = NULL;
|
Swig_TypeCache_global = NULL;
|
||||||
|
Swig_Capsule_global = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SWIGRUNTIME void
|
SWIGRUNTIME void
|
||||||
|
|
@ -1676,7 +1683,9 @@ SWIG_Python_SetModule(swig_module_info *swig_module) {
|
||||||
#endif
|
#endif
|
||||||
PyObject *pointer = PyCapsule_New((void *) swig_module, SWIGPY_CAPSULE_NAME, SWIG_Python_DestroyModule);
|
PyObject *pointer = PyCapsule_New((void *) swig_module, SWIGPY_CAPSULE_NAME, SWIG_Python_DestroyModule);
|
||||||
if (pointer && module) {
|
if (pointer && module) {
|
||||||
if (PyModule_AddObject(module, "type_pointer_capsule" SWIG_TYPE_TABLE_NAME, pointer) != 0) {
|
if (PyModule_AddObject(module, "type_pointer_capsule" SWIG_TYPE_TABLE_NAME, pointer) == 0) {
|
||||||
|
Swig_Capsule_global = pointer;
|
||||||
|
} else {
|
||||||
Py_DECREF(pointer);
|
Py_DECREF(pointer);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue