How can I tell a Python script to halt for debugger attach to process?

Question:

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?

Asked By: Nitzan

||

Answers:

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()
Answered By: GLaDOS

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.

Answered By: Chris Hunt

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.

Answered By: Timofey Solonin

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?

Answered By: Sogartar

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.

Answered By: kmaork
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.