विभाजन दोष (सेगमेंटेशन फॉल्ट): Difference between revisions
m (Abhishek moved page विखंडन दोष to विभाजन दोष (सेगमेंटेशन फॉल्ट) without leaving a redirect) |
No edit summary |
||
Line 1: | Line 1: | ||
{{short description|Computer fault caused by access to restricted memory}} | {{short description|Computer fault caused by access to restricted memory}} | ||
{{redirect| | {{redirect| | ||
सेगफॉल्ट| | |||
[[ कम्प्यूटिंग ]] में, | वेबसाइट|सेगफॉल्ट (वेबसाइट)}} | ||
[[ कम्प्यूटिंग ]]में, विभाजन दोष या एक्सेस उल्लंघन [[दोष (कंप्यूटिंग)]], या विफलता की स्थिति है, जो मेमोरी सुरक्षा के साथ हार्डवेयर द्वारा उठाया जाता है, [[ऑपरेटिंग सिस्टम]] (OS) को सूचित करता है, सॉफ्टवेयर ने प्रतिबंधित क्षेत्र तक पहुंचने का प्रयास किया है। मेमोरी (एक मेमोरी एक्सेस उल्लंघन)। मानक x[[86]] कंप्यूटरों पर, यह सामान्य सुरक्षा दोष का एक रूप है। [[ऑपरेटिंग सिस्टम कर्नेल]], प्रतिक्रिया में, आमतौर पर कुछ सुधारात्मक कार्रवाई करता है, आम तौर पर प्रक्रिया को [[ संकेत (कंप्यूटिंग) ]] भेजकर गलती को आपत्तिजनक [[प्रक्रिया (कंप्यूटिंग)]] पर भेज देता है। प्रक्रियाएं कुछ मामलों में एक कस्टम सिग्नल हैंडलर स्थापित कर सकती हैं, जिससे उन्हें अपने आप ठीक होने की अनुमति मिलती है,<ref name="Peter Van der Linden">''Expert C programming: deep C secrets'' By Peter Van der Linden, page 188</ref> लेकिन अन्यथा ओएस डिफ़ॉल्ट सिग्नल हैंडलर का उपयोग किया जाता है, आम तौर पर प्रक्रिया की [[असामान्य समाप्ति]] (एक प्रोग्राम [[क्रैश (कंप्यूटिंग)]]), और कभी-कभी एक [[कोर निपात]] होता है। | |||
सेगमेंटेशन दोष [[सी (प्रोग्रामिंग भाषा)]] जैसी भाषाओं में लिखे गए प्रोग्रामों में त्रुटि का एक सामान्य वर्ग है जो निम्न-स्तरीय मेमोरी एक्सेस प्रदान करता है और कुछ से लेकर कोई सुरक्षा जांच नहीं करता है। वे मुख्य रूप से [[ आभासी मेमोरी ]] एड्रेसिंग के लिए पॉइंटर (कंप्यूटर प्रोग्रामिंग) के उपयोग में त्रुटियों के कारण उत्पन्न होते हैं, विशेष रूप से अवैध पहुंच के कारण। एक अन्य प्रकार की मेमोरी एक्सेस त्रुटि एक [[बस त्रुटि]] है, जिसके विभिन्न कारण भी हैं, लेकिन आज यह बहुत दुर्लभ है; ये मुख्य रूप से गलत भौतिक मेमोरी एड्रेसिंग के कारण होते हैं, या गलत तरीके से मेमोरी एक्सेस के कारण होते हैं - ये ऐसे मेमोरी रेफरेंस होते हैं जिन्हें हार्डवेयर एड्रेस नहीं कर सकता है, बजाय उन रेफरेंस के जिन्हें एड्रेस करने की अनुमति नहीं है। | सेगमेंटेशन दोष [[सी (प्रोग्रामिंग भाषा)]] जैसी भाषाओं में लिखे गए प्रोग्रामों में त्रुटि का एक सामान्य वर्ग है जो निम्न-स्तरीय मेमोरी एक्सेस प्रदान करता है और कुछ से लेकर कोई सुरक्षा जांच नहीं करता है। वे मुख्य रूप से [[ आभासी मेमोरी ]] एड्रेसिंग के लिए पॉइंटर (कंप्यूटर प्रोग्रामिंग) के उपयोग में त्रुटियों के कारण उत्पन्न होते हैं, विशेष रूप से अवैध पहुंच के कारण। एक अन्य प्रकार की मेमोरी एक्सेस त्रुटि एक [[बस त्रुटि]] है, जिसके विभिन्न कारण भी हैं, लेकिन आज यह बहुत दुर्लभ है; ये मुख्य रूप से गलत भौतिक मेमोरी एड्रेसिंग के कारण होते हैं, या गलत तरीके से मेमोरी एक्सेस के कारण होते हैं - ये ऐसे मेमोरी रेफरेंस होते हैं जिन्हें हार्डवेयर एड्रेस नहीं कर सकता है, बजाय उन रेफरेंस के जिन्हें एड्रेस करने की अनुमति नहीं है। | ||
Line 29: | Line 31: | ||
* स्मृति तक पहुँचने का प्रयास कार्यक्रम के पास अधिकार नहीं है (जैसे कि प्रक्रिया के संदर्भ में कर्नेल संरचनाएँ) | * स्मृति तक पहुँचने का प्रयास कार्यक्रम के पास अधिकार नहीं है (जैसे कि प्रक्रिया के संदर्भ में कर्नेल संरचनाएँ) | ||
* रीड-ओनली मेमोरी (जैसे कोड सेगमेंट) लिखने का प्रयास | * रीड-ओनली मेमोरी (जैसे कोड सेगमेंट) लिखने का प्रयास | ||
ये बदले में | ये बदले में प्रायः प्रोग्रामिंग त्रुटियों के कारण होते हैं, जिसके परिणामस्वरूप अमान्य मेमोरी एक्सेस होती है: | ||
* एक अशक्त सूचक को संदर्भित करना, जो आमतौर पर एक ऐसे पते की ओर इशारा करता है जो प्रक्रिया के पता स्थान का हिस्सा नहीं है | * एक अशक्त सूचक को संदर्भित करना, जो आमतौर पर एक ऐसे पते की ओर इशारा करता है जो प्रक्रिया के पता स्थान का हिस्सा नहीं है | ||
* एक गैर-प्रारंभिक सूचक ([[जंगली सूचक]], जो एक यादृच्छिक स्मृति पते को इंगित करता है) को संदर्भित या असाइन करना | * एक गैर-प्रारंभिक सूचक ([[जंगली सूचक]], जो एक यादृच्छिक स्मृति पते को इंगित करता है) को संदर्भित या असाइन करना | ||
Line 37: | Line 39: | ||
* ऐसे प्रोग्राम को निष्पादित करने का प्रयास करना जो सही ढंग से संकलित नहीं होता है। (कुछ संकलक{{Which?|date=December 2021}} संकलन-समय त्रुटियों की उपस्थिति के बावजूद निष्पादन योग्य फ़ाइल आउटपुट करेगा।) | * ऐसे प्रोग्राम को निष्पादित करने का प्रयास करना जो सही ढंग से संकलित नहीं होता है। (कुछ संकलक{{Which?|date=December 2021}} संकलन-समय त्रुटियों की उपस्थिति के बावजूद निष्पादन योग्य फ़ाइल आउटपुट करेगा।) | ||
सी कोड में, सेगमेंटेशन दोष | सी कोड में, सेगमेंटेशन दोष प्रायः पॉइंटर उपयोग में त्रुटियों के कारण होते हैं, खासकर [[सी गतिशील स्मृति आवंटन]] में। अशक्त सूचक को संदर्भित करना, जिसके परिणामस्वरूप [[अपरिभाषित व्यवहार]] होता है, आमतौर पर एक विभाजन दोष का कारण होगा। ऐसा इसलिए है क्योंकि एक शून्य सूचक वैध स्मृति पता नहीं हो सकता है। दूसरी ओर, वाइल्ड पॉइंटर्स और डैंगलिंग पॉइंटर्स उस मेमोरी की ओर इशारा करते हैं जो मौजूद हो भी सकती है और नहीं भी, और पढ़ने योग्य या लिखने योग्य हो भी सकती है और नहीं भी, और इस प्रकार क्षणिक बग का परिणाम हो सकता है। उदाहरण के लिए: | ||
<syntaxhighlight lang=c> | <syntaxhighlight lang=c> | ||
char *p1 = NULL; // Null pointer | char *p1 = NULL; // Null pointer | ||
Line 105: | Line 107: | ||
*ptr = 1; | *ptr = 1; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
निम्नलिखित कोड में एक नल पॉइंटर डिरेफरेंस शामिल है, लेकिन जब संकलित किया जाता है तो | निम्नलिखित कोड में एक नल पॉइंटर डिरेफरेंस शामिल है, लेकिन जब संकलित किया जाता है तो प्रायः सेगमेंटेशन गलती नहीं होती है, क्योंकि मूल्य अप्रयुक्त होता है और इस प्रकार डीरेफरेंस को प्रायः [[मृत कोड उन्मूलन]] द्वारा अनुकूलित किया जाएगा: | ||
<syntaxhighlight lang=c> | <syntaxhighlight lang=c> | ||
int *ptr = NULL; | int *ptr = NULL; |
Revision as of 11:05, 28 April 2023
कम्प्यूटिंग में, विभाजन दोष या एक्सेस उल्लंघन दोष (कंप्यूटिंग), या विफलता की स्थिति है, जो मेमोरी सुरक्षा के साथ हार्डवेयर द्वारा उठाया जाता है, ऑपरेटिंग सिस्टम (OS) को सूचित करता है, सॉफ्टवेयर ने प्रतिबंधित क्षेत्र तक पहुंचने का प्रयास किया है। मेमोरी (एक मेमोरी एक्सेस उल्लंघन)। मानक x86 कंप्यूटरों पर, यह सामान्य सुरक्षा दोष का एक रूप है। ऑपरेटिंग सिस्टम कर्नेल, प्रतिक्रिया में, आमतौर पर कुछ सुधारात्मक कार्रवाई करता है, आम तौर पर प्रक्रिया को संकेत (कंप्यूटिंग) भेजकर गलती को आपत्तिजनक प्रक्रिया (कंप्यूटिंग) पर भेज देता है। प्रक्रियाएं कुछ मामलों में एक कस्टम सिग्नल हैंडलर स्थापित कर सकती हैं, जिससे उन्हें अपने आप ठीक होने की अनुमति मिलती है,[1] लेकिन अन्यथा ओएस डिफ़ॉल्ट सिग्नल हैंडलर का उपयोग किया जाता है, आम तौर पर प्रक्रिया की असामान्य समाप्ति (एक प्रोग्राम क्रैश (कंप्यूटिंग)), और कभी-कभी एक कोर निपात होता है।
सेगमेंटेशन दोष सी (प्रोग्रामिंग भाषा) जैसी भाषाओं में लिखे गए प्रोग्रामों में त्रुटि का एक सामान्य वर्ग है जो निम्न-स्तरीय मेमोरी एक्सेस प्रदान करता है और कुछ से लेकर कोई सुरक्षा जांच नहीं करता है। वे मुख्य रूप से आभासी मेमोरी एड्रेसिंग के लिए पॉइंटर (कंप्यूटर प्रोग्रामिंग) के उपयोग में त्रुटियों के कारण उत्पन्न होते हैं, विशेष रूप से अवैध पहुंच के कारण। एक अन्य प्रकार की मेमोरी एक्सेस त्रुटि एक बस त्रुटि है, जिसके विभिन्न कारण भी हैं, लेकिन आज यह बहुत दुर्लभ है; ये मुख्य रूप से गलत भौतिक मेमोरी एड्रेसिंग के कारण होते हैं, या गलत तरीके से मेमोरी एक्सेस के कारण होते हैं - ये ऐसे मेमोरी रेफरेंस होते हैं जिन्हें हार्डवेयर एड्रेस नहीं कर सकता है, बजाय उन रेफरेंस के जिन्हें एड्रेस करने की अनुमति नहीं है।
कई प्रोग्रामिंग लैंग्वेज सेगमेंटेशन दोषों से बचने और मेमोरी सुरक्षा में सुधार के लिए डिज़ाइन किए गए तंत्रों को नियोजित कर सकती हैं। उदाहरण के लिए, जंग (प्रोग्रामिंग भाषा) एक स्वामित्व-आधारित को नियोजित करता है[2] स्मृति सुरक्षा सुनिश्चित करने के लिए मॉडल।[3] अन्य भाषाएँ, जैसे कि लिस्प (प्रोग्रामिंग भाषा) और जावा (प्रोग्रामिंग भाषा), कचरा संग्रह (कंप्यूटर विज्ञान) को नियोजित करती हैं,[4] जो स्मृति त्रुटियों के कुछ वर्गों से बचा जाता है जिससे विभाजन दोष हो सकते हैं।[5]
सिंहावलोकन
सेगमेंटेशन फॉल्ट तब होता है जब कोई प्रोग्राम स्मृति लोकेशन तक पहुंचने का प्रयास करता है जिसे एक्सेस करने की अनुमति नहीं है, या किसी मेमोरी लोकेशन को इस तरह एक्सेस करने का प्रयास करता है जिसकी अनुमति नहीं है (उदाहरण के लिए, केवल पढ़ने के लिये मेमोरी में लिखने का प्रयास | रीड-ओनली लोकेशन, या ऑपरेटिंग सिस्टम के हिस्से को ओवरराइट करने के लिए)।
शब्द विभाजन के कंप्यूटिंग में विभिन्न उपयोग हैं; सेगमेंटेशन फॉल्ट के संदर्भ में, 1950 के दशक से इस्तेमाल किया जाने वाला शब्द,[citation needed] यह किसी प्रोग्राम के एड्रेस स्पेस को संदर्भित करता है।[6] स्मृति सुरक्षा के साथ, केवल प्रोग्राम का अपना पता स्थान ही पढ़ने योग्य होता है, और इसमें से केवल कॉल स्टैक और प्रोग्राम के डेटा सेगमेंट का रीड/राइट भाग लिखने योग्य होता है, जबकि रीड-ओनली डेटा और कोड खंड लिखने योग्य नहीं होते हैं। इस प्रकार प्रोग्राम के एड्रेस स्पेस के बाहर पढ़ने का प्रयास, या एड्रेस स्पेस के रीड-ओनली सेगमेंट में लिखने से सेगमेंटेशन फॉल्ट होता है, इसलिए नाम।
वर्चुअल मेमोरी प्रदान करने के लिए हार्डवेयर स्मृति विभाजन का उपयोग करने वाले सिस्टम पर, सेगमेंटेशन गलती तब होती है जब हार्डवेयर गैर-मौजूद सेगमेंट को संदर्भित करने का प्रयास करता है, डेटा खंड की सीमाओं के बाहर किसी स्थान को संदर्भित करता है, या किसी स्थान को संदर्भित करता है। उस सेगमेंट के लिए दी गई अनुमतियों द्वारा अनुमत फैशन नहीं। केवल पेजिंग का उपयोग करने वाले सिस्टम पर, एक अमान्य पृष्ठ दोष आमतौर पर एक विभाजन दोष की ओर जाता है, और विभाजन दोष और पृष्ठ दोष दोनों ही वर्चुअल मेमोरी मैनेजमेंट सिस्टम द्वारा उठाए गए दोष हैं। सेगमेंटेशन दोष पृष्ठ दोषों से स्वतंत्र रूप से भी हो सकते हैं: वैध पृष्ठ तक अवैध पहुंच एक सेगमेंटेशन गलती है, लेकिन अमान्य पृष्ठ गलती नहीं है, और सेगमेंटेशन दोष पृष्ठ के मध्य में हो सकते हैं (इसलिए कोई पृष्ठ गलती नहीं है), उदाहरण के लिए बफ़र अधिकता जो एक पृष्ठ के भीतर रहता है लेकिन अवैध रूप से स्मृति को अधिलेखित कर देता है।
हार्डवेयर स्तर पर, स्मृति प्रबंधन इकाई (एमएमयू) द्वारा अवैध पहुंच (यदि संदर्भित मेमोरी मौजूद है) द्वारा इसकी स्मृति सुरक्षा सुविधा के भाग के रूप में, या एक अमान्य पृष्ठ दोष (यदि संदर्भित स्मृति मौजूद नहीं है) द्वारा शुरू में गलती उठाई जाती है ). यदि समस्या एक अमान्य तार्किक पता नहीं है बल्कि एक अमान्य भौतिक पता है, तो इसके बजाय एक बस त्रुटि उठाई जाती है, हालांकि ये हमेशा अलग नहीं होते हैं।
ऑपरेटिंग सिस्टम के स्तर पर, यह गलती पकड़ी जाती है और उस सिग्नल के लिए प्रक्रिया के हैंडलर को सक्रिय करते हुए, आपत्तिजनक प्रक्रिया को एक संकेत दिया जाता है। अलग-अलग ऑपरेटिंग सिस्टम में अलग-अलग सिग्नल नाम होते हैं जो इंगित करते हैं कि सेगमेंटेशन गलती हुई है। यूनिक्स जैसे ऑपरेटिंग सिस्टम पर, SIGSEGV नामक एक सिग्नल (विभाजन उल्लंघन से संक्षिप्त) को आपत्तिजनक प्रक्रिया के लिए भेजा जाता है। Microsoft Windows पर, आपत्तिजनक प्रक्रिया को एक STATUS_ACCESS_VIOLATION अपवाद प्रबंधन प्राप्त होता है।
कारण
जिन परिस्थितियों में सेगमेंटेशन का उल्लंघन होता है और वे खुद को कैसे प्रकट करते हैं, वे हार्डवेयर और ऑपरेटिंग सिस्टम के लिए विशिष्ट हैं: अलग-अलग हार्डवेयर दी गई शर्तों के लिए अलग-अलग दोष पैदा करते हैं, और अलग-अलग ऑपरेटिंग सिस्टम इन्हें अलग-अलग सिग्नल में परिवर्तित करते हैं जो प्रक्रियाओं पर पारित होते हैं। निकटस्थ कारण एक मेमोरी एक्सेस उल्लंघन है, जबकि अंतर्निहित कारण आमतौर पर किसी प्रकार का सॉफ्टवेयर बग है। मूल कारण विश्लेषण का निर्धारण - बग को डिबग करना - कुछ मामलों में सरल हो सकता है, जहां प्रोग्राम लगातार सेगमेंटेशन गलती का कारण बनता है (उदाहरण के लिए, शून्य सूचक को संदर्भित करना), जबकि अन्य मामलों में बग को पुन: पेश करना और स्मृति पर निर्भर करना मुश्किल हो सकता है प्रत्येक रन पर आवंटन (उदाहरण के लिए, झूलने वाले सूचक को संदर्भित करना)।
विभाजन दोष के कुछ विशिष्ट कारण निम्नलिखित हैं:
- एक गैर-मौजूद स्मृति पते तक पहुँचने का प्रयास (प्रक्रिया के पता स्थान के बाहर)
- स्मृति तक पहुँचने का प्रयास कार्यक्रम के पास अधिकार नहीं है (जैसे कि प्रक्रिया के संदर्भ में कर्नेल संरचनाएँ)
- रीड-ओनली मेमोरी (जैसे कोड सेगमेंट) लिखने का प्रयास
ये बदले में प्रायः प्रोग्रामिंग त्रुटियों के कारण होते हैं, जिसके परिणामस्वरूप अमान्य मेमोरी एक्सेस होती है:
- एक अशक्त सूचक को संदर्भित करना, जो आमतौर पर एक ऐसे पते की ओर इशारा करता है जो प्रक्रिया के पता स्थान का हिस्सा नहीं है
- एक गैर-प्रारंभिक सूचक (जंगली सूचक, जो एक यादृच्छिक स्मृति पते को इंगित करता है) को संदर्भित या असाइन करना
- फ्रीड पॉइंटर को डिफ्रेंसिंग या असाइन करना (झूलने वाला पॉइंटर, जो उस मेमोरी को इंगित करता है जिसे मुक्त/डीललोकेटेड/डिलीट किया गया है)
- एक बफर अतिप्रवाह
- स्टैक ओवरफ़्लो
- ऐसे प्रोग्राम को निष्पादित करने का प्रयास करना जो सही ढंग से संकलित नहीं होता है। (कुछ संकलक[which?] संकलन-समय त्रुटियों की उपस्थिति के बावजूद निष्पादन योग्य फ़ाइल आउटपुट करेगा।)
सी कोड में, सेगमेंटेशन दोष प्रायः पॉइंटर उपयोग में त्रुटियों के कारण होते हैं, खासकर सी गतिशील स्मृति आवंटन में। अशक्त सूचक को संदर्भित करना, जिसके परिणामस्वरूप अपरिभाषित व्यवहार होता है, आमतौर पर एक विभाजन दोष का कारण होगा। ऐसा इसलिए है क्योंकि एक शून्य सूचक वैध स्मृति पता नहीं हो सकता है। दूसरी ओर, वाइल्ड पॉइंटर्स और डैंगलिंग पॉइंटर्स उस मेमोरी की ओर इशारा करते हैं जो मौजूद हो भी सकती है और नहीं भी, और पढ़ने योग्य या लिखने योग्य हो भी सकती है और नहीं भी, और इस प्रकार क्षणिक बग का परिणाम हो सकता है। उदाहरण के लिए:
char *p1 = NULL; // Null pointer
char *p2; // Wild pointer: not initialized at all.
char *p3 = malloc(10 * sizeof(char)); // Initialized pointer to allocated memory
// (assuming malloc did not fail)
free(p3); // p3 is now a dangling pointer, as memory has been freed
इनमें से किसी भी वेरिएबल को डिफ्रेंस करने से सेगमेंटेशन फॉल्ट हो सकता है: नल पॉइंटर को डीरेफर करने से आमतौर पर एक सेगफॉल्ट होता है, जबकि वाइल्ड पॉइंटर से पढ़ने के बजाय रैंडम डेटा हो सकता है, लेकिन कोई सेगफॉल्ट नहीं होता है, और डैंगलिंग पॉइंटर से पढ़ने के परिणामस्वरूप वैध डेटा हो सकता है। जबकि, और फिर यादृच्छिक डेटा, क्योंकि यह ओवरराइट किया गया है।
हैंडलिंग
सेगमेंटेशन गलती या बस त्रुटि के लिए डिफ़ॉल्ट क्रिया उस प्रक्रिया की असामान्य समाप्ति है जिसने इसे ट्रिगर किया। डिबगिंग में सहायता के लिए एक कोर फ़ाइल उत्पन्न की जा सकती है, और अन्य प्लेटफ़ॉर्म-निर्भर क्रियाएं भी की जा सकती हैं। उदाहरण के लिए, ग्रसिक्युरिटी पैच का उपयोग करने वाले लिनक्स सिस्टम बफर ओवरफ्लो का उपयोग करके संभावित घुसपैठ के प्रयासों की निगरानी के लिए SIGSEGV संकेतों को लॉग कर सकते हैं।
कुछ प्रणालियों पर, जैसे कि लिनक्स और विंडोज, यह संभव है कि कार्यक्रम स्वयं एक विभाजन दोष को संभाले।[7] आर्किटेक्चर और ऑपरेटिंग सिस्टम के आधार पर, रनिंग प्रोग्राम न केवल ईवेंट को हैंडल कर सकता है, बल्कि इसकी स्थिति के बारे में कुछ जानकारी निकाल सकता है जैसे स्टैक ट्रेस प्राप्त करना, प्रोसेसर रजिस्टर वैल्यू, स्रोत कोड की लाइन जब इसे ट्रिगर किया गया था, मेमोरी एड्रेस जो था अमान्य रूप से एक्सेस किया गया[8] और क्या कार्रवाई पढ़ी गई या लिखी गई थी।[9] हालांकि एक सेगमेंटेशन गलती का आम तौर पर मतलब है कि प्रोग्राम में एक बग है जिसे ठीक करने की आवश्यकता है, जानबूझकर ऐसी विफलता का कारण परीक्षण, डिबगिंग और प्लेटफॉर्म का अनुकरण करना भी संभव है जहां मेमोरी तक सीधी पहुंच की आवश्यकता है। बाद वाले मामले में, सिस्टम को गलती होने के बाद भी प्रोग्राम को चलाने की अनुमति देने में सक्षम होना चाहिए। इस मामले में, जब सिस्टम अनुमति देता है, तो घटना को संभालना और निष्पादन जारी रखने के लिए असफल निर्देश पर कूदने के लिए प्रोसेसर प्रोग्राम काउंटर को बढ़ाना संभव है।[10]
उदाहरण
रीड ओनली मेमोरी में लिखना
रीड-ओनली मेमोरी में लिखने से सेगमेंटेशन फॉल्ट होता है। कोड त्रुटियों के स्तर पर, यह तब होता है जब प्रोग्राम अपने स्वयं के कोड सेगमेंट या डेटा सेगमेंट के रीड-ओनली हिस्से को लिखता है, क्योंकि ये OS द्वारा रीड-ओनली मेमोरी में लोड किए जाते हैं।
यहां एएनएसआई सी कोड का एक उदाहरण दिया गया है जो आम तौर पर स्मृति सुरक्षा वाले प्लेटफॉर्म पर सेगमेंटेशन गलती का कारण बनता है। यह एक स्ट्रिंग शाब्दिक को संशोधित करने का प्रयास करता है, जो एएनएसआई सी मानक के अनुसार अपरिभाषित व्यवहार है। अधिकांश संकलक इसे संकलित समय पर नहीं पकड़ेंगे, और इसके बजाय इसे निष्पादन योग्य कोड में संकलित करेंगे जो क्रैश हो जाएगा:
int main(void)
{
char *s = "hello world";
*s = 'H';
}
जब इस कोड वाले प्रोग्राम को संकलित किया जाता है, तो स्ट्रिंग हैलो वर्ल्ड को प्रोग्राम एक्जीक्यूटेबल फ़ाइल के रोडाटा सेक्शन में रखा जाता है: डेटा सेगमेंट का रीड-ओनली सेक्शन। जब लोड किया जाता है, तो ऑपरेटिंग सिस्टम इसे अन्य स्ट्रिंग्स और निरंतर (प्रोग्रामिंग) डेटा के साथ मेमोरी के रीड-ओनली सेगमेंट में रखता है। जब निष्पादित किया जाता है, तो एक चर, s, स्ट्रिंग के स्थान को इंगित करने के लिए सेट किया जाता है, और चर के माध्यम से स्मृति में H वर्ण लिखने का प्रयास किया जाता है, जिससे विभाजन दोष उत्पन्न होता है। ऐसे प्रोग्राम को एक कंपाइलर के साथ संकलित करना जो संकलन समय पर केवल-पढ़ने के लिए स्थानों के असाइनमेंट की जांच नहीं करता है, और इसे यूनिक्स-जैसे ऑपरेटिंग सिस्टम पर चलाने से निम्न रनटाइम त्रुटि उत्पन्न होती है:
$ gcc segfault.c -g -o segfault
$ ./segfault
Segmentation fault
जीडीबी से कोर फ़ाइल का पश्व-अनुरेखन:
Program received signal SIGSEGV, Segmentation fault.
0x1c0005c2 in main () at segfault.c:6
6 *s = 'H';
इस कोड को वर्ण सूचक के बजाय सरणी का उपयोग करके ठीक किया जा सकता है, क्योंकि यह ढेर पर स्मृति आवंटित करता है और इसे स्ट्रिंग अक्षर के मान में प्रारंभ करता है:
char s[] = "hello world";
s[0] = 'H'; // equivalently, *s = 'H';
भले ही स्ट्रिंग अक्षर को संशोधित नहीं किया जाना चाहिए (यह सी मानक में अपरिभाषित व्यवहार है), सी में वे हैं static char []
प्रकार,[11][12][13] इसलिए मूल कोड में कोई निहित रूपांतरण नहीं है (जो इंगित करता है a char *
उस सरणी में), जबकि सी ++ में वे हैं static const char []
प्रकार, और इस प्रकार एक निहित रूपांतरण होता है, इसलिए संकलक आमतौर पर इस विशेष त्रुटि को पकड़ लेंगे।
अशक्त सूचक dereference
सी और सी-जैसी भाषाओं में, अशक्त संकेतकों का उपयोग बिना किसी वस्तु के संकेतक और एक त्रुटि संकेतक के रूप में किया जाता है, और एक अशक्त सूचक (एक अशक्त सूचक के माध्यम से पढ़ना या लिखना) को संदर्भित करना एक बहुत ही सामान्य कार्यक्रम त्रुटि है। सी मानक यह नहीं कहता है कि शून्य सूचक स्मृति पता 0 के सूचक के समान है, हालांकि व्यवहार में ऐसा हो सकता है। अधिकांश ऑपरेटिंग सिस्टम नल पॉइंटर के पते को इस तरह से मैप करते हैं कि इसे एक्सेस करने से सेगमेंटेशन गलती हो जाती है। सी मानक द्वारा इस व्यवहार की गारंटी नहीं है। एक अशक्त सूचक को संदर्भित करना C में अपरिभाषित व्यवहार है, और एक अनुरूप कार्यान्वयन को यह मानने की अनुमति है कि कोई भी सूचक जो अशक्त है, अशक्त नहीं है।
int *ptr = NULL;
printf("%d", *ptr);
यह नमूना कोड एक शून्य सूचक बनाता है, और फिर इसके मान तक पहुँचने का प्रयास करता है (मान पढ़ें)। ऐसा करने से कई ऑपरेटिंग सिस्टम पर रनटाइम में सेगमेंटेशन गलती हो जाती है।
एक अशक्त सूचक को हटाना और फिर उसे निर्दिष्ट करना (एक गैर-मौजूद लक्ष्य के लिए एक मान लिखना) भी आमतौर पर एक विभाजन दोष का कारण बनता है:
int *ptr = NULL;
*ptr = 1;
निम्नलिखित कोड में एक नल पॉइंटर डिरेफरेंस शामिल है, लेकिन जब संकलित किया जाता है तो प्रायः सेगमेंटेशन गलती नहीं होती है, क्योंकि मूल्य अप्रयुक्त होता है और इस प्रकार डीरेफरेंस को प्रायः मृत कोड उन्मूलन द्वारा अनुकूलित किया जाएगा:
int *ptr = NULL;
*ptr;
बफर अतिप्रवाह
निम्न कोड वर्ण सरणी तक पहुँचता है s
इसकी ऊपरी सीमा से परे। संकलक और प्रोसेसर के आधार पर, इसका परिणाम विभाजन दोष हो सकता है।
char s[] = "hello world";
char c = s[20];
ढेर अतिप्रवाह
आधार मामले के बिना एक और उदाहरण प्रत्यावर्तन है:
int main(void)
{
return main();
}
जो स्टैक ओवरफ़्लो का कारण बनता है जिसके परिणामस्वरूप सेगमेंटेशन गलती होती है।[14] भाषा, संकलक द्वारा किए गए अनुकूलन और कोड की सटीक संरचना के आधार पर अनंत पुनरावर्तन आवश्यक रूप से स्टैक ओवरफ़्लो का परिणाम नहीं हो सकता है। इस मामले में, अगम्य कोड (रिटर्न स्टेटमेंट) का व्यवहार अपरिभाषित है, इसलिए कंपाइलर इसे समाप्त कर सकता है और टेल कॉल ऑप्टिमाइज़ेशन का उपयोग कर सकता है जिसके परिणामस्वरूप कोई स्टैक उपयोग नहीं हो सकता है। अन्य अनुकूलन में पुनरावर्तन को पुनरावृत्ति में अनुवाद करना शामिल हो सकता है, जो उदाहरण फ़ंक्शन की संरचना को देखते हुए प्रोग्राम को हमेशा के लिए चलाने में परिणाम देगा, जबकि संभवतः इसके स्टैक को ओवरफ्लो नहीं करेगा।
यह भी देखें
- सामान्य संरक्षण त्रुटि
- भंडारण उल्लंघन
- गुरु ध्यान
संदर्भ
- ↑ Expert C programming: deep C secrets By Peter Van der Linden, page 188
- ↑ "The Rust Programming Language - Ownership".
- ↑ "Fearless Concurrency with Rust - The Rust Programming Language Blog".
- ↑ McCarthy, John (April 1960). "सांकेतिक भावों के पुनरावर्ती कार्य और मशीन द्वारा उनकी गणना, भाग I". Communications of the ACM. 4 (3): 184–195. doi:10.1145/367177.367199. S2CID 1489409. Retrieved 2018-09-22.
- ↑ Dhurjati, Dinakar; Kowshik, Sumant; Adve, Vikram; Lattner, Chris (1 January 2003). "मेमोरी सुरक्षा रनटाइम चेक या कचरा संग्रह के बिना" (PDF). Proceedings of the 2003 ACM SIGPLAN Conference on Language, Compiler, and Tool for Embedded Systems (in English). ACM. 38 (7): 69–80. doi:10.1145/780732.780743. ISBN 1581136471. S2CID 1459540. Retrieved 2018-09-22.
- ↑ "डिबगिंग विभाजन दोष और सूचक समस्याएं - Cprogramming.com". www.cprogramming.com. Retrieved 2021-02-03.
- ↑ "Cleanly recovering from Segfaults under Windows and Linux (32-bit, x86)". Retrieved 2020-08-23.
- ↑ "Implementation of the SIGSEGV/SIGABRT handler which prints the debug stack trace". GitHub. Retrieved 2020-08-23.
- ↑ "How to identify read or write operations of page fault when using sigaction handler on SIGSEGV?(LINUX)". Retrieved 2020-08-23.
- ↑ "LINUX – WRITING FAULT HANDLERS". Retrieved 2020-08-23.
- ↑ "6.1.4 String literals". ISO/IEC 9899:1990 - Programming languages -- C.
- ↑ "6.4.5 String literals". ISO/IEC 9899:1999 - Programming languages -- C.
- ↑ "6.4.5 String literals". ISO/IEC 9899:2011 - Programming languages -- C.
- ↑ What is the difference between a segmentation fault and a stack overflow? at Stack Overflow