क्या पायथन विभाजन की गलती का कारण बनता है?


85

मैं पायथन में कोसाराजू के मजबूत कनेक्टेड घटक (एससीसी) ग्राफ खोज एल्गोरिदम को लागू कर रहा हूं।

कार्यक्रम छोटे डेटा सेट पर बहुत अच्छा चलता है, लेकिन जब मैं इसे सुपर-लार्ज ग्राफ (800,000 से अधिक नोड्स) पर चलाता हूं, तो यह "सेगमेंटेशन फॉल्ट" कहता है।

इसका कारण क्या हो सकता है? धन्यवाद!


अतिरिक्त जानकारी: पहले मुझे यह त्रुटि सुपर-बड़े डेटा सेट पर चलने पर मिली:

"RuntimeError: maximum recursion depth exceeded in cmp"

तब मैं पुनरावृत्ति सीमा का उपयोग करके रीसेट करता हूं

sys.setrecursionlimit(50000)

लेकिन एक 'विभाजन दोष' मिला

मेरा विश्वास करो कि यह एक अनंत लूप नहीं है, यह अपेक्षाकृत छोटे डेटा पर सही चलता है। यह संभव है कि कार्यक्रम संसाधनों को समाप्त कर दे?


10
हो सकता है कि आप एक नज़र क्रेशपायथन
अभिजीत

2
क्या यह शुद्ध पायथन में चल रहा है या आप C एक्सटेंशन मॉड्यूल का उपयोग कर रहे हैं? यदि यह शुद्ध अजगर है तो यह एक बग है और बधाई हो। यदि आप एसी मॉड्यूल का उपयोग कर रहे हैं, तो सेगफॉल्ट संभवतः वहां से आ रहा है।
अपरोनस्टरलिंग

यह शुद्ध अजगर है। कार्यक्रम अपेक्षाकृत छोटे डेटा सेट पर बहुत अच्छा चलता है और इससे मुझे लगता है कि कोड सही है।
xiaolong

पायथन प्रलेखन के अनुसार:
जेम्स थिएले

2
पायथन प्रलेखन के अनुसार :::::: उच्चतम संभव सीमा प्लेटफ़ॉर्म-निर्भर है। एक उपयोगकर्ता को उच्च सीमा निर्धारित करने की आवश्यकता हो सकती है जब उसके पास एक कार्यक्रम है जिसमें गहरी पुनरावृत्ति की आवश्यकता होती है और एक मंच जो एक उच्च सीमा का समर्थन करता है। यह देखभाल के साथ किया जाना चाहिए, क्योंकि बहुत अधिक सीमा दुर्घटना का कारण बन सकती है। :::::: आपने एक OS निर्दिष्ट नहीं किया। क्रैश का संदर्भ आपके ओएस पर सेगमेंट की गलती का मतलब हो सकता है । एक छोटे स्टैक का प्रयास करें। लेकिन IIRC आप जिस एल्गोरिथ्म का उपयोग कर रहे हैं वह रंटियर SSC को स्टैक पर रखता है ताकि आप स्टैक से बाहर निकल सकें।
जेम्स थीले

जवाबों:


80

यह तब होता है जब एक अजगर विस्तार (सी में लिखा) पहुंच से परे एक स्मृति तक पहुंचने की कोशिश करता है।

आप इसे निम्नलिखित तरीकों से ट्रेस कर सकते हैं।

  • sys.settraceकोड की पहली पंक्ति में जोड़ें ।
  • मार्कgdb द्वारा वर्णित के रूप में इस उत्तर में उपयोग करें .. कमांड प्रॉम्प्ट पर

    gdb python
    (gdb) run /path/to/script.py
    ## wait for segfault ##
    (gdb) backtrace
    ## stack trace of the c code
    

2
धन्यवाद, लेकिन मेरा कोड शुद्ध अजगर है, क्या इससे कोई फर्क पड़ता है?
xiaolong

जाँच करें कि आप किस अजगर मॉड्यूल का उपयोग कर रहे हैं? कुछ मॉड्यूल अजगर में लिखे गए हैं और अन्य सी में हैं। मुझे लगता है कि आपको बग की रिपोर्ट करने की आवश्यकता है।
शिप्लू मोकादिम

