python:是否可以将控制台附加到正在运行的进程中

Bin*_*hen 78 python

我只想查看进程的状态,是否可以将控制台附加到进程中,因此我可以调用进程内的函数并查看一些全局变量.

这个过程在不受影响的情况下运行会更好(当然性能可以降低一点)

Rob*_*obM 57

这将中断您的进程(除非您在一个线程中启动它),但您可以使用该code模块启动Python控制台:

import code
code.interact()
Run Code Online (Sandbox Code Playgroud)

这将阻止,直到用户通过执行退出交互式控制台exit().

code模块至少可以在Python v2.6中使用,可能还有其他版本.

我倾向于将这种方法与我的Linux工作的信号结合使用(对于Windows,见下文).我把它放在Python脚本的顶部:

import code
import signal
signal.signal(signal.SIGUSR2, lambda sig, frame: code.interact())
Run Code Online (Sandbox Code Playgroud)

然后从shell中触发它kill -SIGUSR2 <PID>,其中<PID>是进程ID.然后,该过程将停止正在执行的操作并显示控制台:

Python 2.6.2 (r262:71600, Oct  9 2009, 17:53:52)
[GCC 3.4.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>
Run Code Online (Sandbox Code Playgroud)

通常从那里我将加载远程调试器的服务器端组件,如优秀的WinPDB.

Windows不是符合POSIX标准的操作系统,因此不提供与Linux相同的信号.但是,Python v2.2及更高版本会显示特定于Windows的信号SIGBREAK(按CTRL+键触发Pause/Break).这并不能与正常干扰CTRL+ C(SIGINT)操作,并且因此是一个方便的替代.

因此,以上的便携式但略显丑陋的版本是:

import code
import signal
signal.signal(
        vars(signal).get("SIGBREAK") or vars(signal).get("SIGUSR2"),
        lambda sig, frame: code.interact()
        )
Run Code Online (Sandbox Code Playgroud)

这种方法的优点:

  • 没有外部模块(所有标准的Python东西)
  • 在触发之前几乎不消耗任何资源(2x导入)

这是我在生产环境中使用的代码,它将加载WinPDB的服务器端(如果可用)并回退到打开Python控制台.

# Break into a Python console upon SIGUSR1 (Linux) or SIGBREAK (Windows:
# CTRL+Pause/Break).  To be included in all production code, just in case.
def debug_signal_handler(signal, frame):
    del signal
    del frame

    try:
        import rpdb2
        print
        print
        print "Starting embedded RPDB2 debugger. Password is 'foobar'"
        print
        print
        rpdb2.start_embedded_debugger("foobar", True, True)
        rpdb2.setbreak(depth=1)
        return
    except StandardError:
        pass

    try:
        import code
        code.interact()
    except StandardError as ex:
        print "%r, returning to normal program flow" % ex

import signal
try:
    signal.signal(
            vars(signal).get("SIGBREAK") or vars(signal).get("SIGUSR1"),
            debug_signal_handler
            )
except ValueError:
    # Typically: ValueError: signal only works in main thread
    pass
Run Code Online (Sandbox Code Playgroud)


fma*_*ark 42

如果您可以访问程序的源代码,则可以相对轻松地添加此功能.

食谱576515:Debugging a running python process by interrupting and providing an interactive prompt (Python)

报价:

这提供了代码,允许任何使用它的python程序在当前点被中断,并通过普通的python交互式控制台进行通信.这允许调查本地,全局和相关的程序状态,以及调用任意函数和类.

要使用,进程应该导入模块,并在启动期间的任何时候调用listen().要中断此过程,可以直接运行脚本,将进程的进程ID作为参数进行调试.


rconsole提供了大致相同概念的另一种实现方式.从文档:

rconsole是一个具有自动完成功能的远程Python控制台,可用于检查和修改正在运行的脚本的命名空间.

要在脚本中调用,请执行以下操作:

from rfoo.utils import rconsole
rconsole.spawn_server()
Run Code Online (Sandbox Code Playgroud)

要从shell附加,请执行以下操作:

$ rconsole
Run Code Online (Sandbox Code Playgroud)

安全说明:以spawn_server()开头的rconsole监听器将接受任何本地连接,因此可能不安全地在共享主机或类似环境中使用!

  • 这真的是一个非常好的食谱.使用管道和文件进行输入和输出非常聪明,我认为任何体面的项目都会受益于这样的功能. (2认同)
  • 虽然它非常不安全,所以要小心使用 (2认同)

pyt*_*981 23

使用pyrasite-shell.我无法相信它运作良好,但确实如此." 给它一个pid,得到一个shell ".

$ sudo pip install pyrasite
$ echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope # If YAMA activated, see below.
$ pyrasite-shell 16262
Pyrasite Shell 2.0
Connected to 'python my_script.py'
Python 2.7.6 (default, Jun 22 2015, 17:58:13) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.

>>> globals()
>>> print(db_session)
>>> run_some_local_function()
>>> some_existing_local_variable = 'new value'
Run Code Online (Sandbox Code Playgroud)

这将启动python shell,可以访问运行python进程的globals()和locals()变量,以及其他很棒的东西.

仅在Ubuntu上亲自测试过,但似乎也适合OSX.

改编自这个答案.

注意:ptrace_scope只有使用CONFIG_SECURITY_YAMAon 构建的内核/系统才需要关闭属性的行.在敏感环境中小心使用ptrace_scope,因为它可能会引入某些安全漏洞.详情请见此处.


mde*_*ous 6

为什么不简单地使用pdb模块?它允许您停止脚本,检查元素值,并逐行执行代码.由于它是基于Python解释器构建的,因此它还提供了经典解释器提供的功能.要使用它,只需将这两行放在您希望停止并检查它的代码中:

import pdb
pdb.set_trace()
Run Code Online (Sandbox Code Playgroud)

  • 你知道如何为给定的threading.enumerate()线程启动它吗? (3认同)