2013-02-06 67 views
17

अपवाद ऑपरेटिंग सिस्टम के परिप्रेक्ष्य से कैसे काम करते हैं?अपवाद फेंकने के लिए किसकी जिम्मेदारी है ?; ओएस या प्रक्रिया?

सी ++ से आ रहा है, मैं प्रोग्रामर के परिप्रेक्ष्य से अपवादों को समझ सकता हूं।
जब कोई अपवाद फेंक दिया जाता है, तो ढेर खोलने लगते हैं, और प्रत्येक सक्रियण रिकॉर्ड में अपवाद को पकड़ने और संभालने का अवसर होता है।

लेकिन पहली जिम्मेदारी को अपवाद फेंकने की किसकी ज़िम्मेदारी थी?

  1. यह ऑपरेटिंग सिस्टम है कि इस प्रक्रिया करने के लिए एक ट्रिगर भेजता है यह दर्ज करने के लिए यह कह रही है "अपवाद हैंडलिंग राज्य?"
  2. प्रक्रिया है जो अपने स्वयं के प्रोग्राम स्पेस में अपवादों को संभालने और संभालने की प्रक्रिया है, ओएस के लिए अप्रतिबंधित है?

यहां दो दुर्घटनाग्रस्त कार्यक्रम हैं जो मेरी अनिश्चितता को दर्शाते हैं।

int main(){ 

    int i = 1/0; //did the OS tell the process to end? 

    return 0; 
} 

#include <exception> 

int main(){ 

    throw 11; //did the process tell the OS it needs to end? 

    return 0; 
} 
+1

त्वरित उत्तर: सी ++ अपवाद पूरी तरह से संचालित प्रक्रिया है। लेकिन मेरे पास जवाब पर आगे जाने के लिए पर्याप्त ज्ञान नहीं है कि वास्तव में अपवाद कैसे काम करते हैं। संपादित करें: आपके पहले मामले में प्रक्रिया को एक सिग्नल प्राप्त होता है जिसे C++ अपवाद –

+0

में परिवर्तित किया जा सकता है आपके उदाहरणों में से कोई भी क्रैश नहीं होता –

+1

@ BЈовић मुझे लगता है कि क्रैश द्वारा, एक्सप्लोइट का अर्थ गैर-0 त्रुटि कोड से बाहर निकलना है। –

उत्तर

12

सी ++ अपवाद भाषा मानक द्वारा परिभाषित भाषा का हिस्सा हैं, और संकलक और रनटाइम लाइब्रेरी द्वारा कार्यान्वित किया गया है। सीपीयू द्वारा अन्य exceptions का पता लगाया गया है, जैसे कि शून्य से विभाजित या एक नल पॉइंटर को डिफ्रेंस करना, दोनों भाषा मानक में Undefined Behavior के उदाहरण हैं। प्रोसेसर शब्दावली में faults और x86 पर उदाहरण के लिए fault handler ट्रिगर करें जिसे ओएस द्वारा सर्विस किया जाता है। ओएस तब उस प्रक्रिया को उस गलती की रिपोर्ट करने का विकल्प चुन सकता है जिसके कारण यह हुआ, यूनिक्स पर यह signals के साथ किया गया है। यदि आपकी प्रक्रिया signal handlerSIGSEGV के लिए स्थापित की गई है, उदाहरण के लिए, यह प्रक्रिया द्वारा परिभाषित सी ++ अपवादों से अलग है, तो यह CPU द्वारा उत्पन्न गलती को संभाल सकता है ... यह तंत्र भाषा द्वारा परिभाषित सी ++ अपवादों से अलग है।

आपके उदाहरण में, जब एक सी ++ प्रोग्राम throws एक अपवाद यह पूरी तरह से संकलक उत्पन्न कोड और भाषा रनटाइम लाइब्रेरी द्वारा संभाला जाता है, तो कोई कर्नेल कॉल आवश्यक नहीं होता है और प्रोसेसर द्वारा उत्पन्न कोई हार्डवेयर गलती नहीं होती है।

+0

