2012-07-24 15 views
23

Bunun hiç iyi bir fikir olacağını savunan değilim, ama yeterince büyük bir giriş dizesi eval çalıştırarak Python (2.7 ve 3.2 işaretli) çökmesine olabileceğini saptadık:Python'un değerlendirmesine neden bir uzunluk sınırı var?

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

Açık Bilgisayarım S sadece iyi oluşturulabilir, ancak yaklaşık N>74900 değerleri için Python Segmentation fault (core dumped) ile başarısız olur. Tercümanın işleyebileceği dizgenin (veya ayrıştırma ağacının) uzunluğunun bir sınırı var mı?

Not: Bunu yapmak için gerek yok, bana bu kutunun içinde neler olup bittiğinin benim cehalet yansıtan derin bir sorudur. Python'un neden başarısız olduğunu ve neden bu kadar yıkıcı olduğunu (neden bir istisna atmamalı?) Anlamayı isterim.

+7

IIRC, Python yorumlayıcısı segfaultmanı her durumda bir hata olarak kabul edilir ve olmamalıdır - bu bir [hata raporu] (http://bugs.python.org/) değerinde olabilir. –

+4

@Lattyware: Çoğu durumda, hepsi değil. Ama bu bir * bir böcek olarak görülmelidir. –

+0

İlginç bir şekilde, 'sum (xrange (75000))' gayet iyi çalışıyor gibi görünüyor – inspectorG4dget

cevap

18

Bu sorun, CPython derleyicisindeki yığın taşması nedeniyle oluşur. Aynı sorunu yeniden oluşturmak için kolay bir yol segfault değil değerlendirme sırasında, derleme aşamasında oluyor kanıtlıyor

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

olduğunu. (Elbette gdb ile onaylamak da kolaydır.)

[Yan not: Daha küçük ifadeler için derleyici burada sabit bir şekilde katlanır, bu nedenle kodun yürütülmesi sırasında meydana gelen tek şey sonucu yüklemektir. :. yan not

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

sonu]

Bu sorun bir known defect olduğunu. Python geliştiricileri, kaynak dağıtımının directory Lib/test/crashers'unda Python yorumlayıcısını çökertmek için çeşitli yollar topladı. Bu soruna karşılık gelen Lib/test/crashers/compiler_recursion.py'dur.

+0

Sadece referans için, bu Python 3.3+ 'de sabitlenmiş gibi görünüyor. Kod, "RecursionError: derleme sırasında maksimum yineleme derinliği aşıldı" seçeneğini yükseltir. –

İlgili konular