从正在运行的Python应用程序中显示堆栈跟踪
我有这个不时被卡住的Python应用程序,我找不到在哪里。
有什么方法可以告诉Python解释器向您显示正在运行的确切代码吗?
某种即时堆栈跟踪?
相关问题:
我有这样的情况下使用的模块 - 一个进程将会运行很长时间,但有时会出现未知和不可重复的原因。 它有点怪异,只适用于unix(需要信号):
import code, traceback, signal
def debug(sig, frame):
"""Interrupt running process, and provide a python prompt for
interactive debugging."""
d={'_frame':frame} # Allow access to frame object.
d.update(frame.f_globals) # Unless shadowed by global
d.update(frame.f_locals)
i = code.InteractiveConsole(d)
message = "Signal received : entering python shell.nTraceback:n"
message += ''.join(traceback.format_stack(frame))
i.interact(message)
def listen():
signal.signal(signal.SIGUSR1, debug) # Register handler
要使用,只需在程序启动时的某个时刻调用listen()函数(甚至可以将它粘贴到site.py中让所有python程序使用它),然后让它运行。 在任何时候,使用kill或python发送进程一个SIGUSR1信号:
os.kill(pid, signal.SIGUSR1)
这将导致程序在当前所处的位置断开到一个python控制台,向您显示堆栈跟踪,并让您操作这些变量。 使用control-d(EOF)继续运行(尽管请注意,您可能会在您发出信号时中断任何I / O等,因此它不是完全非侵入式的。
我有另一个脚本执行相同的操作,除了通过管道与正在运行的进程通信(以允许调试后台进程等)。 在这里发布它有点大,但是我已经将它作为一个python食谱食谱加入。
建议安装一个信号处理程序是一个很好的建议,我使用它很多。 例如,默认情况下,bzr会安装一个调用pdb.set_trace()
立即将您放入pdb提示符的SIGQUIT处理程序。 (有关确切的细节,请参阅bzrlib.breakin模块的源代码。)使用pdb,您不仅可以获取当前堆栈跟踪,还可以检查变量等。
但是,有时我需要调试一个我没有先见之明的进程来安装信号处理程序。在linux上,您可以将gdb附加到进程并使用某些gdb宏来获取python堆栈跟踪。 把http://svn.python.org/projects/python/trunk/Misc/gdbinit放入~/.gdbinit
,然后:
gdb -p
PID
pystack
不幸的是,这不是完全可靠的,但它在大多数时间都有效。
最后,附加strace
通常会给你一个好主意,一个过程在做什么。
我几乎总是处理多个线程,主线程通常没有太多的工作,所以最有意思的是转储所有的堆栈(这更像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)
链接地址: http://www.djcxy.com/p/14459.html
上一篇: Showing the stack trace from a running Python application
下一篇: What does JVM flag CMSClassUnloadingEnabled actually do?