[Python-checkins] bpo-33418: Add tp_clear for function object (GH-8058)
INADA Naoki
webhook-mailer at python.org
Tue Jul 3 22:16:00 EDT 2018
https://github.com/python/cpython/commit/3c452404ae178b742967589a0bb4a5ec768d76e0
commit: 3c452404ae178b742967589a0bb4a5ec768d76e0
branch: master
author: INADA Naoki <methane at users.noreply.github.com>
committer: GitHub <noreply at github.com>
date: 2018-07-04T11:15:50+09:00
summary:
bpo-33418: Add tp_clear for function object (GH-8058)
Without tp_clear, GC can't break cyclic reference.
It will cause memory leak when cyclic reference is
created intentionally.
files:
A Misc/NEWS.d/next/Core and Builtins/2018-07-03-19-00-10.bpo-33418.cfGm3n.rst
M Objects/funcobject.c
diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-07-03-19-00-10.bpo-33418.cfGm3n.rst b/Misc/NEWS.d/next/Core and Builtins/2018-07-03-19-00-10.bpo-33418.cfGm3n.rst
new file mode 100644
index 000000000000..8f136c6a35c1
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2018-07-03-19-00-10.bpo-33418.cfGm3n.rst
@@ -0,0 +1,2 @@
+Fix potential memory leak in function object when it creates reference
+cycle.
diff --git a/Objects/funcobject.c b/Objects/funcobject.c
index 241685d5b7bb..c2f79c05dbb2 100644
--- a/Objects/funcobject.c
+++ b/Objects/funcobject.c
@@ -523,23 +523,31 @@ func_new_impl(PyTypeObject *type, PyCodeObject *code, PyObject *globals,
return (PyObject *)newfunc;
}
+static int
+func_clear(PyFunctionObject *op)
+{
+ Py_CLEAR(op->func_code);
+ Py_CLEAR(op->func_globals);
+ Py_CLEAR(op->func_module);
+ Py_CLEAR(op->func_name);
+ Py_CLEAR(op->func_defaults);
+ Py_CLEAR(op->func_kwdefaults);
+ Py_CLEAR(op->func_doc);
+ Py_CLEAR(op->func_dict);
+ Py_CLEAR(op->func_closure);
+ Py_CLEAR(op->func_annotations);
+ Py_CLEAR(op->func_qualname);
+ return 0;
+}
+
static void
func_dealloc(PyFunctionObject *op)
{
_PyObject_GC_UNTRACK(op);
- if (op->func_weakreflist != NULL)
+ if (op->func_weakreflist != NULL) {
PyObject_ClearWeakRefs((PyObject *) op);
- Py_DECREF(op->func_code);
- Py_DECREF(op->func_globals);
- Py_XDECREF(op->func_module);
- Py_DECREF(op->func_name);
- Py_XDECREF(op->func_defaults);
- Py_XDECREF(op->func_kwdefaults);
- Py_XDECREF(op->func_doc);
- Py_XDECREF(op->func_dict);
- Py_XDECREF(op->func_closure);
- Py_XDECREF(op->func_annotations);
- Py_XDECREF(op->func_qualname);
+ }
+ (void)func_clear(op);
PyObject_GC_Del(op);
}
@@ -612,7 +620,7 @@ PyTypeObject PyFunction_Type = {
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
func_new__doc__, /* tp_doc */
(traverseproc)func_traverse, /* tp_traverse */
- 0, /* tp_clear */
+ (inquiry)func_clear, /* tp_clear */
0, /* tp_richcompare */
offsetof(PyFunctionObject, func_weakreflist), /* tp_weaklistoffset */
0, /* tp_iter */
More information about the Python-checkins
mailing list