1
इसी तरह, सहायक भी: stdlib के ट्रेस मॉड्यूल ने मुझे एक स्टेजिंग सर्वर पर एक विभाजन दोष की तह तक पहुंचने में मदद की, एक नई निर्भरता स्थापित किए बिना, और कोड को संशोधित किए बिना।
ड्रफ्टकैचर

4
OSX सिएरा पर, gdb को lldb
kthouz


54

मैं समझता हूं कि आपने अपना मुद्दा हल कर लिया है, लेकिन इस धागे को पढ़ने वाले अन्य लोगों के लिए, यहां जवाब है: आपको उस स्टैक को बढ़ाना होगा जो आपके ऑपरेटिंग सिस्टम को अजगर प्रक्रिया के लिए आवंटित करता है।

इसे करने का तरीका, ऑपरेटिंग सिस्टम पर निर्भर है। लिनक्स में, आप कमांड को ulimit -sअपने वर्तमान मूल्य के साथ जांच सकते हैं और इसके साथ बढ़ा सकते हैंulimit -s <new_value>

पिछले मूल्य को दोगुना करने की कोशिश करें और जब तक यह काम न करे, तब तक दोगुना जारी रखें, जब तक कि आप ऐसा न कर लें या स्मृति से बाहर न चला जाए।


यह भी जांचने का एक अच्छा तरीका है कि क्या आप एक एलिमिट मैक्स के खिलाफ आ रहे हैं, दौड़ना lsofऔर उपयोग करना grepया wc -lहर चीज का ट्रैक रखना है।
17

मैं सहमत हूँ। यह वास्तव में मेरे कोसाराजू के SCC कार्यान्वयन के लिए काम करता है, जो पायथन और C ++ कार्यान्वयन दोनों पर सेगफॉल्ट को ठीक करके। : <br/> मेरी मैक के लिए, मैं बाहर अधिकतम संभव के माध्यम से पाया
रॉक

4
ध्यान दें कि ulimit मूल्य केवल उस विशेष शेल के लिए संशोधित किया गया है जिसमें इसे निष्पादित किया गया है, ताकि आप गलती से अपने पूरे सिस्टम के लिए मान को संशोधित न करें
तन्मय गर्ग

1
मैंने ऐसा किया और 16384-के साथ समाप्त हो गया, हालांकि दौड़ने के बाद भी मुझे एक विभाजन त्रुटि मिली।
श्रीहरी आर

@ श्रीहरि ने इसे और भी बढ़ाने की कोशिश की। हालांकि यह एक अजगर विस्तार के साथ एक मुद्दा भी हो सकता है (यदि आप कोई उपयोग कर रहे हैं), जो (यह अन्य उत्तर) [ stackoverflow.com/a/10035594/25891] सुझाव देता है कि डीबग कैसे करें
Davide

18

खंडन दोष एक सामान्य है, इसके कई संभावित कारण हैं:

  • कम स्मृति
  • दोषपूर्ण राम स्मृति
  • एक क्वेरी का उपयोग करते हुए db से एक बड़ा डेटा सेट प्राप्त करना (यदि प्राप्त डेटा का आकार स्वैप मेम से अधिक है)
  • गलत क्वेरी / छोटी गाड़ी कोड
  • लंबा लूप होना (एकाधिक पुनरावृत्ति)

3

Ulimit को अद्यतन करना मेरे कोसाराजू के SCC कार्यान्वयन के लिए काम कर रहा है, जो Python (Python segfault .. जो जानता था!) ​​और C ++ कार्यान्वयन दोनों पर सेगफ़ॉल्ट को ठीक करके।

मेरे मैक के लिए, मुझे इसके माध्यम से अधिकतम संभव पता चला:

$ ulimit -s -H
65532

उस मूल्य को कैसे अपडेट किया जाए? वह मान किस प्रकार की इकाई में है?
पाब्लो

यदि आप इस बारे में बहुत कुछ जानते हैं कि आपको अपनी सीमाओं की आवश्यकता क्या है (और आप जानते हैं कि आपका प्लेटफ़ॉर्म लिनक्स से कभी भी दूर नहीं होगा), तो आप अपने कोड के भीतर से केवल उस कमांड को निष्पादित करने के लिए एक अजगर निष्पादित कमांड का उपयोग कर सकते हैं। मैंने व्यक्तिगत रूप से इसे अपनी .bashrc फ़ाइल में जोड़ा है।
ट्रम्पेटलिक्स

