From d7c8d15e2b558e2e6e4c8b78148908f387be09f8 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Wed, 10 Nov 2021 19:05:29 +0000 Subject: [PATCH 1/2] bpo-45711: assert that the type of exc_info is redundant --- Python/ceval.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Python/ceval.c b/Python/ceval.c index fadb97adefb2b4..f824478b365321 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1060,6 +1060,17 @@ match_class(PyThreadState *tstate, PyObject *subject, PyObject *type, static int do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause); static int unpack_iterable(PyThreadState *, PyObject *, int, int, PyObject **); +static void +_assert_exception_type_is_redundant(PyObject* type, PyObject* val) +{ + if (type == NULL || type == Py_None) { + assert(val == NULL || val == Py_None); + } + else { + assert(PyExceptionInstance_Check(val)); + assert(PyExceptionInstance_Class(val) == type); + } +} PyObject * PyEval_EvalCode(PyObject *co, PyObject *globals, PyObject *locals) @@ -2847,6 +2858,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr exc_info->exc_type = POP(); exc_info->exc_value = POP(); exc_info->exc_traceback = POP(); + _assert_exception_type_is_redundant(exc_info->exc_type, exc_info->exc_value); Py_XDECREF(type); Py_XDECREF(value); Py_XDECREF(traceback); @@ -2868,6 +2880,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr type = POP(); value = POP(); traceback = POP(); + _assert_exception_type_is_redundant(type, value); Py_DECREF(POP()); /* lasti */ _PyErr_Restore(tstate, type, value, traceback); exc_info = tstate->exc_info; @@ -2877,6 +2890,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr exc_info->exc_type = POP(); exc_info->exc_value = POP(); exc_info->exc_traceback = POP(); + _assert_exception_type_is_redundant(exc_info->exc_type, exc_info->exc_value); Py_XDECREF(type); Py_XDECREF(value); Py_XDECREF(traceback); @@ -2899,6 +2913,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr PyObject *exc = POP(); PyObject *val = POP(); PyObject *tb = POP(); + _assert_exception_type_is_redundant(exc, val); assert(PyExceptionClass_Check(exc)); _PyErr_Restore(tstate, exc, val, tb); goto exception_unwind; @@ -2908,6 +2923,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr PyObject *exc = POP(); PyObject *val = POP(); PyObject *tb = POP(); + _assert_exception_type_is_redundant(exc, val); assert(PyExceptionClass_Check(exc)); if (PyErr_GivenExceptionMatches(exc, PyExc_StopAsyncIteration)) { Py_DECREF(exc); @@ -4362,6 +4378,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr exc = TOP(); val = SECOND(); tb = THIRD(); + _assert_exception_type_is_redundant(exc, val); assert(!Py_IsNone(exc)); assert(!PyLong_Check(exc)); assert(PyLong_Check(PEEK(7))); @@ -4380,6 +4397,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr PyObject *type = TOP(); PyObject *value = SECOND(); PyObject *tb = THIRD(); + _assert_exception_type_is_redundant(type, value); _PyErr_StackItem *exc_info = tstate->exc_info; SET_THIRD(exc_info->exc_traceback); SET_SECOND(exc_info->exc_value); @@ -5238,6 +5256,7 @@ MISS_WITH_OPARG_COUNTER(BINARY_MULTIPLY) PUSH(tb); PUSH(val); PUSH(exc); + _assert_exception_type_is_redundant(exc, val); JUMPTO(handler); /* Resume normal execution */ frame->f_state = FRAME_EXECUTING; From f5cb124ce1928d0d43266eb46688bed2bb2153a2 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Thu, 11 Nov 2021 17:32:20 +0000 Subject: [PATCH 2/2] convert to macro, Py_DEBUG only --- Python/ceval.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/Python/ceval.c b/Python/ceval.c index f824478b365321..7451fc38637c97 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1060,6 +1060,7 @@ match_class(PyThreadState *tstate, PyObject *subject, PyObject *type, static int do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause); static int unpack_iterable(PyThreadState *, PyObject *, int, int, PyObject **); +#ifdef Py_DEBUG static void _assert_exception_type_is_redundant(PyObject* type, PyObject* val) { @@ -1072,6 +1073,11 @@ _assert_exception_type_is_redundant(PyObject* type, PyObject* val) } } +#define ASSERT_EXC_TYPE_IS_REDUNDANT(t, v) _assert_exception_type_is_redundant(t, v) +#else +#define ASSERT_EXC_TYPE_IS_REDUNDANT(t, v) +#endif + PyObject * PyEval_EvalCode(PyObject *co, PyObject *globals, PyObject *locals) { @@ -2858,7 +2864,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr exc_info->exc_type = POP(); exc_info->exc_value = POP(); exc_info->exc_traceback = POP(); - _assert_exception_type_is_redundant(exc_info->exc_type, exc_info->exc_value); + ASSERT_EXC_TYPE_IS_REDUNDANT(exc_info->exc_type, exc_info->exc_value); Py_XDECREF(type); Py_XDECREF(value); Py_XDECREF(traceback); @@ -2880,7 +2886,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr type = POP(); value = POP(); traceback = POP(); - _assert_exception_type_is_redundant(type, value); + ASSERT_EXC_TYPE_IS_REDUNDANT(type, value); Py_DECREF(POP()); /* lasti */ _PyErr_Restore(tstate, type, value, traceback); exc_info = tstate->exc_info; @@ -2890,7 +2896,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr exc_info->exc_type = POP(); exc_info->exc_value = POP(); exc_info->exc_traceback = POP(); - _assert_exception_type_is_redundant(exc_info->exc_type, exc_info->exc_value); + ASSERT_EXC_TYPE_IS_REDUNDANT(exc_info->exc_type, exc_info->exc_value); Py_XDECREF(type); Py_XDECREF(value); Py_XDECREF(traceback); @@ -2913,7 +2919,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr PyObject *exc = POP(); PyObject *val = POP(); PyObject *tb = POP(); - _assert_exception_type_is_redundant(exc, val); + ASSERT_EXC_TYPE_IS_REDUNDANT(exc, val); assert(PyExceptionClass_Check(exc)); _PyErr_Restore(tstate, exc, val, tb); goto exception_unwind; @@ -2923,7 +2929,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr PyObject *exc = POP(); PyObject *val = POP(); PyObject *tb = POP(); - _assert_exception_type_is_redundant(exc, val); + ASSERT_EXC_TYPE_IS_REDUNDANT(exc, val); assert(PyExceptionClass_Check(exc)); if (PyErr_GivenExceptionMatches(exc, PyExc_StopAsyncIteration)) { Py_DECREF(exc); @@ -4378,7 +4384,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr exc = TOP(); val = SECOND(); tb = THIRD(); - _assert_exception_type_is_redundant(exc, val); + ASSERT_EXC_TYPE_IS_REDUNDANT(exc, val); assert(!Py_IsNone(exc)); assert(!PyLong_Check(exc)); assert(PyLong_Check(PEEK(7))); @@ -4397,7 +4403,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr PyObject *type = TOP(); PyObject *value = SECOND(); PyObject *tb = THIRD(); - _assert_exception_type_is_redundant(type, value); + ASSERT_EXC_TYPE_IS_REDUNDANT(type, value); _PyErr_StackItem *exc_info = tstate->exc_info; SET_THIRD(exc_info->exc_traceback); SET_SECOND(exc_info->exc_value); @@ -5256,7 +5262,7 @@ MISS_WITH_OPARG_COUNTER(BINARY_MULTIPLY) PUSH(tb); PUSH(val); PUSH(exc); - _assert_exception_type_is_redundant(exc, val); + ASSERT_EXC_TYPE_IS_REDUNDANT(exc, val); JUMPTO(handler); /* Resume normal execution */ frame->f_state = FRAME_EXECUTING;