我有一个Python应用程序,它不时卡住,我不知道在哪里。
是否有任何方法向Python解释器发出信号,以显示正在运行的确切代码?
某种飞行中的堆叠痕迹?
相关问题:
从Python代码中的方法打印当前调用堆栈 检查正在运行的进程正在做什么:打印未检测的Python程序的堆栈跟踪
我有一个Python应用程序,它不时卡住,我不知道在哪里。
是否有任何方法向Python解释器发出信号,以显示正在运行的确切代码?
某种飞行中的堆叠痕迹?
相关问题:
从Python代码中的方法打印当前调用堆栈 检查正在运行的进程正在做什么:打印未检测的Python程序的堆栈跟踪
当前回答
在Solaris上,你可以使用pstack(1)。不需要修改python代码。如。
# pstack 16000 | grep : | head
16000: /usr/bin/python2.6 /usr/lib/pkg.depotd --cfg svc:/application/pkg/serv
[ /usr/lib/python2.6/vendor-packages/cherrypy/process/wspbus.py:282 (_wait) ]
[ /usr/lib/python2.6/vendor-packages/cherrypy/process/wspbus.py:295 (wait) ]
[ /usr/lib/python2.6/vendor-packages/cherrypy/process/wspbus.py:242 (block) ]
[ /usr/lib/python2.6/vendor-packages/cherrypy/_init_.py:249 (quickstart) ]
[ /usr/lib/pkg.depotd:890 (<module>) ]
[ /usr/lib/python2.6/threading.py:256 (wait) ]
[ /usr/lib/python2.6/Queue.py:177 (get) ]
[ /usr/lib/python2.6/vendor-packages/pkg/server/depot.py:2142 (run) ]
[ /usr/lib/python2.6/threading.py:477 (run)
etc.
其他回答
没有办法钩入正在运行的python进程并获得合理的结果。如果进程锁定,我所做的是连接strace并试图弄清楚到底发生了什么。
不幸的是,strace通常是“修复”竞争条件的观察器,因此输出在那里也是无用的。
我正在寻找一段时间的解决方案来调试我的线程,我发现它在这里感谢haridsv。我使用稍微简化的版本,使用traceback.print_stack():
import sys, traceback, signal
import threading
import os
def dumpstacks(signal, frame):
id2name = dict((th.ident, th.name) for th in threading.enumerate())
for threadId, stack in sys._current_frames().items():
print(id2name[threadId])
traceback.print_stack(f=stack)
signal.signal(signal.SIGQUIT, dumpstacks)
os.killpg(os.getpgid(0), signal.SIGQUIT)
为了满足我的需要,我还按名称筛选线程。
在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)的人来说应该很熟悉。
从Austin 3.3开始,您可以使用-w/——where选项来发出当前堆栈跟踪。参见https://stackoverflow.com/a/70905181/1838793
如果您想查看正在运行的Python应用程序,以类似top的方式查看“活动”调用堆栈,可以使用austin-tui (https://github.com/p403n1x87/austin-tui)。你可以从PyPI安装它。
pipx install austin-tui
请注意,它需要austin二进制文件才能工作(https://github.com/p403n1x87/austin),但随后您可以使用
austin-tui -p <pid>
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的指针。)