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
Traceback says line -1 when KeyboardInterrupt during minimal for-if-loop #107901
Comments
@markshannon as an expert here. I investigated the Lines 944 to 955 in ee40b3e
-1 set at
during the call of _PyCode_CheckLineNumber (lasti=42, bounds=...) Also the disassembly here:
|
cc @iritkatriel as well. I bisected to 4c72517, and I think this is the relevant line: Line 534 in ee40b3e
I assume we need every instruction that checks the eval breaker to also have a line number. It looks like Here's the disassembly showing a Disassembly of reproducer on main.def f():
for i in range(30000000):
if not i%1000000:
pass
import dis
from pprint import pprint
pprint(list(dis.get_instructions(f)))
|
In case this helps with debugging, I've played around a bit more and found an even simpler test case: for i in q: # Where q = [1]*int(3e7) or something similar.
if i:
pass |
Agree. |
Looks plausible. It might be simply a matter of copying the location of the old (backward jump) to the new jump that we are adding in this line. Let me know if you would like to try, or would prefer I do. |
Does the insertion of the extra jump take place before or after line number propagation? |
This also happens in 3.11, which suggests that 4c72517 is not the root cause. For the fix in 3.13 we might want to tag instructions that check the eval breaker (as well as raises and returns) as needing a line number, then make sure we propagate line numbers to those instructions. For the 3.11 and 3.12 maybe just backport the change to line propagation and not the metadata? |
It happens after line numbers are resolved. |
I created a PR that fixes the case that was reported here. We will need to follow up with tests that ensure that all instructions that check the eval breaker have a line number. I tested and found that this is not the case, I saw some instructions in exception handlers that violated this (and they were not as straightforward to fix). |
…of a for loop (pythonGH-108242) (cherry picked from commit a1cc74c) Co-authored-by: Irit Katriel <1055913+iritkatriel@users.noreply.github.com>
I've pushed a fix for 3.12 and main. In 3.11 this is a different problem - the JUMP transformation that needed fixing is not there. The bytecode looks like this:
You would have thought that the jump in line 44 would be removed as redundant, but it's not for some reason. Anyway, the problem is that the |
…he end of a for loop
I made a PR for 3.11 with the equivalent fix, but in that case it had impact on line tracing (I'm not sure why in 3.12 and main it didn't, but @markshannon might). The line trace in 3.11 ends up showing the line of the |
Presumably the difference between 3.11 and 3.12 is PEP 669 (instrumentation). I agree that a fix that duplicates trace events is worse than not fixing it. And I'm not sure how much effort we should spend at this point to come up with a correct fix unique to 3.11. |
Can this issue be closed or is there more to do? |
Still need to do this:
|
… check the eval breaker
… check the eval breaker
More generally, the issue happens with all exceptions raised by other threads.
Run the code below and interrupt with ctrl+c.
With the following traceback:
The issue disappears as soon as we add just a bit more to the loop
The issue persists whether running from the shell or as a file or even using
exec
. It works the same inside functions/methods. It exists in 3.11 and 3.12 but not 3.10, across Windows and Linux.Linked PRs
The text was updated successfully, but these errors were encountered: