2011-01-25 11 views
7

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

मैं ज्यादातर जिज्ञासा से बाहर पूछ रहा हूँ, मैं एक मौजूदा समस्या (अभी तक) को सुलझाने की कोशिश नहीं कर रहा हूँ। धन्यवाद

+0

यह रुचि का हो सकता है: http://stackoverflow.com/questions/4747934/c-catch-a-divide-by-zero-error –

+1

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

उत्तर

5

libsigsegv विभाजन दोष से निपटने और अतिप्रवाह ढेर के लिए एक पार मंच पुस्तकालय है। हालांकि, अधिकांश मामलों में, जब आप एक सेगमेंटेशन गलती का पता लगाते हैं, तो सही काम करना है कि इसे पुनर्प्राप्त करने की कोशिश करने के बजाय निष्पादन को यथासंभव तेज़ी से समाप्त करना है। एक segfault आमतौर पर एक बग या दूषित स्मृति का संकेत है, और एक बार जब आप स्मृति दूषित हो जाते हैं, तो इससे पुनर्प्राप्त करना लगभग असंभव है।

+0

करने के लिए एक मुश्किल बात होगी हाँ, ऐसा समाधान केवल कुछ मामलों पर लागू होगा, जहां मैं गारंटी दे सकता हूं कि कार्यक्रम के पर्यावरण को अन्यथा दूषित नहीं किया गया था। –

+0

@ जॉन होलेसेक आप किसी भी परिस्थिति में ऐसी गारंटी कैसे प्रदान कर सकते हैं? –

+0

उदाहरण के लिए यदि कोई सूचक मान मान्य स्मृति स्थान पर इंगित करता है तो परीक्षण करने के लिए - ऐसी चीज किसी प्रकार के कचरा कलेक्टर के लिए उपयोगी हो सकती है। –

2

समस्या यह है कि अगर प्लगइन SEG दोष, आप गारंटी नहीं दे सकते क्या राज्य अपने मुख्य कार्यक्रम अब और में हो जाएगा। यहां तक ​​कि यदि आप एसआईजीएसईजीवी (जो मुझे विश्वास है कि आप कर सकते हैं) पकड़ सकते हैं, तो आपके पास अपने आवेदन में पुनर्प्राप्त करने का कोई अच्छा तरीका नहीं होगा।

आपको क्या करना होगा fork एड प्रक्रिया में प्लगइन चलाएं ताकि यदि यह आपके मुख्य कार्यक्रम को क्रैश करता है तो भी नीचे नहीं लिया जाता है। उदाहरण के लिए आप पाइप के साथ प्रक्रियाओं के बीच संवाद कर सकते हैं।

+0

प्लगइन के साथ उदाहरण सिर्फ एक विचार था जहां इसका उपयोग किया जा सकता था। इस तरह की एक प्लगइन को या तो उप-प्रक्रिया के रूप में चलाने की आवश्यकता होगी, जैसा कि आपने सुझाव दिया था या इसे नियमों के सख्त सेट का पालन करना होगा, जैसा कि हो सकता है, या ऐसा नहीं हो सकता है (लेकिन फिर से, मैं लागू करने में सक्षम नहीं होगा इस)। हालांकि अगर मुझे कुछ स्मृति को पढ़ने/लिखने की आवश्यकता है, तो मुझे segfault के मामले में ठीक होने में सक्षम होना चाहिए। –

+0

हां, यह आमतौर पर –

1

नहीं, कोई मानक तरीका नहीं है। सी ++ में, ऐसे "सीपीयू अपवाद" अपरिभाषित व्यवहार के अभिव्यक्ति हैं, यानी सी ++ मानक उनके व्यवहार, या बाद में होने वाली किसी भी चीज़ के बारे में कुछ भी निर्दिष्ट नहीं करता है। यहां तक ​​कि "सीजीएफॉल्ट" की धारणा मानक सी ++ में मौजूद नहीं है। एक पूर्ण सूचक को अस्वीकार करने से आपके कंप्यूटर को आग लग सकती है, और स्पष्ट रूप से उस बिंदु को पकड़ने के लिए थोड़ा बायां है।

सी यह या तो समाधान नहीं: SIGSEGV एक मानक सी संकेत नहीं है; यह एक पॉज़िक्स एक्सटेंशन है। उदाहरण के लिए, विंडोज में SIGSEGV नहीं है।

2

यह मानक सी ++ में शामिल नहीं है, हालांकि आम डेस्कटॉप ओएस इसे करने के लिए सुविधाएं प्रदान करते हैं। विंडोज़ में संरचित अपवाद हैंडलिंग (एसईएच) है जिसके लिए प्रासंगिक कंपाइलर एक्सटेंशन उपलब्ध हैं, और पीओएसईक्स सिग्नल हैंडलिंग प्रदान करता है।

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

आप उसी दृष्टिकोण का उपयोग नहीं कर सकते- यहां तक ​​कि असेंबलर में भी। इन सुविधाओं को ओएस द्वारा प्रदान किया जाता है- जब सीपीयू एक अपवाद उठाता है, तो यह तय करने के लिए ओएस पर जाता है कि इसके बारे में क्या करना है, उपयोगकर्ता-मोड नहीं। इतना ही नहीं, लेकिन मैं कहूंगा कि कोड में उपयोग करते समय एसईएच और सिग्नल हैंडलिंग मौलिक रूप से अलग-अलग दृष्टिकोणों की गारंटी देने के लिए काफी अलग हैं, इसलिए एक साधारण #ifdef इसे काट नहीं देगा।

setjmp और longjmp केवल उपयोगकर्ता-मोड कोड द्वारा उठाए गए "सिग्नल" के लिए काम कर सकते हैं, ओएस-स्तर नहीं।

2

मुझे नहीं लगता कि एक असली क्रॉस प्लेटफ़ॉर्म समाधान मौजूद है।

विंडोज़ के तहत आप सी ++ अपवादों के लिए एसईएच अपवादों का अनुवाद करने के लिए _set_se_translator का उपयोग कर सकते हैं।

कैसे लिनक्स के तहत भी ऐसा ही करने पर निम्न आलेख C++ exception-handling tricks for Linux देखें

0

सिग्नल संचालकों कुछ बात करने के लिए प्रोग्राम निष्पादन अप ठीक कर सकते हैं; वास्तव में अनुमति है सिग्नल (7) मैनुअल पेज में दस्तावेज किया गया है।

कार्यान्वयन गलती निम्नलिखित कि

    • SIGSEGV संचालकों से दोषयुक्त अनुदेश (यह आप स्मृति नक्शा बदल सकते हैं और वापस जाने के लिए अनुमति देता है) के लिए वापसी, और शिक्षा के लिए जाना जाएगा रहे हैं SIGFPE के लिए है कि इस कार्यान्वयन है

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