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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4163964/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 14:34:35  来源:igfitidea点击:

python: is it possible to attach a console into a running process

python

提问by Bin Chen

I just want to see the state of the process, is it possible to attach a console into the process, so I can invoke functions inside the process and see some of the global variables.

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

It's better the process is running without being affected(of course performance can down a little bit)

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

采纳答案by fmark

If you have access to the program's source-code, you can add this functionality relatively easily.

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

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

配方 576515Debugging a running python process by interrupting and providing an interactive prompt (Python)

To quote:

报价:

This provides code to allow any python program which uses it to be interrupted at the current point, and communicated with via a normal python interactive console. This allows the locals, globals and associated program state to be investigated, as well as calling arbitrary functions and classes.

To use, a process should import the module, and call listen() at any point during startup. To interrupt this process, the script can be run directly, giving the process Id of the process to debug as the parameter.

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

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



Another implementation of roughly the same concept is provided by rconsole. From the documentation:

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

rconsole is a remote Python console with auto completion, which can be used to inspect and modify the namespace of a running script.

To invoke in a script do:

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

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

from rfoo.utils import rconsole
rconsole.spawn_server()

To attach from a shell do:

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

$ rconsole

Security note: The rconsole listener started with spawn_server() will accept any local connection and may therefore be insecure to use in shared hosting or similar environments!

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

回答by mdeous

Why not simply using the pdbmodule? It allows you to stop a script, inspect elements values, and execute the code line by line. And since it is built upon the Python interpreter, it also provides the features provided by the classic interpreter. To use it, just put these 2 lines in your code, where you wish to stop and inspect it:

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

import pdb
pdb.set_trace()

回答by RobM

This will interrupt your process (unless you start it in a thread), but you can use the codemodule to start a Python console:

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

import code
code.interact()

This will block until the user exits the interactive console by executing exit().

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

The codemodule is available in at least Python v2.6, probably others.

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

I tend to use this approach in combination with signals for my Linux work (for Windows, see below). I slap this at the top of my Python scripts:

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

import code
import signal
signal.signal(signal.SIGUSR2, lambda sig, frame: code.interact())

And then trigger it from a shell with kill -SIGUSR2 <PID>, where <PID>is the process ID. The process then stops whatever it is doing and presents a console:

然后从 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)
>>>

Generally from there I'll load the server-side component of a remote debugger like the excellent WinPDB.

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

Windows is not a POSIX-compliant OS, and so does not provide the same signals as Linux. However, Python v2.2 and above expose a Windows-specific signal SIGBREAK(triggered by pressing CTRL+Pause/Break). This does notinterfere with normal CTRL+C(SIGINT) operation, and so is a handy alternative.

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

Therefore a portable, but slightly ugly, version of the above is:

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

import code
import signal
signal.signal(
        vars(signal).get("SIGBREAK") or vars(signal).get("SIGUSR2"),
        lambda sig, frame: code.interact()
        )

Advantages of this approach:

这种方法的优点:

  • No external modules (all standard Python stuff)
  • Barely consumes any resources until triggered (2x import)
  • 没有外部模块(所有标准的 Python 东西)
  • 在触发之前几乎不消耗任何资源(2x 导入)


Here's the code I use in my production environment which will load the server-side of WinPDB (if available) and fall back to opening a Python console.

这是我在生产环境中使用的代码,它将加载 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

回答by Joshua Richardson

Another possibility, without adding stuff to the python scripts, is described here:

此处描述了另一种不向 python 脚本添加内容的可能性:

https://wiki.python.org/moin/DebuggingWithGdb

https://wiki.python.org/moin/DebuggingWithGdb

Unfortunately, this solution also requires some forethought, at least to the extent that you need to be using a version of python with debugging symbols in it.

不幸的是,这个解决方案也需要一些深谋远虑,至少在你需要使用带有调试符号的 python 版本的程度上。

回答by python1981

Use pyrasite-shell. I can't believe it works so well, but it does. "Give it a pid, get a shell".

使用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'

This launches the python shell with access to the globals() and locals() variables of that running python process, and other wonderful things.

这将启动 python shell,可以访问正在运行的 python 进程的 globals() 和 locals() 变量,以及其他奇妙的东西。

Only tested this personally on Ubuntu but seems to cater for OSX too.

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

Adapted from this answer.

改编自这个答案

Note: The line switching off the ptrace_scopeproperty is only necessary for kernels/systems that have been built with CONFIG_SECURITY_YAMAon. Take care messing with ptrace_scope in sensitive environments because it could introduce certain security vulnerabilities. See herefor details.

注意:关闭ptrace_scope属性的行仅对于已构建为CONFIG_SECURITY_YAMAon 的内核/系统是必需的。在敏感环境中小心使用 ptrace_scope,因为它可能会引入某些安全漏洞。有关详细信息,请参见此处

回答by shao.lo

Using PyCharm, I was getting a failure to connect to process in Ubuntu. The fix for this is to disable YAMA. For more info see askubuntu

使用 PyCharm,我无法连接到 Ubuntu 中的进程。解决方法是禁用 YAMA。有关更多信息,请参阅askubuntu

echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope