import unittest
import pickle
import weakref
+import gc
+import traceback
from test.support import TESTFN, unlink, run_unittest
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)
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() \
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; \