2

Google खोज ने मुझे यह लेख मिला, और मैंने निम्नलिखित "व्यक्तिगत समाधान" पर चर्चा नहीं की।


लिनक्स के लिए विंडोज सबसिस्टम पर पायथन 3.7 के साथ मेरी हाल की झुंझलाहट यह है कि: एक ही पंडास लाइब्रेरी के साथ दो मशीनों पर, एक मुझे segmentation faultऔर दूसरी रिपोर्ट को चेतावनी देती है। यह स्पष्ट नहीं था कि कौन सा नया था, लेकिन "फिर से स्थापित" pandasसमस्या को हल करता है।

आज्ञा है कि मैं छोटी गाड़ी मशीन पर चला।

conda install pandas

अधिक विवरण: मैं समान स्क्रिप्ट चला रहा था (Git के माध्यम से समन्वयित), और दोनों WSL + एनाकोंडा के साथ विंडोज 10 मशीन हैं। केस बनाने के लिए यहां स्क्रीनशॉट पर जाएं। इसके अलावा, मशीन पर जहां कमांड-लाइन के pythonबारे में शिकायत होगी Segmentation fault (core dumped), जुपाइटर लैब बस कर्नेल को हर बार पुनः आरंभ करता है। इससे भी बदतर, अभी तक कोई चेतावनी नहीं दी गई थी।

यहां छवि विवरण दर्ज करें


कुछ महीनों बाद अपडेट: मैंने विंडोज मशीन पर जुपिटर सर्वर की मेजबानी छोड़ दी। अब मैं एक लिनक्स सर्वर पर खोले गए दूरस्थ बंदरगाहों को लाने के लिए और दूरस्थ लिनक्स मशीन पर अपने सभी काम चलाने के लिए विंडोज पर डब्ल्यूएसएल का उपयोग करता हूं। मैंने कभी भी महीनों की अच्छी संख्या के लिए किसी भी निष्पादन त्रुटि का अनुभव नहीं किया है :)


0

RPI पर dlib को अपग्रेड करने के बाद मैं इस विभाजन दोष का सामना कर रहा था। मैंने ढेर को ट्रेसबैक किया जैसा कि ऊपर शिप्पू मोकादिम द्वारा सुझाया गया है और यह एक ओपनबीएलएएस लाइब्रेरी पर बसा है।

चूंकि OpenBLAS भी बहु-थ्रेडेड है, इसलिए इसे मुल्ट-थ्रेडेड एप्लिकेशन में उपयोग करने से विभाजन की गलती तक तेजी से गुणा हो जाएगा। बहु-थ्रेडेड अनुप्रयोगों के लिए, OpenBlas को एकल थ्रेड मोड पर सेट करें।

अजगर आभासी वातावरण में, OpenBLAS को केवल संपादन द्वारा एक सूत्र का उपयोग करने के लिए कहें:

    $ workon <myenv>
    $ nano .virtualenv/<myenv>/bin/postactivate

और जोड़:

    export OPENBLAS_NUM_THREADS=1 
    export OPENBLAS_MAIN_FREE=1

रिबूट के बाद मैं अपने सभी इमेज रिकॉग्निशन एप्स को rpi3b पर चलाने में सक्षम था जो पहले इसे क्रैश कर रहे थे।

संदर्भ: https://github.com/ageitgey/face_recognition/issues/294


-1

लगता है कि आप स्टैक मेमोरी से बाहर हैं। आप इसे बढ़ाना चाह सकते हैं जैसा कि डेविड ने कहा था। अजगर कोड में करने के लिए, आपको थ्रेडिंग का उपयोग करके अपना "मुख्य ()" चलाना होगा:

def main():
    pass # write your code here

sys.setrecursionlimit(2097152)    # adjust numbers
threading.stack_size(134217728)   # for your needs

main_thread = threading.Thread(target=main)
main_thread.start()
main_thread.join()

स्रोत: codeforces पर c1729 पद । PyPy के साथ यह Runing एक सा है जटिल

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.