我有一个Python应用程序,它不时卡住,我不知道在哪里。
是否有任何方法向Python解释器发出信号,以显示正在运行的确切代码?
某种飞行中的堆叠痕迹?
相关问题:
从Python代码中的方法打印当前调用堆栈 检查正在运行的进程正在做什么:打印未检测的Python程序的堆栈跟踪
我有一个Python应用程序,它不时卡住,我不知道在哪里。
是否有任何方法向Python解释器发出信号,以显示正在运行的确切代码?
某种飞行中的堆叠痕迹?
相关问题:
从Python代码中的方法打印当前调用堆栈 检查正在运行的进程正在做什么:打印未检测的Python程序的堆栈跟踪
当前回答
如何调试任何函数在控制台:
创建使用pdb.set_trace()的函数,然后是要调试的函数。
>>> import pdb
>>> import my_function
>>> def f():
... pdb.set_trace()
... my_function()
...
然后调用创建的函数:
>>> f()
> <stdin>(3)f()
(Pdb) s
--Call--
> <stdin>(1)my_function()
(Pdb)
愉快的调试:)
其他回答
>>> 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进程来打印堆栈。
安装信号处理程序的建议很好,我经常使用它。例如,bzr默认安装一个SIGQUIT处理程序,调用pdb.set_trace()立即将您放入pdb提示符中。(参见bzrlib。进入模块的源代码以获取确切的细节。)使用pdb,您不仅可以获得当前堆栈跟踪(使用(w)here命令),还可以检查变量等。
然而,有时我需要调试一个我没有预见到在其中安装信号处理程序的进程。在linux上,您可以将gdb附加到进程,并使用一些gdb宏获得python堆栈跟踪。将http://svn.python.org/projects/python/trunk/Misc/gdbinit放在~/中。gdbinit,然后:
附加gdb: gdb -p PID 获取python堆栈跟踪:pystack
不幸的是,它不是完全可靠的,但它在大多数时候都是有效的。参见https://wiki.python.org/moin/DebuggingWithGdb
最后,附加strace通常可以让您很好地了解进程正在做什么。
我是GDB阵营的python扩展。关注https://wiki.python.org/moin/DebuggingWithGdb,这意味着
DNF install GDB python-debuginfo或sudo apt-get install GDB python2.7-dbg GDB python <运行进程>的pid py-bt
同时考虑info threads和thread apply all py-bt。
我想对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)
Pyringe是一个调试器,可以与正在运行的python进程交互,打印堆栈跟踪,变量等,而不需要任何先验设置。
虽然我过去经常使用信号处理程序解决方案,但在某些环境中仍然很难重现这个问题。