diff --git a/Lib/test/test_dynamic.py b/Lib/test/test_dynamic.py index 3e0fcf4d158f8a..fee7718f634e78 100644 --- a/Lib/test/test_dynamic.py +++ b/Lib/test/test_dynamic.py @@ -1,6 +1,7 @@ # Test the most dynamic corner cases of Python's runtime semantics. import builtins +import sys import unittest from test.support import swap_item, swap_attr @@ -146,5 +147,48 @@ def __missing__(self, key): for _ in range(30): self.assertEqual(sum_1000(), expected) + +class TestTracing(unittest.TestCase): + + def setUp(self): + self.addCleanup(sys.settrace, sys.gettrace()) + sys.settrace(None) + + def test_after_specialization(self): + + def trace(frame, event, arg): + return trace + + turn_on_trace = False + + class C: + def __init__(self, x): + self.x = x + def __del__(self): + if turn_on_trace: + sys.settrace(trace) + + def f(): + # LOAD_GLOBAL[_BUILTIN] immediately follows the call to C.__del__ + C(0).x, len + + def g(): + # BINARY_SUSCR[_LIST_INT] immediately follows the call to C.__del__ + [0][C(0).x] + + def h(): + # BINARY_OP[_ADD_INT] immediately follows the call to C.__del__ + 0 + C(0).x + + for func in (f, g, h): + with self.subTest(func.__name__): + for _ in range(58): + func() + turn_on_trace = True + func() + sys.settrace(None) + turn_on_trace = False + + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-09-07-12-02-11.gh-issue-96636.YvN-K6.rst b/Misc/NEWS.d/next/Core and Builtins/2022-09-07-12-02-11.gh-issue-96636.YvN-K6.rst new file mode 100644 index 00000000000000..e0fbd8761aa335 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-09-07-12-02-11.gh-issue-96636.YvN-K6.rst @@ -0,0 +1,3 @@ +Ensure that tracing, ``sys.setrace()``, is turned on immediately. In +pre-release versions of 3.11, some tracing events might have been lost when +turning on tracing in a ``__del__`` method or interrupt. diff --git a/Python/ceval.c b/Python/ceval.c index 196a706ad9fd47..461439b1edae37 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1327,12 +1327,6 @@ eval_frame_handle_pending(PyThreadState *tstate) #define PRE_DISPATCH_GOTO() ((void)0) #endif -#define NOTRACE_DISPATCH() \ - { \ - NEXTOPARG(); \ - PRE_DISPATCH_GOTO(); \ - DISPATCH_GOTO(); \ - } /* Do interpreter dispatch accounting for tracing and instrumentation */ #define DISPATCH() \ @@ -1344,10 +1338,11 @@ eval_frame_handle_pending(PyThreadState *tstate) DISPATCH_GOTO(); \ } -#define NOTRACE_DISPATCH_SAME_OPARG() \ +#define DISPATCH_SAME_OPARG() \ { \ opcode = _Py_OPCODE(*next_instr); \ PRE_DISPATCH_GOTO(); \ + opcode |= cframe.use_tracing OR_DTRACE_LINE; \ DISPATCH_GOTO(); \ } @@ -1851,7 +1846,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } Py_INCREF(value); PUSH(value); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(LOAD_FAST__LOAD_CONST) { @@ -1866,7 +1861,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int value = GETITEM(consts, oparg); Py_INCREF(value); PUSH(value); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(STORE_FAST__LOAD_FAST) { @@ -1880,7 +1875,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } Py_INCREF(value); PUSH(value); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(STORE_FAST__STORE_FAST) { @@ -1890,7 +1885,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int next_instr++; value = POP(); SETLOCAL(oparg, value); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(LOAD_CONST__LOAD_FAST) { @@ -1905,7 +1900,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } Py_INCREF(value); PUSH(value); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(POP_TOP) { @@ -1984,7 +1979,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int goto error; } JUMPBY(INLINE_CACHE_ENTRIES_BINARY_OP); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(BINARY_OP_MULTIPLY_FLOAT) { @@ -2005,7 +2000,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int goto error; } JUMPBY(INLINE_CACHE_ENTRIES_BINARY_OP); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(BINARY_OP_SUBTRACT_INT) { @@ -2024,7 +2019,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int goto error; } JUMPBY(INLINE_CACHE_ENTRIES_BINARY_OP); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(BINARY_OP_SUBTRACT_FLOAT) { @@ -2044,7 +2039,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int goto error; } JUMPBY(INLINE_CACHE_ENTRIES_BINARY_OP); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(BINARY_OP_ADD_UNICODE) { @@ -2063,7 +2058,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int goto error; } JUMPBY(INLINE_CACHE_ENTRIES_BINARY_OP); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(BINARY_OP_INPLACE_ADD_UNICODE) { @@ -2099,7 +2094,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } // The STORE_FAST is already done. JUMPBY(INLINE_CACHE_ENTRIES_BINARY_OP + 1); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(BINARY_OP_ADD_FLOAT) { @@ -2120,7 +2115,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int goto error; } JUMPBY(INLINE_CACHE_ENTRIES_BINARY_OP); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(BINARY_OP_ADD_INT) { @@ -2139,7 +2134,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int goto error; } JUMPBY(INLINE_CACHE_ENTRIES_BINARY_OP); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(BINARY_SUBSCR) { @@ -2165,7 +2160,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int if (_Py_Specialize_BinarySubscr(container, sub, next_instr) < 0) { goto error; } - NOTRACE_DISPATCH_SAME_OPARG(); + DISPATCH_SAME_OPARG(); } else { STAT_INC(BINARY_SUBSCR, deferred); @@ -2196,7 +2191,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int SET_TOP(res); Py_DECREF(list); JUMPBY(INLINE_CACHE_ENTRIES_BINARY_SUBSCR); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(BINARY_SUBSCR_TUPLE_INT) { @@ -2221,7 +2216,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int SET_TOP(res); Py_DECREF(tuple); JUMPBY(INLINE_CACHE_ENTRIES_BINARY_SUBSCR); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(BINARY_SUBSCR_DICT) { @@ -2330,7 +2325,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int if (_Py_Specialize_StoreSubscr(container, sub, next_instr) < 0) { goto error; } - NOTRACE_DISPATCH_SAME_OPARG(); + DISPATCH_SAME_OPARG(); } else { STAT_INC(STORE_SUBSCR, deferred); @@ -2362,7 +2357,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); Py_DECREF(list); JUMPBY(INLINE_CACHE_ENTRIES_STORE_SUBSCR); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(STORE_SUBSCR_DICT) { @@ -2820,7 +2815,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int PyObject *seq = TOP(); next_instr--; _Py_Specialize_UnpackSequence(seq, next_instr, oparg); - NOTRACE_DISPATCH_SAME_OPARG(); + DISPATCH_SAME_OPARG(); } else { STAT_INC(UNPACK_SEQUENCE, deferred); @@ -2838,7 +2833,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int PUSH(Py_NewRef(PyTuple_GET_ITEM(seq, 0))); Py_DECREF(seq); JUMPBY(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(UNPACK_SEQUENCE_TUPLE) { @@ -2853,7 +2848,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } Py_DECREF(seq); JUMPBY(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(UNPACK_SEQUENCE_LIST) { @@ -2868,7 +2863,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } Py_DECREF(seq); JUMPBY(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(UNPACK_EX) { @@ -3063,7 +3058,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int if (_Py_Specialize_LoadGlobal(GLOBALS(), BUILTINS(), next_instr, name) < 0) { goto error; } - NOTRACE_DISPATCH_SAME_OPARG(); + DISPATCH_SAME_OPARG(); } else { STAT_INC(LOAD_GLOBAL, deferred); @@ -3090,7 +3085,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int STACK_GROW(push_null+1); Py_INCREF(res); SET_TOP(res); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(LOAD_GLOBAL_BUILTIN) { @@ -3115,7 +3110,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int STACK_GROW(push_null+1); Py_INCREF(res); SET_TOP(res); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(DELETE_FAST) { @@ -3488,7 +3483,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int if (_Py_Specialize_LoadAttr(owner, next_instr, name) < 0) { goto error; } - NOTRACE_DISPATCH_SAME_OPARG(); + DISPATCH_SAME_OPARG(); } else { STAT_INC(LOAD_ATTR, deferred); @@ -3517,7 +3512,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int SET_TOP(res); Py_DECREF(owner); JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(LOAD_ATTR_MODULE) { @@ -3529,7 +3524,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int SET_TOP(res); Py_DECREF(owner); JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(LOAD_ATTR_WITH_HINT) { @@ -3564,7 +3559,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int SET_TOP(res); Py_DECREF(owner); JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(LOAD_ATTR_SLOT) { @@ -3584,9 +3579,10 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int SET_TOP(res); Py_DECREF(owner); JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); - NOTRACE_DISPATCH(); + DISPATCH(); } + DISPATCH(); TARGET(STORE_ATTR_ADAPTIVE) { assert(cframe.use_tracing == 0); _PyAttrCache *cache = (_PyAttrCache *)next_instr; @@ -3597,7 +3593,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int if (_Py_Specialize_StoreAttr(owner, next_instr, name) < 0) { goto error; } - NOTRACE_DISPATCH_SAME_OPARG(); + DISPATCH_SAME_OPARG(); } else { STAT_INC(STORE_ATTR, deferred); @@ -3631,7 +3627,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } Py_DECREF(owner); JUMPBY(INLINE_CACHE_ENTRIES_STORE_ATTR); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(STORE_ATTR_WITH_HINT) { @@ -3678,7 +3674,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int dict->ma_version_tag = DICT_NEXT_VERSION(); Py_DECREF(owner); JUMPBY(INLINE_CACHE_ENTRIES_STORE_ATTR); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(STORE_ATTR_SLOT) { @@ -3698,7 +3694,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int Py_XDECREF(old_value); Py_DECREF(owner); JUMPBY(INLINE_CACHE_ENTRIES_STORE_ATTR); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(COMPARE_OP) { @@ -3725,7 +3721,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int PyObject *left = SECOND(); next_instr--; _Py_Specialize_CompareOp(left, right, next_instr, oparg); - NOTRACE_DISPATCH_SAME_OPARG(); + DISPATCH_SAME_OPARG(); } else { STAT_INC(COMPARE_OP, deferred); @@ -3773,7 +3769,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int opcode == POP_JUMP_FORWARD_IF_FALSE); JUMPBY(1 + oparg); } - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(COMPARE_OP_INT_JUMP) { @@ -3816,7 +3812,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int opcode == POP_JUMP_FORWARD_IF_FALSE); JUMPBY(1 + oparg); } - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(COMPARE_OP_STR_JUMP) { @@ -3860,7 +3856,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int opcode == POP_JUMP_FORWARD_IF_FALSE); JUMPBY(1 + oparg); } - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(IS_OP) { @@ -4534,7 +4530,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int if (_Py_Specialize_LoadMethod(owner, next_instr, name) < 0) { goto error; } - NOTRACE_DISPATCH_SAME_OPARG(); + DISPATCH_SAME_OPARG(); } else { STAT_INC(LOAD_METHOD, deferred); @@ -4566,7 +4562,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int SET_TOP(res); PUSH(self); JUMPBY(INLINE_CACHE_ENTRIES_LOAD_METHOD); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(LOAD_METHOD_WITH_DICT) { @@ -4598,7 +4594,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int SET_TOP(res); PUSH(self); JUMPBY(INLINE_CACHE_ENTRIES_LOAD_METHOD); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(LOAD_METHOD_NO_DICT) { @@ -4617,7 +4613,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int SET_TOP(res); PUSH(self); JUMPBY(INLINE_CACHE_ENTRIES_LOAD_METHOD); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(LOAD_METHOD_MODULE) { @@ -4630,7 +4626,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int Py_DECREF(owner); PUSH(res); JUMPBY(INLINE_CACHE_ENTRIES_LOAD_METHOD); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(LOAD_METHOD_CLASS) { @@ -4653,7 +4649,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int Py_DECREF(cls); PUSH(res); JUMPBY(INLINE_CACHE_ENTRIES_LOAD_METHOD); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(PRECALL) { @@ -4808,7 +4804,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int if (err < 0) { goto error; } - NOTRACE_DISPATCH_SAME_OPARG(); + DISPATCH_SAME_OPARG(); } else { STAT_INC(PRECALL, deferred); @@ -4829,7 +4825,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int if (err < 0) { goto error; } - NOTRACE_DISPATCH_SAME_OPARG(); + DISPATCH_SAME_OPARG(); } else { STAT_INC(CALL, deferred); @@ -4929,7 +4925,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int Py_DECREF(obj); STACK_SHRINK(2); SET_TOP(res); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(PRECALL_NO_KW_STR_1) { @@ -5199,7 +5195,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int STACK_SHRINK(2); Py_DECREF(list); Py_DECREF(callable); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(PRECALL_NO_KW_METHOD_DESCRIPTOR_O) { @@ -5569,7 +5565,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int PyObject *rhs = TOP(); next_instr--; _Py_Specialize_BinaryOp(lhs, rhs, next_instr, oparg, &GETLOCAL(0)); - NOTRACE_DISPATCH_SAME_OPARG(); + DISPATCH_SAME_OPARG(); } else { STAT_INC(BINARY_OP, deferred); @@ -5604,10 +5600,12 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } TARGET(EXTENDED_ARG_QUICK) { + assert(cframe.use_tracing == 0); assert(oparg); - oparg <<= 8; - oparg |= _Py_OPARG(*next_instr); - NOTRACE_DISPATCH_SAME_OPARG(); + int oldoparg = oparg; + NEXTOPARG(); + oparg |= oldoparg << 8; + DISPATCH_GOTO(); } TARGET(CACHE) {