Skip to content

sys.monitoring: BRANCH_LEFT event from a non-branch opcode #128419

Open
@nedbat

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

Metadata

Assignees

No one assigned

    Labels

    interpreter-core(Objects, Python, Grammar, and Parser dirs)type-bugAn unexpected behavior, bug, or error

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions