sys.monitoring: BRANCH_LEFT event from a non-branch opcode #128419
Open
Description
Bug report
Bug description:
Using sys.monitoring, I get a BRANCH_LEFT event from an instruction with no branch (STORE_NAME).
This is while_true.py:
a, i = 1, 0
while True:
if i >= 3:
a = 4
break
i += 1
assert a == 4 and i == 3
Disassembled:
% python3 -m dis -O while_true.py
0 0 RESUME 0
1 2 LOAD_CONST 0 ((1, 0))
4 UNPACK_SEQUENCE 2
8 STORE_NAME 0 (a)
10 STORE_NAME 1 (i)
2 L1: 12 NOT_TAKEN
3 14 LOAD_NAME 1 (i)
16 LOAD_SMALL_INT 3
18 COMPARE_OP 188 (bool(>=))
22 POP_JUMP_IF_FALSE 4 (to L2)
26 NOT_TAKEN
4 28 LOAD_SMALL_INT 4
30 STORE_NAME 0 (a)
5 32 JUMP_FORWARD 7 (to L3)
6 L2: 34 LOAD_NAME 1 (i)
36 LOAD_SMALL_INT 1
38 BINARY_OP 13 (+=)
42 STORE_NAME 1 (i)
44 JUMP_BACKWARD 18 (to L1)
7 L3: 48 LOAD_NAME 0 (a)
50 LOAD_SMALL_INT 4
52 COMPARE_OP 88 (bool(==))
56 POP_JUMP_IF_FALSE 8 (to L4)
60 NOT_TAKEN
62 LOAD_NAME 1 (i)
64 LOAD_SMALL_INT 3
66 COMPARE_OP 88 (bool(==))
70 POP_JUMP_IF_TRUE 3 (to L5)
74 NOT_TAKEN
L4: 76 LOAD_COMMON_CONSTANT 0 (AssertionError)
78 RAISE_VARARGS 1
L5: 80 LOAD_CONST 1 (None)
82 RETURN_VALUE
Running run_sysmon.py shows these events:
3.14.0a3+ (heads/main:c9d2bc6d7f6, Jan 2 2025, 10:39:14) [Clang 16.0.0 (clang-1600.0.26.6)]
PY_START: while_true.py@0 #0
LINE: while_true.py #1
LINE: while_true.py #2
BRANCH_LEFT: while_true.py@8->14 #1->3 ****
LINE: while_true.py #3
BRANCH_RIGHT: while_true.py@22->34 #3->6
LINE: while_true.py #6
JUMP: while_true.py@44->12 #6->2
BRANCH_LEFT: while_true.py@22->28 #3->4
LINE: while_true.py #4
LINE: while_true.py #5
JUMP: while_true.py@32->48 #5->7
LINE: while_true.py #7
BRANCH_LEFT: while_true.py@56->62 #7->7
BRANCH_RIGHT: while_true.py@70->80 #7->7
PY_RETURN: while_true.py@82 #7
The starred line is a BRANCH_LEFT event from a STORE_NAME opcode, which doesn't make sense. The disassembly shows line 2 with a NOT_TAKEN event which I expect is left over from optimizing away the while True:
.
CPython versions tested on:
CPython main branch
Operating systems tested on:
macOS