Closed
Description
Bug report
Bug description:
As @gaogaotiantian pointed out in #132451 (comment) PDB's new remote attaching feature can enter an uninterruptible infinite loop if you type while True: pass
at a PDB prompt. We're able to interrupt the script itself, when you 'cont'inue past a breakpoint, but aren't able to interrupt a statement evaluated interactively at a PDB prompt.
I have a few different ideas for how this could be fixed, though they all have different tradeoffs.
Options:
- the client can send a SIGINT signal to the remote.
-
- Pro: it can interrupt IO, as long as
PyErr_CheckSignals()
is being called by the main thread
- Pro: it can interrupt IO, as long as
-
- Con: it will not work on Windows
-
- Con: it will kill the process if the SIGINT handler has been unset (and PDB does mess with the signal handler - I'm not sure this is just a theoretical problem)
- we can raise a
KeyboardInterrupt
from an injected script
-
- Pro: It will work on Windows
-
- Con: We need to change
sys.remote_exec()
to allowKeyboardInterrupt
to escape
- Con: We need to change
-
- Pro: A looping injected script can be killed now, though!
-
- Con: It cannot interrupt IO
-
- Con: The
KeyboardInterrupt
will get raised even in places where signals were blocked, potentially leading to a crash where something that should never get an exception got one
- Con: The
- we can make PDB stop if
set_trace()
is called while it's evaluating a user-supplied statement
-
- Pro: it will work on Windows
-
- Con: It cannot interrupt IO
-
- Con: it will lead to recursion of PDB's trace function if the script is interrupted, and I don't know how well PDB will handle that
- the PDB server can start a thread that listens to a socket and calls
signal.raise_signal(signal.SIGINT)
every time it gets a message on the socket
-
- Pro: it can interrupt IO in the same cases as 1 can
-
- Pro: it works in "true remote" scenarios where the client and server are on different hosts (which isn't currently a feature, but would be a nice future feature)
-
- Pro: it works on Windows
-
- Con: more complexity, more failure modes
I'm currently leaning towards (4) - it's the most complete fix and works on the most platforms and the most scenarios (interrupting both CPU-bound and IO-bound stuff). I plan to prototype this soon.
CPython versions tested on:
CPython main branch
Operating systems tested on:
No response