diff -r da93fc81b086 Lib/test/test_exceptions.py --- a/Lib/test/test_exceptions.py Sun Jun 15 04:57:40 2008 +0200 +++ b/Lib/test/test_exceptions.py Sun Jun 15 19:40:47 2008 +0200 @@ -5,8 +5,6 @@ import unittest 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 -r da93fc81b086 Python/ceval.c --- a/Python/ceval.c Sun Jun 15 04:57:40 2008 +0200 +++ b/Python/ceval.c Sun Jun 15 19:40:47 2008 +0200 @@ -699,29 +699,39 @@ PyEval_EvalFrameEx(PyFrameObject *f, int } #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() \