diff options
| author | Phillip J. Eby <pje@telecommunity.com> | 2006-04-15 01:02:17 (GMT) |
|---|---|---|
| committer | Phillip J. Eby <pje@telecommunity.com> | 2006-04-15 01:02:17 (GMT) |
| commit | 8ebb28df3a6e0bce240b6c2aa20d7aa5a4dfef39 (patch) | |
| tree | 066424b3c1e37a639145e6453cb4f7d1b83b41e1 /Objects/frameobject.c | |
| parent | 3cfea2dc987b90e637c4cbd5db5dc1f542e448b2 (diff) | |
| download | cpython-8ebb28df3a6e0bce240b6c2aa20d7aa5a4dfef39.zip cpython-8ebb28df3a6e0bce240b6c2aa20d7aa5a4dfef39.tar.gz cpython-8ebb28df3a6e0bce240b6c2aa20d7aa5a4dfef39.tar.bz2 | |
Fix SF#1470508: crash in generator cycle finalization. There were two
problems: first, PyGen_NeedsFinalizing() had an off-by-one bug that
prevented it from ever saying a generator didn't need finalizing, and
second, frame objects cleared themselves in a way that caused their
owning generator to think they were still executable, causing a double
deallocation of objects on the value stack if there was still a loop
on the block stack. This revision also removes some unnecessary
close() operations from test_generators that are now appropriately
handled by the cycle collector.
Diffstat (limited to 'Objects/frameobject.c')
| -rw-r--r-- | Objects/frameobject.c | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 8aa3377..49f74cb 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -454,9 +454,15 @@ frame_traverse(PyFrameObject *f, visitproc visit, void *arg) static void frame_clear(PyFrameObject *f) { - PyObject **fastlocals, **p; + PyObject **fastlocals, **p, **oldtop; int i, slots; + oldtop = f->f_stacktop; + + /* Before anything else, make sure that this frame is clearly marked + as being defunct! */ + f->f_stacktop = NULL; + Py_XDECREF(f->f_exc_type); f->f_exc_type = NULL; @@ -473,17 +479,13 @@ frame_clear(PyFrameObject *f) slots = f->f_nlocals + f->f_ncells + f->f_nfreevars; fastlocals = f->f_localsplus; for (i = slots; --i >= 0; ++fastlocals) { - if (*fastlocals != NULL) { - Py_XDECREF(*fastlocals); - *fastlocals = NULL; - } + Py_CLEAR(*fastlocals); } /* stack */ - if (f->f_stacktop != NULL) { - for (p = f->f_valuestack; p < f->f_stacktop; p++) { - Py_XDECREF(*p); - *p = NULL; + if (oldtop != NULL) { + for (p = f->f_valuestack; p < oldtop; p++) { + Py_CLEAR(*p); } } } |
