23

私はこれが良い考えだとは主張していませんが、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が失敗する理由を理解したいので、壊滅的に(例外をスローしないのはなぜですか?)

4

1 に答える 1

18

この問題は、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        

サイドノートの終わり。]

この問題は既知の欠陥です。Python開発者は、ソースディストリビューションのディレクトリでPythonインタープリターをクラッシュさせるいくつかの方法を収集しました。Lib/test/crashersこの問題に対応するのはLib/test/crashers/compiler_recursion.pyです。

于 2012-07-24T21:44:01.187 に答える