[Python-3000-checkins] r64302 - in python/branches/py3k: Lib/test/test_exceptions.py Python/ceval.c

benjamin.peterson python-3000-checkins at python.org
Sun Jun 15 22:09:12 CEST 2008


Author: benjamin.peterson
Date: Sun Jun 15 22:09:12 2008
New Revision: 64302

Log:
improvements to the fix for #3114

keep the tstate consistent and a better test


Modified:
   python/branches/py3k/Lib/test/test_exceptions.py
   python/branches/py3k/Python/ceval.c

Modified: python/branches/py3k/Lib/test/test_exceptions.py
==============================================================================
--- python/branches/py3k/Lib/test/test_exceptions.py	(original)
+++ python/branches/py3k/Lib/test/test_exceptions.py	Sun Jun 15 22:09:12 2008
@@ -5,8 +5,6 @@
 import unittest
 import pickle
 import weakref
-import gc
-import traceback
 
 from test.support import TESTFN, unlink, run_unittest
 
@@ -553,9 +551,9 @@
             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 @@
             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)

Modified: python/branches/py3k/Python/ceval.c
==============================================================================
--- python/branches/py3k/Python/ceval.c	(original)
+++ python/branches/py3k/Python/ceval.c	Sun Jun 15 22:09:12 2008
@@ -699,29 +699,39 @@
 	}
 
 #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() \


More information about the Python-3000-checkins mailing list