2010-07-22 20 views
26

क्या कोई ऐसा है जो मैं AccessViolationException पकड़ने के लिए कर सकता हूं? इसे एक अप्रबंधित डीएलएल द्वारा फेंक दिया जा रहा है जिसे मैं नियंत्रित नहीं करता हूं।क्या .NET में एक्सेस उल्लंघन अपवाद को पकड़ना संभव है?

उत्तर

26

आपको नहीं करना चाहिए। एक प्रवेश उल्लंघन एक गंभीर समस्या है: यह एक अमान्य स्मृति पता (या पढ़ने के लिए) लिखने का एक अप्रत्याशित प्रयास है। चूंकि जॉन ने पहले से ही स्पष्ट किया है, अप्रबंधित डीएलएल पहले से ही उल्लंघन उल्लंघन के पहले प्रक्रिया स्मृति को दूषित कर सकता है। वर्तमान प्रक्रिया के किसी भी हिस्से पर इसका अप्रत्याशित प्रभाव हो सकता है।

सबसे सुरक्षित बात यह है कि संभवतः उपयोगकर्ता को सूचित करें और फिर तुरंत बाहर निकलें।

कुछ और विवरण: एक एक्सेस उल्लंघन एक ओएस अपवाद है (एक तथाकथित एसईएच या संरचित अपवाद हैंडलिंग अपवाद)। System.Exception से प्रबंधित सीएलआर अपवादों की तुलना में यह एक अलग तरह का अपवाद है। आप शायद ही कभी प्रबंधित कोड में SEH अपवाद देखेंगे, लेकिन यदि कोई होता है, उदा। अप्रबंधित कोड में, सीएलआर इसे प्रबंधित कोड पर पहुंचाएगा जहां आप इसे पकड़ने में भी सक्षम हैं।

हालांकि, एसईएच अपवादों को पकड़ना ज्यादातर एक अच्छा विचार नहीं है। अधिक जानकारी MSDN पत्रिका में लेख Handling Corrupted State Exceptions जहां निम्न पाठ यह से लिया से वर्णन किया गया:

CLR हमेशा कार्यक्रम में ही द्वारा उठाए गए अपवाद के रूप में एक ही प्रक्रियाओं का उपयोग करके प्रबंधित कोड के SEH अपवाद जन्म दिया है। यह तब तक कोई समस्या नहीं है जब तक कोड असाधारण स्थितियों को संभालने का प्रयास नहीं करता है, जिसे उचित रूप से संभाल नहीं सकता है। अधिकांश उल्लंघन एक्सेस उल्लंघन के बाद निष्पादन को सुरक्षित रूप से जारी नहीं रख सकते हैं। दुर्भाग्यवश, सीएलआर के अपवाद हैंडलिंग मॉडल ने हमेशा उपयोगकर्ताओं को सिस्टम के शीर्ष पर किसी अपवाद को पकड़ने की अनुमति देकर इन गंभीर त्रुटियों को पकड़ने के लिए प्रोत्साहित किया है। अपवाद पदानुक्रम। लेकिन यह शायद ही कभी सही काम है।

यह .NET 3.5 जब तक सच था। .NET 4 में व्यवहार बदल दिया गया है। यदि आप अभी भी इस तरह के अपवादों को पकड़ने में सक्षम होना चाहते हैं तो आपको app.config में legacyCorruptedState­­ExceptionsPolicy=true जोड़ना होगा। उपरोक्त लिखित कला में और विवरण।

+4

स्पष्टीकरण के लिए: आप ASAP से बाहर निकलने का कारण यह है कि आप यह नहीं जानते कि अप्रबंधित डीएलएल ने एक्सेस उल्लंघन को हिट करने से पहले ओवरराइट किया था। हो सकता है कि यह पर्याप्त स्थानों पर कचरा लिख ​​रहा हो कि आपका प्रोग्राम सुरक्षित रूप से जारी नहीं हो सकता है। –

+0

