转储所有活动线程的堆栈跟踪
我正在尝试转储所有活动线程的列表,包括每个线程的当前堆栈。 我可以使用 threading.enumerate() 获取所有线程的列表,但我无法找到从那里访问堆栈的方法。
背景:Zope/Plone 应用程序有时会崩溃,消耗 100% 的 cpu,需要重新启动。 我有一种感觉,这是一个无法正确终止的循环,但我无法在测试环境中重现它以进行验证。 我设法注册了一个可以从外部触发的信号处理程序,这样我就可以在这种情况再次发生时触发一些代码。 如果我可以转储所有活动线程的堆栈跟踪,那就可以告诉我出了什么问题。 这个洞在 python 2.4 上运行...
任何有关如何追踪此类情况的想法都值得赞赏:)
干杯, 克里斯
I'm trying to dump a list of all active threads including the current stack of each. I can get a list of all threads using threading.enumerate(), but i can't figure out a way to get to the stack from there.
Background: A Zope/Plone app freaks out from time to time, consuming 100% of cpu and needs to be restarted. I have a feeling it's a loop which doesn't terminate properly, but i cannot reproduce it in the test-environemt for verification. I managed to register a signal handler which can be triggered from the outside, so i can trigger some code as soon as the situation occurs again. If I could dump the stacktrace for all active threads, that would give me a clue what goes wrong. The hole thing runs on python 2.4...
Any ideas on how to trace down situations like these are appreciated :)
Cheers,
Chriss
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
正如 jitter 在之前的回答中指出的那样,
sys._current_frames()
为您提供了 v2.5+ 所需的内容。 对于懒惰的人来说,以下代码片段对我有用,可能会对您有所帮助:As jitter points out in an earlier answer
sys._current_frames()
gives you what you need for v2.5+. For the lazy the following code snippet worked for me and may help you:对于 Python 3.3 及更高版本,有
faulthandler.dump_traceback( )
。下面的代码产生类似的输出,但包含线程名称,并且可以增强以打印更多信息。
For Python 3.3 and later, there is
faulthandler.dump_traceback()
.The code below produces similar output, but includes the thread name and could be enhanced to print more information.
使用 Zope 时,您需要安装
Products.signalstack
或 mr.freeze; 这些就是为了这个目的而设计的!向您的 Zope 服务器发送 USR1 信号,它会立即将所有线程的堆栈跟踪转储到控制台。 即使所有 Zope 线程都被锁定,它也会这样做。
在底层,这些包间接使用
threadframes
; 对于 Python 2.5 及更高版本,当不使用 Zope 时,您可以使用sys._current_frames()
函数来访问每个线程的堆栈帧。从 Zope 2.12.5 开始,此功能已集成到 Zope 本身中,并且没有需要再安装额外的软件包了。
When using Zope, you want to install
Products.signalstack
or mr.freeze; these were designed for just this purpose!Send a USR1 signal to your Zope server and it'll immediately dump stack traces for all threads to the console. It'll do this even if all Zope threads are locked up.
Under the hood these packages indirectly use
threadframes
; for Python versions 2.5 and up, when not using Zope, you can build the same functionality using thesys._current_frames()
function to access per-thread stack frames.As of Zope 2.12.5 this functionality is integrated into Zope itself, and there is no need to install additional packages anymore.
2.4. 太糟糕了。 从 Python 2.5 开始,有
sys._current_frames()
。但你可以尝试threadframe。 如果 makefile 给您带来麻烦,您可以尝试这个 setup.py对于 threadframe
使用 threadframe 时的示例输出
2.4. Too bad. From Python 2.5 on there is
sys._current_frames()
.But you could try threadframe. And if the makefile gives you trouble you could try this setup.py for threadframe
Sample output when using threadframe
只是为了完整起见, Products.LongRequestLogger 对于识别瓶颈非常有帮助,并这样做它以特定的时间间隔转储堆栈跟踪。
Just for completeness sake, Products.LongRequestLogger is super helpful to identify bottlenecks, and to do so it dumps stacktraces at specific intervals.
ASPN 上有一个适用的食谱。 您可以使用threading.enumerate()来获取所有tids,然后只需调用_async_raise()并使用一些合适的异常来强制进行堆栈跟踪。
There is an applicable recipe on ASPN. You can use
threading.enumerate()
to get all the tids, then just call _async_raise() with some suitable exception to force a stack trace.