You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Jumping before comprehensions yields SIGSEGV #92311
import sys
def fun():
a = 1 # <---- jump location
x = [i for i in range(10)]
c = 3 # current location
def trace(frame, event, arg):
if event == "line" and frame.f_lineno == 9:
frame.f_lineno = 4
return trace
sys.settrace(trace)
if __name__ == "__main__":
fun()
Jumping from line current location to jump location yields SIGSEGV
Error messages
.venv/bin/python <cwd>/cakeshop.py
Fatal Python error: Segmentation fault
Current thread 0x00007f16eaae5280 (most recent call first):
File "<cwd>/cakeshop.py", line 14 in trace
File "<cwd>/cakeshop.py", line 9 in fun
File "<cwd>/cakeshop.py", line 22 in <module>
Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
Your environment
CPython versions tested on: 3.9.11, 3.10.1 (3.11.x works as expected same as <3.9)
Operating system and architecture: Linux q 5.4.0-42-generic x64
Bisecting between v3.10.0a1 and main, it looks like this was the first commit in which the behavior was fixed:
adcd2205565f91c6719f4141ab4e1da6d7086126 is the first new commit
commit adcd2205565f91c6719f4141ab4e1da6d7086126
Author: Mark Shannon <mark@hotpy.org>
Date: Fri May 7 15:19:19 2021 +0100
bpo-40222: "Zero cost" exception handling (GH-25729)
"Zero cost" exception handling.
* Uses a lookup table to determine how to handle exceptions.
* Removes SETUP_FINALLY and POP_TOP block instructions, eliminating (most of) the runtime overhead of try statements.
* Reduces the size of the frame object by about 60%.
Bisecting between v3.8.0a1 and 3.10.0a1 got me this as the breaking commit:
fee552669f21ca294f57fe0df826945edc779090 is the first bad commit
commit fee552669f21ca294f57fe0df826945edc779090
Author: Mark Shannon <mark@hotpy.org>
Date: Thu Nov 21 09:11:43 2019 +0000
Produce cleaner bytecode for 'with' and 'async with' by generating separate code for normal and exceptional paths. (#6641)
Remove BEGIN_FINALLY, END_FINALLY, CALL_FINALLY and POP_FINALLY bytecodes. Implement finally blocks by code duplication.
Reimplement frame.lineno setter using line numbers rather than bytecode offsets.
The code assumed that GET_ITER must signal the start of a for-loop, so it pushes a Loop (2) code. But it's not a for-loop; it's a list comprehension. So the Loop block is never popped.
Activity
serhiy-storchaka commentedon May 5, 2022
@markshannon
sweeneyde commentedon May 6, 2022
Bisecting between
v3.10.0a1andmain, it looks like this was the first commit in which the behavior was fixed:Bisecting between
v3.8.0a1and3.10.0a1got me this as the breaking commit:sweeneyde commentedon May 12, 2022
This is a walkthrough of the offending call to
frame_setlinenoin Pythonv3.10.0a1:The relevant bytecode of
fun()Walking through frame_setlineno
So I believe the problem is
markblocks(): I don't know why it would decide that aLoop (2)is on the stack at indices 9-14.sweeneyde commentedon May 12, 2022
Ah, so this is the issue in 3.10:
cpython/Objects/frameobject.c
Lines 183 to 187 in 8e9afaf
The code assumed that
GET_ITERmust signal the start of afor-loop, so it pushes aLoop (2)code. But it's not afor-loop; it's a list comprehension. So theLoopblock is never popped.[3.10] gh-92311: Let frame_setlineno jump over listcomps (GH-92717)
[3.9] gh-92311: Let frame_setlineno jump over listcomps (#92740)
gh-92311: Add tests for frame_setlineno jumping over listcomps (#92741)
pythongh-92311: Add tests for frame_setlineno jumping over listcomps (p…
gh-92311: Add tests for frame_setlineno jumping over listcomps (GH-92741
sweeneyde commentedon May 14, 2022
[3.9] pythongh-92311: Let frame_setlineno jump over listcomps (python…