2012-08-02 27 views
5

मैंने एक ऐसी स्थिति में भाग लिया है, जहां एक मिनीडम्प के अनुसार, कुछ फाइलें रिकर्सिव-डेसेंट पार्सर में स्टैक ओवरफ़्लो उत्पन्न कर रही हैं। दुर्भाग्यवश, मैं इस फाइल को एक उदाहरण के उदाहरण पर नहीं प्राप्त कर सकता हूं जो इस मुद्दे को पुन: उत्पन्न करने के लिए करता है (ग्राहक की गोपनीयता की चिंता है), जो मुझे इस पल के लिए असली समस्या का निदान करने के लिए थोड़ा सा झटका लगा देता है।मैं वर्कर थ्रेड पर स्टैक ओवरफ़्लो से कैसे रोक सकता हूं या पुनर्प्राप्त कर सकता हूं?

स्पष्ट रूप से पार्सर को कुछ ध्यान देने की ज़रूरत है, लेकिन अभी मेरी शीर्ष प्राथमिकता केवल प्रोग्राम को चलाने के लिए है। स्टॉपगैप उपाय के रूप में, मैं इसे पूरे कार्यक्रम को कम करने से रोकने के लिए क्या कर सकता हूं?

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

पार्सिंग Parallel.ForEach() लूप में हो रहा है। मैं इसे किसी अन्य दृष्टिकोण के लिए स्वैप करने के लिए तैयार हूं अगर इससे मदद मिलेगी।

संपादित करें: वास्तव में हत्यारा क्या होगा यदि मैं वर्तमान धागे के ढेर का आकार प्राप्त कर सकूं, और स्टैक पॉइंटर की स्थिति प्राप्त कर सकूं। क्या यह संभव है?

संपादित करें 2: अंततः मैं किसी से नमूना फ़ाइल लिखने और डीबगर में त्रुटि को फंसाने में कामयाब रहा। यह पता चला है कि यह कोड नहीं है जो हमारे लिए है - अपवाद कहीं भी HtmlAgilityPack में हो रहा है। तो ऐसा लगता है कि मुझे पूरी तरह से अलग करने की कोशिश करने और खोजने की ज़रूरत है।

+0

यह सुनिश्चित नहीं है कि इससे मदद मिलेगी कि स्टैक ओवरफ़्लो का क्या कारण है, स्पष्ट नहीं है (पैरालाइज़्म का कारण यह नहीं होना चाहिए: पुनर्संरचना हो सकती है), लेकिन क्या आपने समवर्ती कॉल की मात्रा को सीमित करने के लिए 'समांतर विकल्प। मैक्सडिग्री ओफपेरेलिज्म' का उपयोग करने का प्रयास किया है? – Jcl

+0

एक विकल्प सिर्फ पार्स की वर्तमान "गहराई" को ट्रैक करना है, और अगर यह बहुत अधिक हो तो जमानत है। – dlev

+0

@dlev मुझे अधिक जानकारी चाहिए, हालांकि। .NET प्रलेखन से पता चलता है कि, लेकिन मैं एक उचित अधिकतम गहराई कैसे चुनूं, यह देखते हुए कि स्टैक फ्रेम और कॉल स्टैक दोनों में अलग-अलग आकार हो सकते हैं? –

उत्तर

3

स्टैक में डेस्कटॉप सीएलआर पर डिफ़ॉल्ट रूप से 1 एमबी सीमा है, लेकिन आप can increase it पर हैं।

आप स्टैक के बजाय ढेर का उपयोग करने के लिए continuation passing style का उपयोग कर सकते हैं।

सी # 5.0 में, इस प्रक्रिया को स्वचालित करने वाले संकलक द्वारा प्रदान की गई एसिंक तंत्र है। मैंने नवीनतम निर्माण के साथ यह कोशिश नहीं की है। जैसा कि एलेक्स द्वारा उल्लेख किया गया है, सी # में पूंछ-कॉल अनुकूलन के लिए कोई समर्थन नहीं है, और यह पार्सिंग समस्याओं के लिए एफ # को अपनाने का एक बड़ा कारण हो सकता है। के रूप में this article.

में प्रदर्शन आप ग्राफ़ चक्र का पता लगाने की जरूरत है कि आपके द्वारा कार्यक्रम presence of bad inputs में ठोस बनाने के लिए यहाँ, some material on lexing and parsing with F#. YMMV है।

अधिक जानकारी एकत्र करने के तरीके के रूप में, आप एक संचयक पूर्णांक के माध्यम से सुई कर सकते हैं जो ट्रैक करता है कि आपका कॉल कितना गहरा है। यह सीधे कॉल स्टैक द्वारा खपत स्मृति में अनुवाद नहीं करेगा, लेकिन यह आपको एक सामान्य विचार देता है। उदाहरण के लिए, आप अपने स्वयं के अपवाद को फेंक और पकड़ सकते हैं जब वह संख्या कुछ उपयोगकर्ता-कॉन्फ़िगर करने योग्य या पूर्वनिर्धारित सीमा से अधिक है।

public void Recursive(int acc) 
{ 
    if (acc > myLimit) 
     throw new MyOverflowException(acc); 

    Recursive(acc+1); 
} 

और फिर कॉल-स्थल पर:

try { Recursive(0); } catch (MyOverflowException) { /* handle it*/ } 

के रूप में अनुरोध किया है, मैं तुम्हें शानदार ब्लॉग के लिए एरिक Lippert द्वारा this very topic.

+1

थोड़ा विस्तार अच्छा होगा। –

+0

@GregC यह ऐसा कुछ है जिसे मैं दीर्घकालिक समाधान के रूप में करने पर विचार कर रहा हूं। लेकिन अभी मैं एक स्टॉपगैप की तलाश में हूं, और यह एक बड़ा रिफैक्टर होगा। –

+1

मेरा मतलब है कि निरंतरता उत्तीर्ण शैली का एक उदाहरण दें, और शायद यह भी प्रदर्शित करें कि यह कम ढेर का उपयोग कैसे करता है। –

0

एक धागे पर दुर्घटनाग्रस्त SOE के कारण लिंक कर देंगे पूरी प्रक्रिया को नीचे लाएगा और इसके बारे में आप इतना कुछ नहीं कर सकते हैं।

एक पुनर्प्राप्ति उपाय के रूप में आप इसके बजाय पार्सर को एक अलग प्रक्रिया के रूप में लॉन्च कर सकते हैं और बच्चे के साथ संवाद करने के लिए आईपीसी तंत्र स्थापित कर सकते हैं। इस तरह, मुख्य प्रक्रिया को प्रभावित किए बिना बाल प्रक्रिया मरने के लिए स्वतंत्र है।

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

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