7

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?

5 Answers 5

8

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.

Sign up to request clarification or add additional context in comments.

1 Comment

This allows to attach to programs with a more complicated launch strategy, like ROS & ROS2!
2

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() 

3 Comments

ipdb is great, but pdb comes built-in with Python.
Still, I'm very interested in debugging from tools like PyCharm, and from my understanding pdb is limited to the console. Is there a way I could break and attach using a tool like PyCharm?
Well that would work differently. You can look up tutorials for it like this one: jetbrains.com/pycharm/help/remote-debugging.html
1

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.

Comments

1

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?

Comments

-1

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.