diff options
author | Irit Katriel <1055913+iritkatriel@users.noreply.github.com> | 2023-09-07 17:23:11 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-07 17:23:11 (GMT) |
commit | 96396962ce7a83c09bac5061121c779ca6b25ef5 (patch) | |
tree | bc1d4bbd691a159bf5255a886e4dacbba8821c14 | |
parent | 403ab1306a6e9860197bce57eadcb83418966f21 (diff) | |
download | cpython-96396962ce7a83c09bac5061121c779ca6b25ef5.zip cpython-96396962ce7a83c09bac5061121c779ca6b25ef5.tar.gz cpython-96396962ce7a83c09bac5061121c779ca6b25ef5.tar.bz2 |
gh-109094: remove unnecessary updates of frame->prev_instr in instrumentation functions (#109076)
-rw-r--r-- | Lib/test/test_sys_settrace.py | 9 | ||||
-rw-r--r-- | Python/instrumentation.c | 8 |
2 files changed, 11 insertions, 6 deletions
diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py index 2329008..369a276 100644 --- a/Lib/test/test_sys_settrace.py +++ b/Lib/test/test_sys_settrace.py @@ -317,6 +317,13 @@ generator_example.events = ([(0, 'call'), [(5, 'line'), (5, 'return')]) +def lineno_matches_lasti(frame): + last_line = None + for start, end, line in frame.f_code.co_lines(): + if start <= frame.f_lasti < end: + last_line = line + return last_line == frame.f_lineno + class Tracer: def __init__(self, trace_line_events=None, trace_opcode_events=None): self.trace_line_events = trace_line_events @@ -330,6 +337,7 @@ class Tracer: frame.f_trace_opcodes = self.trace_opcode_events def trace(self, frame, event, arg): + assert lineno_matches_lasti(frame) self._reconfigure_frame(frame) self.events.append((frame.f_lineno, event)) return self.trace @@ -1890,6 +1898,7 @@ class JumpTracer: def trace(self, frame, event, arg): if self.done: return + assert lineno_matches_lasti(frame) # frame.f_code.co_firstlineno is the first line of the decorator when # 'function' is decorated and the decorator may be written using # multiple physical lines when it is too long. Use the first line diff --git a/Python/instrumentation.c b/Python/instrumentation.c index acc3278..74c3adf 100644 --- a/Python/instrumentation.c +++ b/Python/instrumentation.c @@ -1057,8 +1057,6 @@ _Py_call_instrumentation_jump( assert(event == PY_MONITORING_EVENT_JUMP || event == PY_MONITORING_EVENT_BRANCH); assert(frame->prev_instr == instr); - /* Event should occur after the jump */ - frame->prev_instr = target; PyCodeObject *code = _PyFrame_GetCode(frame); int to = (int)(target - _PyCode_CODE(code)); PyObject *to_obj = PyLong_FromLong(to * (int)sizeof(_Py_CODEUNIT)); @@ -1071,12 +1069,10 @@ _Py_call_instrumentation_jump( if (err) { return NULL; } - if (frame->prev_instr != target) { + if (frame->prev_instr != instr) { /* The callback has caused a jump (by setting the line number) */ return frame->prev_instr; } - /* Reset prev_instr for INSTRUMENTED_LINE */ - frame->prev_instr = instr; return target; } @@ -1125,7 +1121,7 @@ _Py_Instrumentation_GetLine(PyCodeObject *code, int index) int _Py_call_instrumentation_line(PyThreadState *tstate, _PyInterpreterFrame* frame, _Py_CODEUNIT *instr, _Py_CODEUNIT *prev) { - frame->prev_instr = instr; + assert(frame->prev_instr == instr); PyCodeObject *code = _PyFrame_GetCode(frame); assert(is_version_up_to_date(code, tstate->interp)); assert(instrumentation_cross_checks(tstate->interp, code)); |