summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorMoshe Zadka <moshez@math.huji.ac.il>2001-03-30 21:01:09 (GMT)
committerMoshe Zadka <moshez@math.huji.ac.il>2001-03-30 21:01:09 (GMT)
commit23ec9ebaf9bc0cb8fa17be69b07d793584797c49 (patch)
tree80df8b39e35e2b1fde1675486da3f9894f4f94e6 /Python
parent324ebb156fe776a5fe88536ea18bfefd9b475b5e (diff)
downloadcpython-23ec9ebaf9bc0cb8fa17be69b07d793584797c49.zip
cpython-23ec9ebaf9bc0cb8fa17be69b07d793584797c49.tar.gz
cpython-23ec9ebaf9bc0cb8fa17be69b07d793584797c49.tar.bz2
- exceptions.c - make_class() Added a "goto finally" so that if
populate_methods() fails, the return status will be -1 (failure) instead of 0 (success). fini_exceptions(): When decref'ing the static pointers to the exception classes, clear out their dictionaries too. This breaks a cycle from class->dict->method->class and allows the classes with unbound methods to be reclaimed. This plugs a large memory leak in a common Py_Initialize()/dosomething/Py_Finalize() loop.
Diffstat (limited to 'Python')
-rw-r--r--Python/exceptions.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/Python/exceptions.c b/Python/exceptions.c
index 6d6291c..7d3a46b 100644
--- a/Python/exceptions.c
+++ b/Python/exceptions.c
@@ -168,6 +168,7 @@ make_class(PyObject **klass, PyObject *base,
if (populate_methods(*klass, dict, methods)) {
Py_DECREF(*klass);
*klass = NULL;
+ goto finally;
}
status = 0;
@@ -1096,6 +1097,14 @@ fini_exceptions(void)
PyExc_MemoryErrorInst = NULL;
for (i=0; exctable[i].name; i++) {
+ /* clear the class's dictionary, freeing up circular references
+ * between the class and its methods.
+ */
+ PyObject* cdict = PyObject_GetAttrString(*exctable[i].exc, "__dict__");
+ PyDict_Clear(cdict);
+ Py_DECREF(cdict);
+
+ /* Now decref the exception class */
Py_XDECREF(*exctable[i].exc);
*exctable[i].exc = NULL;
}