From 979f31172890fcfa45e5e23c461b1517a49dbf3b Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 15 Jun 2008 00:05:44 +0000 Subject: #3114 fix a bus error when deallocated exceptions were used --- Lib/test/test_exceptions.py | 19 +++++++++++++++++++ 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; \ -- cgit v0.12