-
-
Notifications
You must be signed in to change notification settings - Fork 30.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
experimental jit causes infinite loops on 3.13 branch #126127
Comments
I tried reverting 6387016 but it did not revert cleanly (it looks like there was a run of backports for argparser from @serhiy-storchaka ) and I was not sure how to correctly resolve the conflicts. |
I was just going to report this issue (with a different reproducer). The 2to3 benchmark in pyperformance is hanging due to this -- same first bad commit of 6387016. I see the same behavior with the Tier 2 interpreter as the full JIT. To reproduce (with a checkout of pyperformance): python -m lib2to3 -f all benchmarks/bm_2to3/vendor Traceback (most recent call last):
File "<frozen runpy>", line 198, in _run_module_as_main
File "<frozen runpy>", line 88, in _run_code
File "/home/mdboom/Work/builds/pyperformance/venv/lib/python3.13/site-packages/lib2to3/__main__.py", line 4, in <module>
sys.exit(main("lib2to3.fixes"))
~~~~^^^^^^^^^^^^^^^^^
File "/home/mdboom/Work/builds/pyperformance/venv/lib/python3.13/site-packages/lib2to3/main.py", line 263, in main
rt.refactor(args, options.write, options.doctests_only,
~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
options.processes)
^^^^^^^^^^^^^^^^^^
File "/home/mdboom/Work/builds/pyperformance/venv/lib/python3.13/site-packages/lib2to3/refactor.py", line 690, in refactor
return super(MultiprocessRefactoringTool, self).refactor(
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
items, write, doctests_only)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/mdboom/Work/builds/pyperformance/venv/lib/python3.13/site-packages/lib2to3/refactor.py", line 284, in refactor
self.refactor_dir(dir_or_file, write, doctests_only)
~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/mdboom/Work/builds/pyperformance/venv/lib/python3.13/site-packages/lib2to3/refactor.py", line 304, in refactor_dir
self.refactor_file(fullname, write, doctests_only)
~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/mdboom/Work/builds/pyperformance/venv/lib/python3.13/site-packages/lib2to3/refactor.py", line 731, in refactor_file
return super(MultiprocessRefactoringTool, self).refactor_file(
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
*args, **kwargs)
^^^^^^^^^^^^^^^^
File "/home/mdboom/Work/builds/pyperformance/venv/lib/python3.13/site-packages/lib2to3/refactor.py", line 339, in refactor_file
tree = self.refactor_string(input, filename)
File "/home/mdboom/Work/builds/pyperformance/venv/lib/python3.13/site-packages/lib2to3/refactor.py", line 371, in refactor_string
self.refactor_tree(tree, name)
~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^
File "/home/mdboom/Work/builds/pyperformance/venv/lib/python3.13/site-packages/lib2to3/refactor.py", line 414, in refactor_tree
match_set = self.BM.run(tree.leaves())
File "/home/mdboom/Work/builds/pyperformance/venv/lib/python3.13/site-packages/lib2to3/btm_matcher.py", line 103, in run
while current_ast_node:
^^^^^^^^^^^^^^^^
KeyboardInterrupt |
Both of these reproducers do some argument parsing, so I wouldn’t be surprised if the argparse change created some new code path that the JIT doesn’t reason about properly. Hm. I wonder if backporting GH-125935 could fix it. I’ll try reproducing with and without that commit. |
Hm, nevermind. 3.13 doesn't even support jitting |
I can reproduce the |
Last few traces compiled before the hang support the theory that this could indeed be triggered by the argparse change, and possibly string-related:
|
Digging a bit deeper, what I'm seeing during the hang is the same trace being compiled over and over again:
I really wish we had a smaller reproducer, because any change I make to the loop being compiled moves the hang to another file... |
It's really hard to create a minimal reproducer for this, but here's what I think you need to do to hit this:
So here's what appears to be happening:
Basically, our forward progress guarantees are being broken. |
It's the allocation of the new executor that's re-scheduling GC (and re-setting the eval breaker). |
Okay, this is pretty contrived (in order to keep the GC in a state that triggers the bug), but here's a reproducer: import gc
THRESHOLD = gc.get_threshold()[0]
REFS = []
def create_gc_objects_during_gc(phase, info):
# Simulate the creation of a full young generation of GC objects in a dying
# object's finalizer:
if phase == "stop":
for _ in range(THRESHOLD):
REFS.append([])
def f():
for _ in range(17): # Just enough times to JIT.
# Loop size of at least 256 instructions to force an EXTENDED_ARG jump.
# This is 128 * (LOAD_FAST + POP_TOP):
_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_
_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_
_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_
_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_;_
# The young generation is currently full. Allocating the executor will
# schedule a collection, which will trigger the bug.
gc.callbacks.append(create_gc_objects_during_gc)
gc.collect() # Clean slate, with a full young generation.
f() # Hang! |
|
@brandtbucher: Do you have any insight into why this doesn't happen on main? Is it the incremental gc? |
Bug report
Bug description:
Attempting to install cython on the 3.13 branch fails with what looks like an infinite loop that sits there and burns CPU forever.
I have bisected this to #124266 which makes no sense to me, but I'm pretty confident about it as observed behavior.
bisect log:
The Python invocation it is failing on from setuptools is :
I have not succeeded in getting traceback out of this yet.
attn @da-woods @scoder
CPython versions tested on:
3.13, CPython main branch
Operating systems tested on:
Linux
The text was updated successfully, but these errors were encountered: