繁体   English   中英

我如何告诉 Python 脚本停止调试器附加到进程?

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

有没有办法告诉 Python 在脚本中的某个点停止执行并等待调试器附加到进程?

Python 中是否有类似于 dot-Net 的Debugger.Break()的东西?

不同的 IDE 可以使用不同的方法附加到进程,但是 PyCharm、Eclipse、Visual Studio 和 VS Code 都使用pydevd (VS/VSC,通过它们的 Python 插件通过ptvsd )来提供它们的进程内调试器实现。 因此,我们可以用一段代码来定位那些。

这个想法是等到pydevd被导入,然后在断点处停止。

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

由于 pydevd 创建__builtins__.breakpoint ,无论 Python 版本如何,这都应该有效。 我在 PyCharm(社区版 2019.1.3)中进行了测试。 我启动了脚本,在我的 IDE 中附加了“附加到进程”选项,并且能够成功附加。 然后脚本按预期在breakpoint()处停止。

安装ipython 和 ipdb 之后你就可以使用

import ipdb
ipdb.set_trace()

并直接从控制台调试。 您还可以使用开箱即用的 pdb :

import pdb
pdb.set_trace()

这是您可以等待pydevd另一种方法:

while not (pydevd.connected and get_global_debugger().ready_to_run):
    sleep(0.3)
breakpoint()

在我的设置中, MetaPathFinder仅在我第一次与pydevd连接时pydevd 使用 while 循环,您应该能够重新连接,因为您不依赖于pydevd import 副作用。

改进 Timofey Solonin 的回答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

# ...

改进是不使用pydevd.connected 它没有在 pydevd 2.8 版中定义。

请注意,在 Linux 上,您可能会遇到无权附加到进程的问题。 尝试将 GDB 附加到进程时如何解决“不允许 ptrace 操作”?

您可以使用我的工具madbg来做到这一点。 把它放在你的程序中:

madbg.set_trace()

此行将阻塞,直到调试器使用以下方式连接:

madbg connect

madbg可以从同一台机器或通过.network 连接。 它还可以抢先停止您的进程并附加到它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM