我有一个Python应用程序,它不时卡住,我不知道在哪里。

是否有任何方法向Python解释器发出信号,以显示正在运行的确切代码?

某种飞行中的堆叠痕迹?

相关问题:

从Python代码中的方法打印当前调用堆栈 检查正在运行的进程正在做什么:打印未检测的Python程序的堆栈跟踪


当前回答

Pyringe是一个调试器,可以与正在运行的python进程交互,打印堆栈跟踪,变量等,而不需要任何先验设置。

虽然我过去经常使用信号处理程序解决方案,但在某些环境中仍然很难重现这个问题。

其他回答

使用inspect模块。

进口检查 帮助(inspect.stack) 模块检查中的函数堆栈帮助:

堆栈(上下文= 1) 返回调用者帧上面堆栈的记录列表。

我发现它确实很有帮助。

如果你需要用uWSGI来做这件事,它有内置的Python Tracebacker,这只是在配置中启用它的问题(编号附加在每个worker的名称上):

py-tracebacker=/var/run/uwsgi/pytrace

一旦你这样做了,你可以简单地通过连接到套接字打印反向跟踪:

uwsgi --connect-and-read /var/run/uwsgi/pytrace1
>>> import traceback
>>> def x():
>>>    print traceback.extract_stack()

>>> x()
[('<stdin>', 1, '<module>', None), ('<stdin>', 2, 'x', None)]

您还可以很好地格式化堆栈跟踪,请参阅文档。

编辑:为了模拟Java的行为,正如道格拉斯·里德所建议的那样,添加以下内容:

import signal
import traceback

signal.signal(signal.SIGUSR1, lambda sig, stack: traceback.print_stack(stack))

到应用程序中的启动代码。然后,您可以通过将SIGUSR1发送到正在运行的Python进程来打印堆栈。

你可以使用hypno包,像这样:

hypno <pid> "import traceback; traceback.print_stack()"

这将把堆栈跟踪打印到程序的标准输出中。

或者,如果你不想打印任何东西到stdout,或者你没有访问它的权限(例如守护进程),你可以使用madbg包,这是一个python调试器,允许你附加到一个正在运行的python程序并在当前终端中调试它。它类似于pyrasite和pyringe,但更新,不需要gdb,并使用IPython作为调试器(这意味着颜色和自动补全)。

要查看正在运行的程序的堆栈跟踪,你可以运行:

madbg attach <pid>

在调试器shell中,输入: 英国电信

免责声明——这两个包都是我写的

在Python 3中,当你第一次在调试器中使用c(ont(inue))时,pdb会自动安装一个信号处理程序。然后按Control-C会让你回到那里。在Python 2中,这里有一个单行程序,即使在相对较旧的版本中也可以工作(在2.7中测试过,但我检查了Python源代码回到2.4,看起来还可以):

import pdb, signal
signal.signal(signal.SIGINT, lambda sig, frame: pdb.Pdb().set_trace(frame))

如果你花时间调试Python, pdb是值得学习的。这个界面有点迟钝,但是对于使用过类似工具(比如gdb)的人来说应该很熟悉。