@ जॉन सॉंडर्स: स्पष्टीकरण के लिए धन्यवाद। मैंने अपना जवाब अपडेट किया। –

+4

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

0

आप कॉल-कैच ब्लॉक के साथ अप्रबंधित डीएलएल को कॉल लपेट सकते हैं। AccessViolationExceptions सामान्य रूप से पकड़ा जा सकता है। दोनों संदेशों निम्न कोड दिखाता निष्पादित:

try 
{ 
    throw new AccessViolationException(); 
} 
catch (Exception e) 
{ 
    MessageBox.Show(e.Message + e.StackTrace, e.Message, MessageBoxButtons.OK, MessageBoxIcons.Error); 
} 
MessageBox.Show("Still running.."); 

संपादित करें: .NET 4 की शुरुआत की एक change in behavior, यह अब संभव नहीं भ्रष्ट अपवादों को पकड़ने के लिए जब तक आप विशेष रूप से "ask" क्रम ऐसा करने के लिए है।

+0

सवाल यह है कि, यह एक अच्छा विचार ऐसा करने के लिए है:

आप System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptions विशेषता के साथ अपने प्रबंधित विधि चिह्नित कर सकते हैं? उपयोगकर्ता को एक अच्छा और मैत्रीपूर्ण संदेश प्रदर्शित करना और लॉग लिखना समझदार हो सकता है। लेकिन उससे आगे काम करना एक अच्छा विचार नहीं है ... – rioki

+0

शायद नहीं, कम से कम नहीं, अगर आप बिल्कुल सकारात्मक नहीं हैं कि कुछ भी बुरा नहीं हुआ। – andyp

+2

यह काम नहीं करता है। मैंने अपवाद और AccessViolationException दोनों को पकड़ने की कोशिश की है, लेकिन यह मेरे पकड़ ब्लॉक को अनदेखा करता है। मुझे लगता है कि मुझे कुछ app.config झंडा चाहिए जो मुझे चाहिए। –

1

सबसे पहले मैं 0xA3 के साथ पूरी तरह से एक। लेकिन अगर कोई रास्ता नहीं है तो आप गंदे अप्रबंधित डीएल को अपनी प्रक्रिया में लपेट सकते हैं और आईपीसी (टीसीपी/आईपी, नामपतियों, आदि) के माध्यम से डेटा स्थानांतरित कर सकते हैं। सभी अपवादों को पकड़ें और मेजबान प्रक्रिया को सूचित करें। तो आपकी मेजबान प्रक्रिया ज्यादातर स्मृति भ्रष्टाचार से बचाती है।

6

हां।

आपकी ऐप में।confg, <configuration> टैग में निम्न कोड खटखटाने:

<runtime> 
    <legacyCorruptedStateExceptionsPolicy enabled="true"/> 
</runtime> 

अब आप किसी भी अन्य की तरह भ्रष्ट अपवादों (सीएसई) को पकड़ने के लिए सक्षम होना चाहिए।

नोट: यदि आप पहले से ही एक क्रम टैग है तो फिर बस <legacyCorruptedStateExceptionsPolicy enabled="true"/> इसे करने के लिए

ऊपर काम करता है नेट 4.5

+1

वें। मैंने इस मुद्दे के कुछ जवाब पढ़े। सभी कहते हैं "जोड़ें" '' app.config' 'पर क्लिक करें, लेकिन कोई भी नहीं कहा कि डिफ़ॉल्ट' 'खंड में नहीं होना चाहिए। ' 'अनुभाग के साथ संकेत के लिए धन्यवाद – user1234

2

के रूप में अन्य लोगों ने बताया, तुम नहीं "संभाल" चाहिए इस हालत के लिए, जोड़ने लेकिन विकास के दौरान समस्या निवारण के लिए इसे पकड़ना आसान है।

[HandleProcessCorruptedStateExceptions] 
public void MyMethod() 
{ 
    try 
    { 
     NaughtyCall(); 
    } 
    catch (AccessViolationException e) 
    { 
     // You should really terminate your application here 
    } 
} 
संबंधित मुद्दे