इस उत्तर के लिए एक और अतिरिक्त मानक प्रोग्राम/भाषा अपवादों के [एलएलवीएम कार्यान्वयन] (http://llvm.org/docs/ExceptionHandling.html) होगा। सार पर्याप्त और अच्छी तरह से स्वरूपित। –

8

आप पूरी तरह से अलग अपवाद प्रक्रियाओं के बारे में दो बात कर रहे हैं।

पहला ओएस द्वारा प्रदान किया जाता है। विंडोज़ में आप उन्हें संभालने के लिए __try and __except का उपयोग कर सकते हैं।

दूसरा सी ++ कंपाइलर द्वारा प्रदान किया जाता है और इसमें किसी भी तरह से ओएस शामिल नहीं होता है।

+4

+1 मैं यह भी जोड़ूंगा कि सी ++ अपवादों में प्लेटफ़ॉर्म-विशिष्ट कार्यान्वयन है और आमतौर पर ओएस द्वारा प्रदान की जाने वाली सुविधाओं के आधार पर। – lapk

+0

@ लैप की टिप्पणी सीधे जवाब का खंडन करती है: "आधारित"! = "किसी भी तरह से शामिल नहीं है"। कुछ स्पष्टीकरण अच्छा होगा। –

+0

@FelixDombek मेरा मतलब था कि सी ++ विनिर्देश बताता है कि कैसे ओ + से स्वतंत्र सी ++ अपवाद संचालित होते हैं। यदि एक कंपाइलर कुछ ओएस सुविधाओं का उपयोग करना चुनता है तो ऐसा करने के लिए स्वतंत्र है, लेकिन यह एक कार्यान्वयन विस्तार है - आप इस पर भरोसा नहीं कर सकते हैं। –

6

चूंकि मुझे केवल एक या दो ओएस के सी ++ में लिखा गया है, और जिसे मैं बेहतर जानता हूं, आधिकारिक तौर पर अपवादों का उपयोग नहीं करता है, ओएस द्वारा अपवादों को छोड़कर बहुत अधिक नियम हैं।

यूनिक्स (एईक्स, सोलारिस, एचपी-यूएक्स, इत्यादि) के सभी रूपों के साथ तीन मुख्य ओएस (लिनक्स, विंडोज़, मैकोज़ एक्स), सी में लिखे गए हैं, साथ ही लगभग किसी अन्य व्यावसायिक रूप से उपलब्ध ओएस के साथ ' टी असेंबलर में लिखा नहीं है, इसलिए सी ++ प्रकार अपवादों को फेंक नहीं सकता है [यह नहीं कह रहा है कि सॉफ़्टवेयर संचालित अपवाद नहीं हैं, सिर्फ वे बिना किसी प्रकार के अनुवाद के सी ++ में "कोशिश/पकड़" के साथ प्राप्त एक्सेप्शन का प्रकार नहीं हैं] ।

पहले उदाहरण में, ओएस निश्चित रूप से शामिल है [सभी ओएस में जो मुझे पता है कि वे कैसे काम करते हैं], क्योंकि शून्य से विभाजन सभी मशीनों पर एक हार्डवेयर अपवाद का कारण बनता है जिसमें एक समारोह के रूप में विभाजन होता है, और इस प्रकार ओएस की आवश्यकता होगी शामिल होना। साथ ही, यह संकलित और असफल हो जाएगा जैसा कि यह सी ++ है, सी या आप एक ही चीज़ को असेंबलर में लिखते हैं। अधिकांश ऑपरेटिंग सिस्टम के लिए, वे प्रोग्राम को सिग्नल भेज देंगे, लेकिन चूंकि आपके पास सिग्नल को संभालने के लिए कोई कोड नहीं है, इसलिए आपका कोड शायद ओएस को बताएगा कि कुछ अजीब हुआ और यह छोड़ रहा है, यहां तक ​​कि परेशान करने के लिए भी परेशान नहीं है ढेर।

दूसरे मामले में, ओएस सभी शामिल नहीं है। कॉल के आस-पास एक "कोशिश-पकड़" ब्लॉक है, जो कहता है "ओह, किसी ने कुछ ऐसा फेंक दिया जो पकड़ा नहीं गया था, बाहर निकलने देता है"। ओएस में शामिल होने का एकमात्र हिस्सा "इस प्रक्रिया से बाहर निकलना" है, जो निश्चित रूप से ओएस द्वारा किया जाना चाहिए, हालांकि मुझे अधिकांश ओएस में विश्वास है, बस 'एप्लिकेशन के प्रारंभ पते' से वापस लौटना होगा एक ही प्रभाव है।