【问题标题】:Why is there a length limit to python's eval?为什么 python 的 eval 有长度限制?
【发布时间】:2023-03-02 23:50:02
【问题描述】:

我并不主张这将是一个好主意,但我发现您可以通过在足够大的输入字符串上运行 eval 来使 Python 崩溃(检查 2.7 和 3.2):

def kill_python(N):
    S = '+'.join((str(n) for n in xrange(N)))
    return eval(S)

在我的计算机上可以很好地生成S,但是对于大约N>74900 的值,Python 将失败并显示Segmentation fault (core dumped)。解释器可以处理的字符串(或解析树)的长度是否有限制?

注意:我不需要这样做,对我来说这是一个更深层次的问题,反映出我对盒子里发生的事情一无所知。我想了解为什么 Python 在这里失败了,而且是灾难性的(为什么不抛出异常?)

【问题讨论】:

  • IIRC,Python 解释器段错误在任何情况下都被认为是一个错误,不应该发生 - 这可能值得bug report
  • @Lattyware:在大多数情况下,不是全部。但是这个应该被认为是一个错误。
  • 有趣的是,sum(xrange(75000)) 似乎工作得很好
  • @SvenMarnach 想到了一些例外(最明显的是导致 CPython 崩溃的扩展模块),但由于这是核心功能,我认为 - 正如你所说 - 这可能是一个错误。
  • 这里的答案也可以看到:stackoverflow.com/questions/5177432/…

标签: python segmentation-fault eval


【解决方案1】:

此问题是由 CPython 编译器中的堆栈溢出引起的。重现相同问题的简单方法是

>>> code = compile("1" + "+1" * 1000000, "", "eval")
Segmentation fault

这证明段错误发生在编译阶段,而不是评估期间。 (当然这个用gdb也很容易确认。)

[旁注:对于较小的表达式,编译器无论如何都会在此处应用常量折叠,因此在代码执行期间唯一发生的事情就是加载结果:

>>> code = compile("1" + "+1" * 1000, "", "eval")
>>> eval(code)
1001
>>> dis.dis(code)
  1           0 LOAD_CONST            1000 (1001)
              3 RETURN_VALUE        

旁注结束。]

这个问题是known defect。 Python 开发人员在源代码分发的directory Lib/test/crashers 中收集了几种使 Python 解释器崩溃的方法。这个问题对应的是Lib/test/crashers/compiler_recursion.py

【讨论】:

  • 仅供参考,这似乎在 Python 3.3+ 中已修复。代码现在引发RecursionError: maximum recursion depth exceeded during compilation
猜你喜欢
  • 1970-01-01
  • 2010-10-16
  • 2010-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-21
  • 1970-01-01
相关资源
最近更新 更多