我有一个Python应用程序,它不时卡住,我不知道在哪里。
是否有任何方法向Python解释器发出信号,以显示正在运行的确切代码?
某种飞行中的堆叠痕迹?
相关问题:
从Python代码中的方法打印当前调用堆栈 检查正在运行的进程正在做什么:打印未检测的Python程序的堆栈跟踪
我有一个Python应用程序,它不时卡住,我不知道在哪里。
是否有任何方法向Python解释器发出信号,以显示正在运行的确切代码?
某种飞行中的堆叠痕迹?
相关问题:
从Python代码中的方法打印当前调用堆栈 检查正在运行的进程正在做什么:打印未检测的Python程序的堆栈跟踪
当前回答
如果您使用的是Linux系统,请使用出色的gdb和Python调试扩展(可以在Python -dbg或Python -debuginfo包中)。它还有助于多线程应用程序、GUI应用程序和C模块。
使用以下命令运行程序:
$ gdb -ex r --args python <programname>.py [arguments]
这指示gdb准备python <programname>.py <arguments>并运行它。
现在当你的程序挂起时,切换到gdb控制台,按Ctr+C并执行:
(gdb) thread apply all py-list
参见示例会话和更多信息在这里和这里。
其他回答
在这里真正帮助我的是spiv的技巧(如果我有声望分数,我会投票并评论),即从一个未准备好的Python进程中获得堆栈跟踪。除非我修改了gdbinit脚本,否则它无法工作。所以:
下载https://svn.python.org/projects/python/trunk/Misc/gdbinit并将其放在~/.gdbinit中 编辑它,将PyEval_EvalFrame更改为PyEval_EvalFrameEx [edit:不再需要;链接的文件在2010-01-14已经有此更改] 附加gdb: gdb -p PID 获取python堆栈跟踪:pystack
我正在寻找一段时间的解决方案来调试我的线程,我发现它在这里感谢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)
为了满足我的需要,我还按名称筛选线程。
如果您使用的是Linux系统,请使用出色的gdb和Python调试扩展(可以在Python -dbg或Python -debuginfo包中)。它还有助于多线程应用程序、GUI应用程序和C模块。
使用以下命令运行程序:
$ gdb -ex r --args python <programname>.py [arguments]
这指示gdb准备python <programname>.py <arguments>并运行它。
现在当你的程序挂起时,切换到gdb控制台,按Ctr+C并执行:
(gdb) thread apply all py-list
参见示例会话和更多信息在这里和这里。
使用inspect模块。
进口检查 帮助(inspect.stack) 模块检查中的函数堆栈帮助:
堆栈(上下文= 1) 返回调用者帧上面堆栈的记录列表。
我发现它确实很有帮助。
我想对haridsv的回答加一个评论,但我缺乏这样做的声誉:
我们中的一些人仍然停留在2.6以上的Python版本(thread .ident需要),所以我让代码在Python 2.5中工作(尽管没有显示线程名称):
import traceback
import sys
def dumpstacks(signal, frame):
code = []
for threadId, stack in sys._current_frames().items():
code.append("\n# Thread: %d" % (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)