問題描述
我并不主張這將是一個(gè)好主意,但我發(fā)現(xiàn)您可以通過在足夠大的輸入字符串上運(yùn)行 eval
來使 Python 崩潰(檢查 2.7 和 3.2):
I'm not advocating that this would ever be a good idea, but I've found that you can crash Python (2.7 and 3.2 checked) by running eval
on a large enough input string:
def kill_python(N):
S = '+'.join((str(n) for n in xrange(N)))
return eval(S)
在我的電腦上 S
可以很好地生成,但是對于大約 N>74900
的值,Python 將失敗并出現(xiàn) Segmentation fault (core dumped)代碼>.解釋器可以處理的字符串(或解析樹)的長度是否有限制?
On my computer S
can be generated just fine, but for values of approximately N>74900
, Python will fail with Segmentation fault (core dumped)
. Is there a limit to the length of string (or parse tree) that the interpreter can handle?
注意:我不需要這樣做,對我來說這是一個(gè)更深層次的問題,反映出我對盒子里發(fā)生的事情一無所知.我想了解為什么 Python 在這里失敗了,而且是災(zāi)難性的(為什么不拋出異常?)
Note: I don't need to do this, to me this is a deeper question reflecting my ignorance of what goes on inside the box. I'd like to understand why Python fails here, and so catastrophically (why not throw an exception?)
推薦答案
這個(gè)問題是由 CPython 編譯器中的堆棧溢出引起的.重現(xiàn)相同問題的簡單方法是
This issue is caused by a stack overflow in the CPython compiler. An easy way to reproduce the same issue is
>>> code = compile("1" + "+1" * 1000000, "", "eval")
Segmentation fault
這證明段錯(cuò)誤發(fā)生在編譯階段,而不是評估期間.(當(dāng)然這個(gè)用gdb也很容易確認(rèn).)
which proves that the segfault is happening at the compile stage, not during evaluation. (Of course this is also easy to confirm with gdb.)
[旁注:對于較小的表達(dá)式,編譯器無論如何都會(huì)在此處應(yīng)用常量折疊,因此在代碼執(zhí)行期間唯一發(fā)生的事情就是加載結(jié)果:
[Side note: For smaller expressions, the compiler would apply constant folding here anyway, so the only thing happening during the execution of the code is to load the result:
>>> code = compile("1" + "+1" * 1000, "", "eval")
>>> eval(code)
1001
>>> dis.dis(code)
1 0 LOAD_CONST 1000 (1001)
3 RETURN_VALUE
旁注結(jié)束.]
此問題是已知缺陷.Python 開發(fā)人員在 目錄 Lib/test/crashes
的源代碼分發(fā).與此問題對應(yīng)的是 Lib/測試/crashers/compiler_recursion.py
.
This issue is a known defect. The Python developers collected several ways to crash the Python interpreter in the directory Lib/test/crashers
of the source distribution. The one corresponding to this issue is Lib/test/crashers/compiler_recursion.py
.
這篇關(guān)于為什么 python 的 eval 有長度限制?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!