为了账号安全,请及时绑定邮箱和手机立即绑定

sys._current_frames() 中的孤立堆栈跟踪

sys._current_frames() 中的孤立堆栈跟踪

慕妹3146593 2022-10-06 16:02:03
这是一个深奥的纯 Python 问题。我正在使用sys._current_frames(). 即,我有一个sys._current_frames()每秒运行一次的后台线程,将结果转储到一个文本文件中,然后我有一些 Python 代码可以从最常见到最少对回溯进行排序。我见过的一个奇怪现象是这样的回溯:  File "/opt/foo/bar.py", line 1437, in __iter__       yield key这yield是我写的生成器。奇怪的是,这个回溯只有一帧。这怎么可能?另一个回溯有很多帧,要么来自进程的顶层,要么来自帧的顶层。这个单帧堆栈跟踪是什么意思?我的一个理论是,这是生成器的冻结状态,在它产生一个值之后,它正在等待next再次调用它。但我想我用一个单独的实验反驳了这个理论:我做了一个生成器,确保它被暂停,被调用 sys._current_frames(),但我没有看到那种堆栈跟踪。
查看完整描述

1 回答

?
交互式爱情

TA贡献1712条经验 获得超3个赞

正如sys._current_frames() 文档警告的那样,

这对于调试死锁最有用:此功能不需要死锁线程的合作,并且只要它们保持死锁,这些线程的调用堆栈就会被冻结。在调用代码检查帧时,为非死锁线程返回的帧可能与该线程的当前活动无关。

sys._current_frames()在您不能保证感兴趣的线程被暂停的任何情况下,自然容易出现竞争条件。


正如您所怀疑的,您看到的是暂停生成器的堆栈跟踪。当一个生成器挂起时,它的栈帧没有父帧。它f_back被设置为空。

sys._current_frames()检索当前正在运行的线程的堆栈帧,但是当您查看这些帧时,它们可能不再运行了。如果生成器在您调用sys._current_frames()和检查框架之间暂停,这就是它的样子。sys._current_frames()如果它在其他地方恢复,您可能还会在看起来与您实际调用时完全不同的调用堆栈顶部看到它。

您的测试没有显示生成器框架,因为您在调用之前sys._current_frames()而不是之后暂停了生成器。生成器的堆栈帧此时不是任何线程的活动帧。


查看完整回答
反对 回复 2022-10-06
  • 1 回答
  • 0 关注
  • 157 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号