Skip to content

Commit bd826b3

Browse files
author
Anselm Kruis
committed
merge 3.4-slp (Stackless python#115)
2 parents f050cf2 + 542af6e commit bd826b3

File tree

3 files changed

+44
-16
lines changed

3 files changed

+44
-16
lines changed

Python/ceval.c

+4-16
Original file line numberDiff line numberDiff line change
@@ -1788,22 +1788,10 @@ slp_eval_frame_value(PyFrameObject *f, int throwflag, PyObject *retval)
17881788
err = 0;
17891789
Py_DECREF(retval);
17901790

1791-
if (err >= 0) {
1792-
if (err > 0) {
1793-
/* There was an exception and a true return */
1794-
PyObject *v = SECOND();
1795-
PyObject *w = THIRD();
1796-
err = 0;
1797-
STACKADJ(-2);
1798-
Py_INCREF(Py_None);
1799-
SET_TOP(Py_None);
1800-
Py_DECREF(u);
1801-
Py_DECREF(v);
1802-
Py_DECREF(w);
1803-
} else {
1804-
/* The stack was rearranged to remove EXIT
1805-
above. Let END_FINALLY do its thing */
1806-
}
1791+
if (err > 0) {
1792+
err = 0;
1793+
/* There was an exception and a True return */
1794+
PUSH(PyLong_FromLong((long) WHY_SILENCED));
18071795
}
18081796
/* XXX: The main loop contains a PREDICT(END_FINALLY).
18091797
* I wonder, if we must use it here?

Stackless/changelog.txt

+4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ What's New in Stackless 3.X.X?
99

1010
*Release date: 20XX-XX-XX*
1111

12+
- https://bitbucket.org/stackless-dev/stackless/issues/115
13+
Fix an unlikely crash caused by an context manager, which silences an
14+
exception.
15+
1216
- https://bitbucket.org/stackless-dev/stackless/issues/117
1317
Fix various reference leaks:
1418
- Leak of a reference to Py_None in generator.throw()

Stackless/unittests/test_defects.py

+36
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,42 @@ def generator():
505505
frame.clear() # causes the failure
506506

507507

508+
class TestContextManager(StacklessTestCase):
509+
def test_crash_on_WHY_SILENCED(self):
510+
current_switch = stackless.current.switch
511+
steps = []
512+
513+
class CtxManager:
514+
def __enter__(self):
515+
steps.append(2)
516+
517+
def __exit__(self, exc_type, exc_val, exc_tb):
518+
steps.append(4)
519+
current_switch() # causes a stack corruption upon resuming __exit__
520+
steps.append(5)
521+
return True # silence the exception
522+
523+
def task():
524+
try:
525+
steps.append(1)
526+
return "OK"
527+
finally:
528+
with CtxManager():
529+
steps.append(3)
530+
1 // 0
531+
steps.append(6)
532+
# Stackless issue #115 ()
533+
# Leaving this finally block crashes Python,
534+
# because the interpreter stack is corrupt.
535+
536+
t = stackless.tasklet(task)()
537+
t.run()
538+
self.assertListEqual(steps, [1, 2, 3, 4])
539+
t.run()
540+
r = t.tempval
541+
self.assertListEqual(steps, [1, 2, 3, 4, 5, 6])
542+
543+
508544
if __name__ == '__main__':
509545
if not sys.argv[1:]:
510546
sys.argv.append('-v')

0 commit comments

Comments
 (0)