]> granicus.if.org Git - python/commitdiff
Fix for bug 133489: compiler leaks memory
authorJeremy Hylton <jeremy@alum.mit.edu>
Fri, 23 Feb 2001 17:55:27 +0000 (17:55 +0000)
committerJeremy Hylton <jeremy@alum.mit.edu>
Fri, 23 Feb 2001 17:55:27 +0000 (17:55 +0000)
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
Python/symtable.c

index f2d424b291b550c1bbff26f2ba14f89fbec63f54..7eac91ab5a5054c5e6e80c996d8527f95143343f 100644 (file)
@@ -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
index 5dc0272daca9db968ddd1bf6e4854583082e21e3..0d2e3243a1e9c74f10eb24607df13acb3a15d905 100644 (file)
@@ -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);