Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 979f311

Browse files
committed
#3114 fix a bus error when deallocated exceptions were used
1 parent c5e9464 commit 979f311

2 files changed

Lines changed: 25 additions & 6 deletions

File tree

Lib/test/test_exceptions.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import unittest
66
import pickle
77
import weakref
8+
import gc
9+
import traceback
810

911
from test.support import TESTFN, unlink, run_unittest
1012

@@ -551,6 +553,23 @@ def yield_raise():
551553
del g
552554
self.assertEquals(sys.exc_info()[0], TypeError)
553555

556+
def test_crash_3114(self):
557+
# Bug #3114: in its destructor, MyObject retrieves a pointer to a
558+
# deallocated exception instance or traceback.
559+
class MyObject:
560+
def __del__(self):
561+
nonlocal e
562+
e = sys.exc_info()
563+
e = ()
564+
try:
565+
raise Exception(MyObject())
566+
except:
567+
pass
568+
gc.collect()
569+
[0]*10000
570+
# Do something with the exception and its traceback
571+
traceback.format_exception(*e)
572+
554573
def test_main():
555574
run_unittest(ExceptionTests)
556575

Python/ceval.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -704,21 +704,21 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
704704
PyObject *v = POP(); \
705705
Py_XDECREF(v); \
706706
} \
707-
Py_XDECREF(tstate->exc_type); \
707+
Py_CLEAR(tstate->exc_type); \
708+
Py_CLEAR(tstate->exc_value); \
709+
Py_CLEAR(tstate->exc_traceback); \
708710
tstate->exc_type = POP(); \
709-
Py_XDECREF(tstate->exc_value); \
710711
tstate->exc_value = POP(); \
711-
Py_XDECREF(tstate->exc_traceback); \
712712
tstate->exc_traceback = POP();
713713

714714
#define SAVE_EXC_STATE() \
715715
{ \
716716
Py_XINCREF(tstate->exc_type); \
717717
Py_XINCREF(tstate->exc_value); \
718718
Py_XINCREF(tstate->exc_traceback); \
719-
Py_XDECREF(f->f_exc_type); \
720-
Py_XDECREF(f->f_exc_value); \
721-
Py_XDECREF(f->f_exc_traceback); \
719+
Py_CLEAR(f->f_exc_type); \
720+
Py_CLEAR(f->f_exc_value); \
721+
Py_CLEAR(f->f_exc_traceback); \
722722
f->f_exc_type = tstate->exc_type; \
723723
f->f_exc_value = tstate->exc_value; \
724724
f->f_exc_traceback = tstate->exc_traceback; \

0 commit comments

Comments
 (0)