Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 74b3bc4

Browse files
committed
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.
1 parent 3e13b1e commit 74b3bc4

2 files changed

Lines changed: 11 additions & 5 deletions

File tree

Python/compile.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3912,8 +3912,10 @@ jcompile(node *n, char *filename, struct compiling *base)
39123912
PyErr_SetString(PyExc_SystemError, "lost syntax error");
39133913
}
39143914
exit:
3915-
if (base == NULL)
3915+
if (base == NULL) {
39163916
PySymtable_Free(sc.c_symtable);
3917+
sc.c_symtable = NULL;
3918+
}
39173919
com_free(&sc);
39183920
return co;
39193921
}
@@ -4193,6 +4195,7 @@ PySymtable_Free(struct symtable *st)
41934195
{
41944196
Py_XDECREF(st->st_symbols);
41954197
Py_XDECREF(st->st_stack);
4198+
Py_XDECREF(st->st_cur);
41964199
PyMem_Free((void *)st);
41974200
}
41984201

@@ -4359,10 +4362,11 @@ symtable_enter_scope(struct symtable *st, char *name, int type,
43594362
PySymtableEntry_New(st, name, type, lineno);
43604363
if (strcmp(name, TOP) == 0)
43614364
st->st_global = st->st_cur->ste_symbols;
4362-
if (prev)
4365+
if (prev && st->st_pass == 1) {
43634366
if (PyList_Append(prev->ste_children,
43644367
(PyObject *)st->st_cur) < 0)
43654368
st->st_errors++;
4369+
}
43664370
}
43674371

43684372
static int

Python/symtable.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@ PySymtableEntry_New(struct symtable *st, char *name, int type, int lineno)
1313
if (k == NULL)
1414
goto fail;
1515
v = PyDict_GetItem(st->st_symbols, k);
16-
if (v) /* XXX could check that name, type, lineno match */
17-
return v;
16+
if (v) /* XXX could check that name, type, lineno match */ {
17+
Py_INCREF(v);
18+
return v;
19+
}
1820

1921
ste = (PySymtableEntryObject *)PyObject_New(PySymtableEntryObject,
2022
&PySymtableEntry_Type);
@@ -69,7 +71,7 @@ PySymtableEntry_New(struct symtable *st, char *name, int type, int lineno)
6971

7072
if (PyDict_SetItem(st->st_symbols, ste->ste_id, (PyObject *)ste) < 0)
7173
goto fail;
72-
74+
7375
return (PyObject *)ste;
7476
fail:
7577
Py_XDECREF(ste);

0 commit comments

Comments
 (0)