mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
improvements to the fix for #3114
keep the tstate consistent and a better test
This commit is contained in:
parent
df6dc8f107
commit
27d63678a3
2 changed files with 28 additions and 23 deletions
|
@ -5,8 +5,6 @@ import sys
|
||||||
import unittest
|
import unittest
|
||||||
import pickle
|
import pickle
|
||||||
import weakref
|
import weakref
|
||||||
import gc
|
|
||||||
import traceback
|
|
||||||
|
|
||||||
from test.support import TESTFN, unlink, run_unittest
|
from test.support import TESTFN, unlink, run_unittest
|
||||||
|
|
||||||
|
@ -553,9 +551,9 @@ class ExceptionTests(unittest.TestCase):
|
||||||
del g
|
del g
|
||||||
self.assertEquals(sys.exc_info()[0], TypeError)
|
self.assertEquals(sys.exc_info()[0], TypeError)
|
||||||
|
|
||||||
def test_crash_3114(self):
|
def test_3114(self):
|
||||||
# Bug #3114: in its destructor, MyObject retrieves a pointer to a
|
# Bug #3114: in its destructor, MyObject retrieves a pointer to
|
||||||
# deallocated exception instance or traceback.
|
# obsolete and/or deallocated objects.
|
||||||
class MyObject:
|
class MyObject:
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
nonlocal e
|
nonlocal e
|
||||||
|
@ -565,10 +563,7 @@ class ExceptionTests(unittest.TestCase):
|
||||||
raise Exception(MyObject())
|
raise Exception(MyObject())
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
gc.collect()
|
self.assertEquals(e, (None, None, None))
|
||||||
[0]*10000
|
|
||||||
# Do something with the exception and its traceback
|
|
||||||
traceback.format_exception(*e)
|
|
||||||
|
|
||||||
def test_main():
|
def test_main():
|
||||||
run_unittest(ExceptionTests)
|
run_unittest(ExceptionTests)
|
||||||
|
|
|
@ -699,29 +699,39 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define UNWIND_EXCEPT_HANDLER(b) \
|
#define UNWIND_EXCEPT_HANDLER(b) \
|
||||||
|
{ \
|
||||||
|
PyObject *type, *value, *traceback; \
|
||||||
assert(STACK_LEVEL() >= (b)->b_level + 3); \
|
assert(STACK_LEVEL() >= (b)->b_level + 3); \
|
||||||
while (STACK_LEVEL() > (b)->b_level + 3) { \
|
while (STACK_LEVEL() > (b)->b_level + 3) { \
|
||||||
PyObject *v = POP(); \
|
value = POP(); \
|
||||||
Py_XDECREF(v); \
|
Py_XDECREF(value); \
|
||||||
} \
|
} \
|
||||||
Py_CLEAR(tstate->exc_type); \
|
type = tstate->exc_type; \
|
||||||
Py_CLEAR(tstate->exc_value); \
|
value = tstate->exc_value; \
|
||||||
Py_CLEAR(tstate->exc_traceback); \
|
traceback = tstate->exc_traceback; \
|
||||||
tstate->exc_type = POP(); \
|
tstate->exc_type = POP(); \
|
||||||
tstate->exc_value = POP(); \
|
tstate->exc_value = POP(); \
|
||||||
tstate->exc_traceback = POP();
|
tstate->exc_traceback = POP(); \
|
||||||
|
Py_XDECREF(type); \
|
||||||
|
Py_XDECREF(value); \
|
||||||
|
Py_XDECREF(traceback); \
|
||||||
|
}
|
||||||
|
|
||||||
#define SAVE_EXC_STATE() \
|
#define SAVE_EXC_STATE() \
|
||||||
{ \
|
{ \
|
||||||
|
PyObject *type, *value, *traceback; \
|
||||||
Py_XINCREF(tstate->exc_type); \
|
Py_XINCREF(tstate->exc_type); \
|
||||||
Py_XINCREF(tstate->exc_value); \
|
Py_XINCREF(tstate->exc_value); \
|
||||||
Py_XINCREF(tstate->exc_traceback); \
|
Py_XINCREF(tstate->exc_traceback); \
|
||||||
Py_CLEAR(f->f_exc_type); \
|
type = f->f_exc_type; \
|
||||||
Py_CLEAR(f->f_exc_value); \
|
value = f->f_exc_value; \
|
||||||
Py_CLEAR(f->f_exc_traceback); \
|
traceback = f->f_exc_traceback; \
|
||||||
f->f_exc_type = tstate->exc_type; \
|
f->f_exc_type = tstate->exc_type; \
|
||||||
f->f_exc_value = tstate->exc_value; \
|
f->f_exc_value = tstate->exc_value; \
|
||||||
f->f_exc_traceback = tstate->exc_traceback; \
|
f->f_exc_traceback = tstate->exc_traceback; \
|
||||||
|
Py_XDECREF(type); \
|
||||||
|
Py_XDECREF(value); \
|
||||||
|
Py_XDECREF(traceback); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SWAP_EXC_STATE() \
|
#define SWAP_EXC_STATE() \
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue