2012-07-24 9 views
23

私はこれが今まで良いアイデアだと主張していないんだけど、私はあなたが十分な大きさの入力文字列にevalを実行することにより、Pythonの(2.7および3.2にチェック)をクラッシュできることを発見しました:オンなぜPythonのevalに長さ制限がありますか?

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がここで失敗するのか、そして壊滅的に(なぜ例外を投げないのですか)理解したいと思います。

+7

IIRCでは、Pythonインタプリタsegfaultingはどのような状況でもバグとみなされるため、発生しないようにしてください。これは[バグレポート](http://bugs.python.org/)の価値があります。 –

+4

@Lattyware:ほとんどの場合、すべてではありません。しかし、これはバグとみなすべきです。 –

+0

興味深いことに、 'sum(xrange(75000))'はうまく動いているようです。 – inspectorG4dget

答えて

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   

サイドノートの終了]

この問題はknown defectです。 Python開発者は、ソース配布のdirectory Lib/test/crashersでPythonインタプリタをクラッシュさせるいくつかの方法を収集しました。この問題に対応するものはLib/test/crashers/compiler_recursion.pyです。

+0

参考までに、これはPython 3.3以降で修正されているようです。このコードは、 'RecursionError:コンパイル時に最大再帰深度を超過しました。 ' –

関連する問題