diff options
author | Benjamin Peterson <benjamin@python.org> | 2008-06-15 00:05:44 (GMT) |
---|---|---|
committer | Benjamin Peterson <benjamin@python.org> | 2008-06-15 00:05:44 (GMT) |
commit | 979f31172890fcfa45e5e23c461b1517a49dbf3b (patch) | |
tree | e395bcce840cfcdb0c5c648aa7f73fa511a4f9e0 | |
parent | c5e94641bff2557a55be2a497bf974ff9c2a6e28 (diff) | |
download | cpython-979f31172890fcfa45e5e23c461b1517a49dbf3b.zip cpython-979f31172890fcfa45e5e23c461b1517a49dbf3b.tar.gz cpython-979f31172890fcfa45e5e23c461b1517a49dbf3b.tar.bz2 |
#3114 fix a bus error when deallocated exceptions were used
-rw-r--r-- | Lib/test/test_exceptions.py | 19 | ||||
-rw-r--r-- | Python/ceval.c | 12 |
2 files changed, 25 insertions, 6 deletions
diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index 55a57ba..753e33b 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -5,6 +5,8 @@ import sys import unittest import pickle import weakref +import gc +import traceback from test.support import TESTFN, unlink, run_unittest @@ -551,6 +553,23 @@ 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. + class MyObject: + def __del__(self): + nonlocal e + e = sys.exc_info() + e = () + try: + raise Exception(MyObject()) + except: + pass + gc.collect() + [0]*10000 + # Do something with the exception and its traceback + traceback.format_exception(*e) + def test_main(): run_unittest(ExceptionTests) diff --git a/Python/ceval.c b/Python/ceval.c index 6aaa52d..4b14784 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -704,11 +704,11 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) PyObject *v = POP(); \ Py_XDECREF(v); \ } \ - Py_XDECREF(tstate->exc_type); \ + Py_CLEAR(tstate->exc_type); \ + Py_CLEAR(tstate->exc_value); \ + Py_CLEAR(tstate->exc_traceback); \ tstate->exc_type = POP(); \ - Py_XDECREF(tstate->exc_value); \ tstate->exc_value = POP(); \ - Py_XDECREF(tstate->exc_traceback); \ tstate->exc_traceback = POP(); #define SAVE_EXC_STATE() \ @@ -716,9 +716,9 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) Py_XINCREF(tstate->exc_type); \ Py_XINCREF(tstate->exc_value); \ Py_XINCREF(tstate->exc_traceback); \ - Py_XDECREF(f->f_exc_type); \ - Py_XDECREF(f->f_exc_value); \ - Py_XDECREF(f->f_exc_traceback); \ + Py_CLEAR(f->f_exc_type); \ + Py_CLEAR(f->f_exc_value); \ + Py_CLEAR(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; \ |