2012-07-24 11 views
23

मैं वकालत नहीं कर रहा है कि यह कभी एक अच्छा विचार हो सकता है, लेकिन मैं पाया है कि आप एक बड़ा पर्याप्त इनपुट स्ट्रिंग पर eval चलाकर अजगर (2.7 और 3.2 की जाँच) दुर्घटना कर सकते हैं:पायथन के eval की लंबाई सीमा क्यों है?

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

पर अपने कंप्यूटर S ठीक उत्पन्न किया जा सकता है, लेकिन लगभग N>74900 के मूल्यों के लिए, अजगर Segmentation fault (core dumped) साथ असफल हो जायेगी। क्या स्ट्रिंग (या पार्स पेड़) की लंबाई की सीमा है जो दुभाषिया संभाल सकता है?

नोट: मैं जरूरत नहीं है ऐसा करने के लिए, यह मेरे लिए क्या बॉक्स के अंदर चला जाता है की मेरी अज्ञानता को दर्शाती एक गहरी सवाल है। मैं समझना चाहता हूं कि क्यों पाइथन यहां विफल रहता है, और इतनी विनाशकारी (क्यों अपवाद फेंक नहीं?)

+7

IIRC, पायथन दुभाषिया segfaulting किसी भी स्थिति में एक बग माना जाता है, और ऐसा नहीं होना चाहिए - यह एक [बग रिपोर्ट] के लायक हो सकता है (http://bugs.python.org/)। –

+4

@ लैटवेयर: ज्यादातर स्थितियों में, सभी नहीं। लेकिन यह एक * एक बग माना जाना चाहिए। –

+0

दिलचस्प है, 'राशि (xrange (75000))' ठीक से काम करने लगता है – inspectorG4dget

उत्तर

18

यह समस्या सीपीथॉन कंपाइलर में एक स्टैक ओवरफ़्लो के कारण होती है। एक आसान तरीका है एक ही समस्या को ठीक करने

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

जो साबित करता है कि segfault, संकलन स्तर पर हो रहा है नहीं मूल्यांकन के दौरान होता है। (बेशक यह gdb के साथ पुष्टि करना भी आसान है।)

[साइड नोट: छोटे अभिव्यक्तियों के लिए, संकलक यहां निरंतर फोल्डिंग लागू करेगा, इसलिए कोड के निष्पादन के दौरान होने वाली एकमात्र चीज परिणाम लोड करना है :। ओर टिप्पणी की

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

अंत]

यह समस्या एक known defect है। पायथन डेवलपर्स ने स्रोत वितरण के directory Lib/test/crashers में पाइथन दुभाषिया को क्रैश करने के कई तरीकों को एकत्रित किया। इस मुद्दे से संबंधित एक Lib/test/crashers/compiler_recursion.py है।

+0

बस संदर्भ के लिए, यह पाइथन 3.3+ में तय किया गया प्रतीत होता है। कोड 'रिकर्सनररर' बढ़ाता है: अब संकलन के दौरान अधिकतम रिकर्सन गहराई पार हो गई है। –

संबंधित मुद्दे