There's a variety of places where we walk over an array of instructions, using some variant of ```c for (int i = 0; i < num_instructions;) { int opcode = instructions[i].op.code; // <decode EXTENDED_ARG> opcode = _PyOpcode_Deopt[opcode]; // or _Py_GetBaseOpcode(code, i) // <handle opcode> i += 1 + _PyOpcode_Caches[opcode]; // or _PyInstruction_GetLength(code, i) } ``` All these make the mistake that if `opcode` is `ENTER_EXECUTOR`, it may obscure an underlying `JUMP_BACKWARD` instruction, which has a cache entry. I fixed this in gh-107256 for `_PyInstruction_GetLength()` and it was first reported in gh-107082, but there are a number of other occurrences. Basically every time we consult `_PyOpcode_Caches` we should ensure that the index is not `ENTER_EXECUTOR`. CC: @markshannon --- Places where I found this: - [x] _PyInstruction_GetLength - [x] code_richcompare - [x] code_hash - [x] ~_Py_GetBaseOpcode~ **[should not be "fixed", it would break callers that need the oparg]** - [ ] mark_stacks - [ ] _PyFrame_OpAlreadyRan - [x] de_instrument? - [x] initialize_tools? - [x] remove_tools? - [x] _PyCode_Quicken? There are possibly others. <!-- gh-linked-prs --> ### Linked PRs * gh-108165 * gh-108188 * gh-108366 * gh-108460 * gh-108482 * gh-108485 * gh-108539 * gh-109420 * gh-111645 <!-- /gh-linked-prs -->