summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorJeremy Hylton <jeremy@alum.mit.edu>2001-02-23 17:55:27 (GMT)
committerJeremy Hylton <jeremy@alum.mit.edu>2001-02-23 17:55:27 (GMT)
commit74b3bc47df9979e54c1f0c7866730eb499705f0e (patch)
tree81c0697e22f1b41bb628669a016d3ad9dd49b203 /Python
parent3e13b1e48bdd0550929f55bac11571116cd655ab (diff)
downloadcpython-74b3bc47df9979e54c1f0c7866730eb499705f0e.zip
cpython-74b3bc47df9979e54c1f0c7866730eb499705f0e.tar.gz
cpython-74b3bc47df9979e54c1f0c7866730eb499705f0e.tar.bz2
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.
Diffstat (limited to 'Python')
-rw-r--r--Python/compile.c8
-rw-r--r--Python/symtable.c8
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);