diff options
| author | Moshe Zadka <moshez@math.huji.ac.il> | 2001-03-30 21:01:09 (GMT) |
|---|---|---|
| committer | Moshe Zadka <moshez@math.huji.ac.il> | 2001-03-30 21:01:09 (GMT) |
| commit | 23ec9ebaf9bc0cb8fa17be69b07d793584797c49 (patch) | |
| tree | 80df8b39e35e2b1fde1675486da3f9894f4f94e6 /Python | |
| parent | 324ebb156fe776a5fe88536ea18bfefd9b475b5e (diff) | |
| download | cpython-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.c | 9 |
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; } |
