获取无法接受信号的卡住的Python进程的堆栈跟踪
我需要运行一个老旧的Zope2网站,但对它有些不满。最大的问题是,它偶尔会卡住,CPU使用率飙到100%,然后就不再响应请求了。虽然这个问题并不是经常发生,但有一个页面上有3个动态图表,有时会引发这个问题,所以我怀疑可能是某种竞争条件导致了无限循环或者卡住了。
问题是,我还没有找到调试这个问题的方法。Zope的日志里没有任何信息,系统日志也没有。我尝试了这个问题中的建议来获取堆栈跟踪,但唯一有效的信号是SIGKILL
。
有没有其他方法可以找出进程在卡住时到底在哪里?
7 个回答
3
你可以看看我对这个问题的回答,使用Products.signalstack。它在产品注册时注册了和你找到的答案一样的处理程序。也许这对你来说效果更好。
如果还是不行,那你可能遇到了操作系统层面的输入输出问题,这时候你唯一的希望就是把gdb附加到这个进程上。可以在Stack Overflow上搜索关于gdb的答案,这里有很多有用的信息!
13
你可以使用 pyrasite 来打印出漂亮的堆栈跟踪信息。
首先,你需要安装 gdb。
# Redhat, CentOS, etc
$ yum install gdb
# Ubuntu, Debian, etc
$ apt-get update && apt-get install gdb
然后,安装 pyrasite。
$ pip install pyrasite
接下来,使用 ps
命令或者其他方法找到卡住的 Python 进程的进程 ID,然后用这个 ID 运行 pyrasite-shell
。
# Assuming process ID is 12345
$ pyrasite-shell 12345
现在你应该能看到一个 Python 的交互式命令行。接着在这个命令行中运行以下命令,就能看到所有线程的堆栈跟踪信息。
import sys, traceback
for thread_id, frame in sys._current_frames().items():
print 'Stack for thread {}'.format(thread_id)
traceback.print_stack(frame)
print ''
0
如果这个程序卡住了,完全没有其他信号能传递过去,你可以考虑用调试工具来运行它,而不是试着在它运行的时候去连接它。
另外,尝试其他调试方法也可能会有帮助,比如关闭代码中的某些部分,这样可以找到一个最简单的情况,看看问题是否还会出现,这样更容易找出问题的原因。