Reputation: 1805
Is there a way to tell Python to halt execution at a certain point in a script and wait for a debugger to attach to the process?
Is there something similar to dot-Net's Debugger.Break()
in Python?
Upvotes: 7
Views: 4856
Reputation: 6012
You can use my tool madbg to do exactly that. Put this in your program:
madbg.set_trace()
This line will block until a debugger connects using:
madbg connect
madbg
could connect from the same machine or over the network. It could also preemptively stop your process and attach to it.
Upvotes: -1
Reputation: 2175
Improving on Timofey Solonin's answer https://stackoverflow.com/a/66841531/324204.
# ...
import pydevd
import time
while pydevd.get_global_debugger() is None or not pydevd.get_global_debugger().ready_to_run:
time.sleep(0.3)
breakpoint() # breaks here
# ...
The improvement is to not use pydevd.connected
. It is not defined in pydevd version 2.8.
Note that on Linux you may have a problem with having no permissions to attach to the process. How to solve "ptrace operation not permitted" when trying to attach GDB to a process?
Upvotes: 1
Reputation: 1403
Here is another way you can wait for pydevd
:
while not (pydevd.connected and get_global_debugger().ready_to_run):
sleep(0.3)
breakpoint()
In my setup MetaPathFinder
was firing only the first time I would connect with pydevd
. With a while loop you should be able to reconnect because you are not relying on pydevd
import side effect.
Upvotes: 1
Reputation: 4030
Different IDEs can use different methods for attaching to the process, however PyCharm, Eclipse, Visual Studio, and VS Code all use pydevd (VS/VSC via their Python plugin via ptvsd) to provide their in-process debugger implementation. As a result, we can target those with one piece of code.
The idea is to wait until pydevd is imported and then stop at a breakpoint.
import sys
import threading
from importlib.abc import MetaPathFinder
class NotificationFinder(MetaPathFinder):
def find_spec(self, fullname, _path, _target=None):
if 'pydevd' in fullname:
with t:
t.notify()
t = threading.Condition()
sys.meta_path.insert(0, NotificationFinder())
with t:
t.wait()
breakpoint()
Since pydevd creates __builtins__.breakpoint
, this should work regardless of the Python version. I tested in PyCharm (Community Edition 2019.1.3). I started the script, attached with the "Attach to process" option in my IDE, and was able to attach successfully. The script then stopped at breakpoint()
as expected.
Upvotes: 8
Reputation: 690
Install ipython and ipdb. Afterwards you can just use
import ipdb
ipdb.set_trace()
And debug straight from the console. You can also use pdb which comes straight out of the box:
import pdb
pdb.set_trace()
Upvotes: 2