From: Moshe Zadka Date: Fri, 30 Mar 2001 21:01:09 +0000 (+0000) Subject: - exceptions.c - make_class() Added a "goto finally" so that if X-Git-Tag: v2.0.1c1~47 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=23ec9ebaf9bc0cb8fa17be69b07d793584797c49;p=thirdparty%2FPython%2Fcpython.git - 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. --- diff --git a/Misc/NEWS b/Misc/NEWS index f4e038386e24..8435758e113a 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -52,6 +52,18 @@ http://sourceforge.net/tracker/index.php?func=detail&aid=&group_id=5470&atid - del func.func_defaults raises a TypeError instead of dumping core +- #121013 - stringobject.c -- "".join(u"this is a test") dumped core + +- 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. + What's New in Python 2.0? ========================= diff --git a/Python/exceptions.c b/Python/exceptions.c index 6d6291ce3225..7d3a46b19f59 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; }