diff --git a/Lib/test/test_dynamic.py b/Lib/test/test_dynamic.py index e896fc703c9a8b..25544dea14df3a 100644 --- a/Lib/test/test_dynamic.py +++ b/Lib/test/test_dynamic.py @@ -149,5 +149,48 @@ def __missing__(self, key): for _ in range(30): self.assertEqual(sum_func(), 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 af47e091bc7f0b..1a1b24434bad89 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -699,12 +699,6 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) #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() \ @@ -716,10 +710,11 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) 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(); \ } @@ -1212,7 +1207,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int assert(value != NULL); Py_INCREF(value); PUSH(value); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(LOAD_FAST__LOAD_CONST) { @@ -1225,7 +1220,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) { @@ -1237,7 +1232,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int assert(value != NULL); Py_INCREF(value); PUSH(value); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(STORE_FAST__STORE_FAST) { @@ -1247,7 +1242,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int next_instr++; value = POP(); SETLOCAL(oparg, value); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(LOAD_CONST__LOAD_FAST) { @@ -1260,7 +1255,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int assert(value != NULL); Py_INCREF(value); PUSH(value); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(POP_TOP) { @@ -1339,7 +1334,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int goto error; } JUMPBY(INLINE_CACHE_ENTRIES_BINARY_OP); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(BINARY_OP_MULTIPLY_FLOAT) { @@ -1360,7 +1355,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int goto error; } JUMPBY(INLINE_CACHE_ENTRIES_BINARY_OP); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(BINARY_OP_SUBTRACT_INT) { @@ -1379,7 +1374,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int goto error; } JUMPBY(INLINE_CACHE_ENTRIES_BINARY_OP); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(BINARY_OP_SUBTRACT_FLOAT) { @@ -1399,7 +1394,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int goto error; } JUMPBY(INLINE_CACHE_ENTRIES_BINARY_OP); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(BINARY_OP_ADD_UNICODE) { @@ -1418,7 +1413,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) { @@ -1454,7 +1449,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) { @@ -1475,7 +1470,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int goto error; } JUMPBY(INLINE_CACHE_ENTRIES_BINARY_OP); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(BINARY_OP_ADD_INT) { @@ -1494,7 +1489,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int goto error; } JUMPBY(INLINE_CACHE_ENTRIES_BINARY_OP); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(BINARY_SUBSCR) { @@ -1560,7 +1555,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); @@ -1591,7 +1586,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) { @@ -1616,7 +1611,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) { @@ -1724,7 +1719,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); @@ -1756,7 +1751,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) { @@ -2238,7 +2233,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); @@ -2256,7 +2251,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) { @@ -2271,7 +2266,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } Py_DECREF(seq); JUMPBY(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(UNPACK_SEQUENCE_LIST) { @@ -2286,7 +2281,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } Py_DECREF(seq); JUMPBY(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(UNPACK_EX) { @@ -2481,7 +2476,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); @@ -2508,7 +2503,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) { @@ -2533,7 +2528,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) { @@ -2942,7 +2937,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); @@ -2973,7 +2968,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) { @@ -2998,7 +2993,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) { @@ -3037,7 +3032,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) { @@ -3059,7 +3054,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_CLASS) { @@ -3082,7 +3077,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int SET_TOP(res); Py_DECREF(cls); JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(LOAD_ATTR_PROPERTY) { @@ -3171,7 +3166,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); @@ -3206,7 +3201,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) { @@ -3255,7 +3250,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) { @@ -3275,7 +3270,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) { @@ -3302,7 +3297,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); @@ -3339,7 +3334,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int else { JUMPBY(1 + oparg); } - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(COMPARE_OP_INT_JUMP) { @@ -3371,7 +3366,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int else { JUMPBY(1 + oparg); } - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(COMPARE_OP_STR_JUMP) { @@ -3404,7 +3399,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int else { JUMPBY(1 + oparg); } - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(IS_OP) { @@ -3829,7 +3824,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int if (ADAPTIVE_COUNTER_IS_ZERO(cache)) { next_instr--; _Py_Specialize_ForIter(TOP(), next_instr); - NOTRACE_DISPATCH_SAME_OPARG(); + DISPATCH_SAME_OPARG(); } else { STAT_INC(FOR_ITER, deferred); @@ -3850,7 +3845,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int Py_INCREF(next); PUSH(next); JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER); - NOTRACE_DISPATCH(); + DISPATCH(); } it->it_seq = NULL; Py_DECREF(seq); @@ -3858,7 +3853,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int STACK_SHRINK(1); Py_DECREF(it); JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(FOR_ITER_RANGE) { @@ -3872,7 +3867,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int STACK_SHRINK(1); Py_DECREF(r); JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg); - NOTRACE_DISPATCH(); + DISPATCH(); } long value = (long)(r->start + (unsigned long)(r->index++) * r->step); @@ -3881,7 +3876,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int } // The STORE_FAST is already done. JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + 1); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(BEFORE_ASYNC_WITH) { @@ -4028,7 +4023,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int SET_TOP(res); PUSH(self); JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(LOAD_ATTR_METHOD_WITH_DICT) { @@ -4056,7 +4051,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int SET_TOP(res); PUSH(self); JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(LOAD_ATTR_METHOD_NO_DICT) { @@ -4075,7 +4070,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int SET_TOP(res); PUSH(self); JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(LOAD_ATTR_METHOD_LAZY_DICT) { @@ -4098,7 +4093,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int SET_TOP(res); PUSH(self); JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(CALL_BOUND_METHOD_EXACT_ARGS) { @@ -4208,7 +4203,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); @@ -4305,7 +4300,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int Py_DECREF(obj); STACK_SHRINK(2); SET_TOP(res); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(CALL_NO_KW_STR_1) { @@ -4575,7 +4570,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int STACK_SHRINK(2); Py_DECREF(list); Py_DECREF(callable); - NOTRACE_DISPATCH(); + DISPATCH(); } TARGET(CALL_NO_KW_METHOD_DESCRIPTOR_O) { @@ -4947,7 +4942,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); @@ -4982,10 +4977,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) {