diff options
-rw-r--r-- | Lib/test/test_exceptions.py | 13 | ||||
-rw-r--r-- | Python/ceval.c | 38 |
2 files changed, 28 insertions, 23 deletions
diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index 753e33b..aa77292 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -5,8 +5,6 @@ import sys import unittest import pickle import weakref -import gc -import traceback from test.support import TESTFN, unlink, run_unittest @@ -553,9 +551,9 @@ class ExceptionTests(unittest.TestCase): del g self.assertEquals(sys.exc_info()[0], TypeError) - def test_crash_3114(self): - # Bug #3114: in its destructor, MyObject retrieves a pointer to a - # deallocated exception instance or traceback. + def test_3114(self): + # Bug #3114: in its destructor, MyObject retrieves a pointer to + # obsolete and/or deallocated objects. class MyObject: def __del__(self): nonlocal e @@ -565,10 +563,7 @@ class ExceptionTests(unittest.TestCase): raise Exception(MyObject()) except: pass - gc.collect() - [0]*10000 - # Do something with the exception and its traceback - traceback.format_exception(*e) + self.assertEquals(e, (None, None, None)) def test_main(): run_unittest(ExceptionTests) diff --git a/Python/ceval.c b/Python/ceval.c index 4b14784..ec279bf 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -699,29 +699,39 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) } #define UNWIND_EXCEPT_HANDLER(b) \ - assert(STACK_LEVEL() >= (b)->b_level + 3); \ - while (STACK_LEVEL() > (b)->b_level + 3) { \ - PyObject *v = POP(); \ - Py_XDECREF(v); \ - } \ - Py_CLEAR(tstate->exc_type); \ - Py_CLEAR(tstate->exc_value); \ - Py_CLEAR(tstate->exc_traceback); \ - tstate->exc_type = POP(); \ - tstate->exc_value = POP(); \ - tstate->exc_traceback = POP(); + { \ + PyObject *type, *value, *traceback; \ + assert(STACK_LEVEL() >= (b)->b_level + 3); \ + while (STACK_LEVEL() > (b)->b_level + 3) { \ + value = POP(); \ + Py_XDECREF(value); \ + } \ + type = tstate->exc_type; \ + value = tstate->exc_value; \ + traceback = tstate->exc_traceback; \ + tstate->exc_type = POP(); \ + tstate->exc_value = POP(); \ + tstate->exc_traceback = POP(); \ + Py_XDECREF(type); \ + Py_XDECREF(value); \ + Py_XDECREF(traceback); \ + } #define SAVE_EXC_STATE() \ { \ + PyObject *type, *value, *traceback; \ Py_XINCREF(tstate->exc_type); \ Py_XINCREF(tstate->exc_value); \ Py_XINCREF(tstate->exc_traceback); \ - Py_CLEAR(f->f_exc_type); \ - Py_CLEAR(f->f_exc_value); \ - Py_CLEAR(f->f_exc_traceback); \ + type = f->f_exc_type; \ + value = f->f_exc_value; \ + traceback = f->f_exc_traceback; \ f->f_exc_type = tstate->exc_type; \ f->f_exc_value = tstate->exc_value; \ f->f_exc_traceback = tstate->exc_traceback; \ + Py_XDECREF(type); \ + Py_XDECREF(value); \ + Py_XDECREF(traceback); \ } #define SWAP_EXC_STATE() \ |