From 74b3bc47df9979e54c1f0c7866730eb499705f0e Mon Sep 17 00:00:00 2001 From: Jeremy Hylton Date: Fri, 23 Feb 2001 17:55:27 +0000 Subject: Fix for bug 133489: compiler leaks memory Two different but related problems: 1. PySymtable_Free() must explicitly DECREF(st->st_cur), which should always point to the global symtable entry. This entry is setup by the first enter_scope() call, but there is never a corresponding exit_scope() call. Since each entry has a reference to scopes defined within it, the missing DECREF caused all symtable entries to be leaked. 2. The leak here masked a separate problem with PySymtableEntry_New(). When the requested entry was found in st->st_symbols, the entry was returned without doing an INCREF. And problem c) The ste_children slot was getting two copies of each child entry, because it was populating the slot on the first and second passes. Now only populate on the first pass. --- Python/compile.c | 8 ++++++-- Python/symtable.c | 8 +++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Python/compile.c b/Python/compile.c index f2d424b..7eac91a 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -3912,8 +3912,10 @@ jcompile(node *n, char *filename, struct compiling *base) PyErr_SetString(PyExc_SystemError, "lost syntax error"); } exit: - if (base == NULL) + if (base == NULL) { PySymtable_Free(sc.c_symtable); + sc.c_symtable = NULL; + } com_free(&sc); return co; } @@ -4193,6 +4195,7 @@ PySymtable_Free(struct symtable *st) { Py_XDECREF(st->st_symbols); Py_XDECREF(st->st_stack); + Py_XDECREF(st->st_cur); PyMem_Free((void *)st); } @@ -4359,10 +4362,11 @@ symtable_enter_scope(struct symtable *st, char *name, int type, PySymtableEntry_New(st, name, type, lineno); if (strcmp(name, TOP) == 0) st->st_global = st->st_cur->ste_symbols; - if (prev) + if (prev && st->st_pass == 1) { if (PyList_Append(prev->ste_children, (PyObject *)st->st_cur) < 0) st->st_errors++; + } } static int diff --git a/Python/symtable.c b/Python/symtable.c index 5dc0272..0d2e324 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -13,8 +13,10 @@ PySymtableEntry_New(struct symtable *st, char *name, int type, int lineno) if (k == NULL) goto fail; v = PyDict_GetItem(st->st_symbols, k); - if (v) /* XXX could check that name, type, lineno match */ - return v; + if (v) /* XXX could check that name, type, lineno match */ { + Py_INCREF(v); + return v; + } ste = (PySymtableEntryObject *)PyObject_New(PySymtableEntryObject, &PySymtableEntry_Type); @@ -69,7 +71,7 @@ PySymtableEntry_New(struct symtable *st, char *name, int type, int lineno) if (PyDict_SetItem(st->st_symbols, ste->ste_id, (PyObject *)ste) < 0) goto fail; - + return (PyObject *)ste; fail: Py_XDECREF(ste); -- cgit v0.12