我有一个Python应用程序,它不时卡住,我不知道在哪里。
是否有任何方法向Python解释器发出信号,以显示正在运行的确切代码?
某种飞行中的堆叠痕迹?
相关问题:
从Python代码中的方法打印当前调用堆栈 检查正在运行的进程正在做什么:打印未检测的Python程序的堆栈跟踪
我有一个Python应用程序,它不时卡住,我不知道在哪里。
是否有任何方法向Python解释器发出信号,以显示正在运行的确切代码?
某种飞行中的堆叠痕迹?
相关问题:
从Python代码中的方法打印当前调用堆栈 检查正在运行的进程正在做什么:打印未检测的Python程序的堆栈跟踪
当前回答
可以使用PuDB,这是一个带有curses接口的Python调试器。只需添加
from pudb import set_interrupt_handler; set_interrupt_handler()
到您的代码中,并在需要中断时使用Ctrl-C。你可以继续使用c,如果你错过了它,想要再试一次,你可以再次打破多次。
其他回答
>>> 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进程来打印堆栈。
pyrasite可以在没有调试符号的情况下,在常规python中运行一个未准备好的python程序,从而获得该程序的堆栈跟踪。在Ubuntu Trusty上对我来说很有魅力:
$ sudo pip install pyrasite
$ echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
$ sudo pyrasite 16262 dump_stacks.py # dumps stacks to stdout/stderr of the python program
(向@Albert致敬,在其他工具中,他的回答包含指向this的指针。)
在运行代码时,您可以插入这个小片段,以查看格式化良好的打印堆栈跟踪。它假设在项目的根目录中有一个名为logs的文件夹。
# DEBUG: START DEBUG -->
import traceback
with open('logs/stack-trace.log', 'w') as file:
traceback.print_stack(file=file)
# DEBUG: END DEBUG --!
我几乎总是处理多线程,主线程通常不做太多,所以最有趣的是转储所有堆栈(这更像Java的转储)。下面是一个基于这个博客的实现:
import threading, sys, traceback
def dumpstacks(signal, frame):
id2name = dict([(th.ident, th.name) for th in threading.enumerate()])
code = []
for threadId, stack in sys._current_frames().items():
code.append("\n# Thread: %s(%d)" % (id2name.get(threadId,""), threadId))
for filename, lineno, name, line in traceback.extract_stack(stack):
code.append('File: "%s", line %d, in %s' % (filename, lineno, name))
if line:
code.append(" %s" % (line.strip()))
print("\n".join(code))
import signal
signal.signal(signal.SIGQUIT, dumpstacks)
你可以使用hypno包,像这样:
hypno <pid> "import traceback; traceback.print_stack()"
这将把堆栈跟踪打印到程序的标准输出中。
或者,如果你不想打印任何东西到stdout,或者你没有访问它的权限(例如守护进程),你可以使用madbg包,这是一个python调试器,允许你附加到一个正在运行的python程序并在当前终端中调试它。它类似于pyrasite和pyringe,但更新,不需要gdb,并使用IPython作为调试器(这意味着颜色和自动补全)。
要查看正在运行的程序的堆栈跟踪,你可以运行:
madbg attach <pid>
在调试器shell中,输入: 英国电信
免责声明——这两个包都是我写的