mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
[3.10] gh-94207: Fix struct module leak (GH-94239) (GH-94266)
* gh-94207: Fix struct module leak (GH-94239)
Make _struct.Struct a GC type
This fixes a memory leak in the _struct module, where as soon
as a Struct object is stored in the cache, there's a cycle from
the _struct module to the cache to Struct objects to the Struct
type back to the module. If _struct.Struct is not gc-tracked, that
cycle is never collected.
This PR makes _struct.Struct GC-tracked, and adds a regression test.
(cherry picked from commit 6b865349aa
)
Co-authored-by: Mark Dickinson <dickinsm@gmail.com>
This commit is contained in:
parent
14943829a8
commit
86e49a5026
3 changed files with 40 additions and 2 deletions
|
@ -1495,10 +1495,26 @@ Struct___init___impl(PyStructObject *self, PyObject *format)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
s_clear(PyStructObject *s)
|
||||
{
|
||||
Py_CLEAR(s->s_format);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
s_traverse(PyStructObject *s, visitproc visit, void *arg)
|
||||
{
|
||||
Py_VISIT(Py_TYPE(s));
|
||||
Py_VISIT(s->s_format);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
s_dealloc(PyStructObject *s)
|
||||
{
|
||||
PyTypeObject *tp = Py_TYPE(s);
|
||||
PyObject_GC_UnTrack(s);
|
||||
if (s->weakreflist != NULL)
|
||||
PyObject_ClearWeakRefs((PyObject *)s);
|
||||
if (s->s_codes != NULL) {
|
||||
|
@ -2079,13 +2095,15 @@ static PyType_Slot PyStructType_slots[] = {
|
|||
{Py_tp_getattro, PyObject_GenericGetAttr},
|
||||
{Py_tp_setattro, PyObject_GenericSetAttr},
|
||||
{Py_tp_doc, (void*)s__doc__},
|
||||
{Py_tp_traverse, s_traverse},
|
||||
{Py_tp_clear, s_clear},
|
||||
{Py_tp_methods, s_methods},
|
||||
{Py_tp_members, s_members},
|
||||
{Py_tp_getset, s_getsetlist},
|
||||
{Py_tp_init, Struct___init__},
|
||||
{Py_tp_alloc, PyType_GenericAlloc},
|
||||
{Py_tp_new, s_new},
|
||||
{Py_tp_free, PyObject_Del},
|
||||
{Py_tp_free, PyObject_GC_Del},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
|
@ -2093,7 +2111,7 @@ static PyType_Spec PyStructType_spec = {
|
|||
"_struct.Struct",
|
||||
sizeof(PyStructObject),
|
||||
0,
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,
|
||||
PyStructType_slots
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue