递归日志导致Python 3解释器崩溃

4
以下代码在 Python 3.6 中记录了一个错误并调用自身,导致堆栈溢出并最终崩溃核心。
>>> import logging
>>> def rec():
...     logging.error("foo")
...     rec()
>>> rec()

[1]    101641 abort (core dumped)  python3

顺便说一句,这不会导致Python 2.7崩溃。

以下是在Python 3.6中收到的错误信息(已压缩):

ERROR:root:foo
...
--- Logging error ---
Traceback (most recent call last):
...
RecursionError: maximum recursion depth exceeded in comparison
...
Fatal Python error: Cannot recover from stack overflow.
...
[1]    101641 abort (core dumped)  python3

Python 2.7:

RuntimeError: maximum recursion depth exceeded

但是在Python 2.7中没有核心转储。

顺便说一下,如果日志级别设置为logging.ERROR,则Python 3.6中出现的上述错误也会发挥作用。其他日志级别同样如此。

更新:我已经记录了一个问题来跟进Python社区issue


2
没有停止条件 - 我在 Python 2.7 中的测试达到了最大递归深度。在 Python 3 中,我猜调用堆栈会溢出,但我不是很确定。 - Tobias Brösamle
1
@TobiasBrösamle 你当然是对的。我对楼主的说法感到惊讶,他说它不会崩溃Python 2.7。还有3个赞... - ElmoVanKielmo
@ElmoVanKielmo,担心的是Python 3.6会中止并转储核心,从而使我失去整个工作会话。在Python 2.7中不会发生这种情况。 - Saim Raza
1
@ElmoVanKielmo 我同意你的说法,不过在Python解释器中,可以从这个异常中恢复,而在这个特定的例子中则不行。(因此,我认为这篇文章还是比较有用的) - Adonis
2
@SaimRaza,我想建议你直接向CPython开发人员报告错误,但你已经这样做了,并且似乎取得了成功 https://bugs.python.org/issue36272 - 做得好 - 现在为你的问题投票! - ElmoVanKielmo
显示剩余6条评论
1个回答

2

你的代码最终会导致一个RuntimeError(Python 2.7)或者RecursionError(Python 3.6)。这是因为两个版本中递归深度都被限制在1000以下:

最初的回答如上,希望我能够帮到您。

>>>import sys
>>>sys.getrecursionlimit()
1000

如果实际上导致堆栈溢出引起崩溃,可能的原因之一是递归深度限制已被修改。最初的回答:如果程序出现了堆栈溢出引起的崩溃,可能的原因是修改了递归深度限制。

我检查了递归限制,并且在两个版本中都设置为1000。 - Saim Raza

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接