转储所有活动线程的堆栈跟踪

Chr*_*iss 31 python multithreading zope plone

我正在尝试转储所有活动线程的列表,包括每个线程的当前堆栈.我可以使用threading.enumerate()获取所有线程的列表,但我无法找到从那里到达堆栈的方法.

背景:一个Zope/Plone应用程序不时出现问题,消耗100%的CPU并需要重新启动.我感觉这是一个没有正确终止的循环,但我无法在test-environemt中重现它以进行验证.我设法注册一个可以从外部触发的信号处理程序,所以我可以在情况再次发生时立即触发一些代码.如果我可以为所有活动线程转储堆栈跟踪,这将给我一个问题的线索.洞的东西在python 2.4上运行......

关于如何追踪这些情况的任何想法都值得赞赏:)

干杯,克里斯

cod*_*one 39

正如早期答案中的抖动指出的那样,sys._current_frames()为您提供v2.5 +所需的内容.对于懒惰,以下代码片段为我工作,可能会帮助您:

print >> sys.stderr, "\n*** STACKTRACE - START ***\n"
code = []
for threadId, stack in sys._current_frames().items():
    code.append("\n# ThreadID: %s" % 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()))

for line in code:
    print >> sys.stderr, line
print >> sys.stderr, "\n*** STACKTRACE - END ***\n"
Run Code Online (Sandbox Code Playgroud)


小智 23

对于Python 3.3及更高版本,有faulthandler.dump_traceback().

下面的代码产生类似的输出,但包括线程名称,可以增强以打印更多信息.

for th in threading.enumerate():
    print(th)
    traceback.print_stack(sys._current_frames()[th.ident])
    print()
Run Code Online (Sandbox Code Playgroud)

  • 注意:faulthandler 代码在 python 3.9.4 中出现段错误(目前是 ubuntu 21.04 中的最新版本),大约两个月前在 3.9.7 python 版本中已修复此问题 (2认同)

Mar*_*ers 10

使用Zope时,你想安装Products.signalstackmr.freeze ; 这些都是为了这个目的而设计的!

向您的Zope服务器发送USR1信号,它会立即将所有线程的堆栈跟踪转储到控制台.即使所有Zope线程都被锁定,它也会这样做.

在引擎盖下这些包间接使用threadframes; 对于Python 2.5及更高版本,当使用Zope时,您可以使用该sys._current_frames()函数构建相同的功能来访问每线程堆栈帧.

Zope 2.12.5开始,此功能已集成到Zope本身,无需再安装其他软件包.


jit*_*ter 7

2.4.太糟糕了.从Python 2.5开始sys._current_frames().

但你可以试试threadframe.如果makefile给你带来麻烦,你可以尝试使用setup.py来获取threadframe

使用threadframe时的示例输出