विभाजन दोष (सेगमेंटेशन फॉल्ट): Difference between revisions
No edit summary |
No edit summary |
||
(10 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
{{short description|Computer fault caused by access to restricted memory}} | {{short description|Computer fault caused by access to restricted memory}}कम्प्यूटिंग में, '''विभाजन दोष''' या '''एक्सेस उल्लंघन दोष''' (कंप्यूटिंग), या विफलता की स्थिति है, जो मेमोरी सुरक्षा के साथ हार्डवेयर द्वारा उठाया जाता है, [[ऑपरेटिंग सिस्टम|ऑपरेटिंग प्रणाली]] (OS) को सूचित करता है, सॉफ्टवेयर ने प्रतिबंधित क्षेत्र तक पहुंचने का प्रयास किया है। मेमोरी ( मेमोरी एक्सेस उल्लंघन) मानक x[[86]] कंप्यूटरों पर, यह सामान्य सुरक्षा दोष का रूप है। [[ऑपरेटिंग सिस्टम कर्नेल|ऑपरेटिंग प्रणाली आधार]], प्रतिक्रिया में, सामान्यतः कुछ सुधारात्मक कार्रवाई करता है, सामान्यतः प्रक्रिया को [[ संकेत (कंप्यूटिंग) ]] भेजकर त्रुटि को आपत्तिजनक [[प्रक्रिया (कंप्यूटिंग)]] पर भेज देता है। प्रक्रियाएं कुछ स्थितियों में कस्टम सिग्नल हैंडलर स्थापित कर सकती हैं, जिससे उन्हें स्वयं ठीक होने की अनुमति मिलती है,<ref name="Peter Van der Linden">''Expert C programming: deep C secrets'' By Peter Van der Linden, page 188</ref> अन्यथा ओएस डिफ़ॉल्ट सिग्नल हैंडलर का उपयोग किया जाता है, सामान्यतः प्रक्रिया की [[असामान्य समाप्ति]] (प्रोग्राम [[क्रैश (कंप्यूटिंग)]]), एवं कभी-कभी [[कोर निपात]] होता है। | ||
विभाजन दोष [[सी (प्रोग्रामिंग भाषा)|C (प्रोग्रामिंग भाषा)]] जैसी भाषाओं में लिखे गए प्रोग्रामों में त्रुटि का सामान्य वर्ग है जो निम्न-स्तरीय मेमोरी एक्सेस प्रदान करता है एवं कोई सुरक्षा निरिक्षण नहीं करता है। वे मुख्य रूप से [[ आभासी मेमोरी |आभासी मेमोरी]] एड्रेसिंग के लिए सूचक (कंप्यूटर प्रोग्रामिंग) के उपयोग में त्रुटियों के कारण उत्पन्न होते हैं, विशेष रूप से अवैध पहुंच के कारण अन्य प्रकार की मेमोरी एक्सेस त्रुटि [[बस त्रुटि]] है, जिसके विभिन्न कारण भी हैं, किन्तु वर्तमान में यह अधिक दुर्लभ है; ये मुख्य रूप से गलत भौतिक मेमोरी एड्रेसिंग के कारण होते हैं, या गलत प्रविधि से मेमोरी एक्सेस के कारण होते हैं, ये ऐसे मेमोरी संदर्भ होते हैं जिन्हें हार्डवेयर एड्रेस नहीं कर सकता है, उन रेफरेंस के जिन्हें एड्रेस करने की अनुमति नहीं होती है। | |||
कई प्रोग्रामिंग भाषा विभाजन दोषों से बचने एवं मेमोरी सुरक्षा में सुधार के लिए चित्रित किए गए तंत्रों को नियोजित कर सकती हैं। उदाहरण के लिए, [[ जंग (प्रोग्रामिंग भाषा) ]]स्वामित्व आधारित को नियोजित करता है।<ref>{{cite web| url = http://doc.rust-lang.org/book/ownership.html| title = The Rust Programming Language - Ownership}}</ref> मेमोरी सुरक्षा सुनिश्चित करने के लिए प्रतिरूप<ref>{{cite web| url = http://blog.rust-lang.org/2015/04/10/Fearless-Concurrency.html| title = Fearless Concurrency with Rust - The Rust Programming Language Blog}}</ref> अन्य भाषाएँ, जैसे कि [[लिस्प (प्रोग्रामिंग भाषा)]] एवं [[जावा (प्रोग्रामिंग भाषा)]], [[कचरा संग्रह (कंप्यूटर विज्ञान)|जंक संग्रह (कंप्यूटर विज्ञान)]] को नियोजित करती हैं,<ref>{{Cite journal|url=http://www-formal.stanford.edu/jmc/recursive.html|title=सांकेतिक भावों के पुनरावर्ती कार्य और मशीन द्वारा उनकी गणना, भाग I|last=McCarthy|first=John|author-link=John McCarthy (computer scientist)|date=April 1960|journal=[[Communications of the ACM]]|volume=4|issue=3|pages=184–195|doi=10.1145/367177.367199|s2cid=1489409|access-date=2018-09-22|doi-access=free}}</ref> जो मेमोरी त्रुटियों के कुछ वर्गों से बचती है, जिससे विभाजन दोष हो सकते हैं।<ref>{{cite journal|last1=Dhurjati|first1=Dinakar|last2=Kowshik|first2=Sumant|last3=Adve|first3=Vikram|last4=Lattner|first4=Chris|title=मेमोरी सुरक्षा रनटाइम चेक या कचरा संग्रह के बिना|journal=Proceedings of the 2003 ACM SIGPLAN Conference on Language, Compiler, and Tool for Embedded Systems|date=1 January 2003|volume=38|issue=7|pages=69–80|doi=10.1145/780732.780743|url=http://llvm.org/pubs/2003-05-05-LCTES03-CodeSafety.pdf|access-date=2018-09-22|publisher=ACM|language=en|isbn=1581136471|s2cid=1459540}}</ref> | |||
कई प्रोग्रामिंग भाषा विभाजन दोषों से बचने एवं मेमोरी सुरक्षा में सुधार के लिए चित्रित किए गए तंत्रों को नियोजित कर सकती हैं। उदाहरण के लिए, [[ जंग (प्रोग्रामिंग भाषा) ]]स्वामित्व आधारित को नियोजित करता है।<ref>{{cite web| url = http://doc.rust-lang.org/book/ownership.html| title = The Rust Programming Language - Ownership}}</ref> | |||
== सिंहावलोकन == | == सिंहावलोकन == | ||
[[File:FreeBSD kernel panic.png|thumb|मानव जनित सिग्नल का उदाहरण]] | [[File:FreeBSD kernel panic.png|thumb|मानव जनित सिग्नल का उदाहरण]] | ||
[[File:KDE Crash Handler screenshot.png|thumb| | [[File:KDE Crash Handler screenshot.png|thumb|केडीई डेस्कटॉप वातावरण में विभाजन दोष कृता को प्रभावित कर रहा है।]]विभाजन दोष तब होता है जब कोई प्रोग्राम [[स्मृति|मेमोरी]] स्थान तक पहुंचने का प्रयास करता है जिसे एक्सेस करने की अनुमति नहीं है, या किसी मेमोरी स्थान मेंइस प्रकार प्रवेश करने का प्रयास करता है, जिसकी अनुमति नहीं है (उदाहरण के लिए, रीड ओनली मेमोरी में लिखने का प्रयास केवल पढ़ने योग्य स्थान, या ऑपरेटिंग प्रणाली के भाग को ओवरराइट करने के लिए)। | ||
शब्द विभाजन के कंप्यूटिंग में विभिन्न उपयोग हैं; विभाजन दोष के संदर्भ में, 1950 के दशक से उपयोग किया जाने वाला शब्द, यह किसी प्रोग्राम के एड्रेस स्पेस को संदर्भित करता है।<ref>{{Cite web|title=डिबगिंग विभाजन दोष और सूचक समस्याएं - Cprogramming.com|url=https://www.cprogramming.com/debugging/segfaults.html|access-date=2021-02-03|website=www.cprogramming.com}}</ref> | शब्द विभाजन के कंप्यूटिंग में विभिन्न उपयोग हैं; विभाजन दोष के संदर्भ में, 1950 के दशक से उपयोग किया जाने वाला शब्द, यह किसी प्रोग्राम के एड्रेस स्पेस को संदर्भित करता है।<ref>{{Cite web|title=डिबगिंग विभाजन दोष और सूचक समस्याएं - Cprogramming.com|url=https://www.cprogramming.com/debugging/segfaults.html|access-date=2021-02-03|website=www.cprogramming.com}}</ref> मेमोरी सुरक्षा के साथ, केवल प्रोग्राम का स्वयं का स्थान ही पढ़ने योग्य होता है, एवं इसमें से केवल [[कॉल स्टैक]] एवं प्रोग्राम के डेटा खंड के लिखने योग्य होता है, जबकि केवल पढ़ने के लिए डेटा एवं [[ कोड खंड ]] लिखने योग्य नहीं होते हैं। इस प्रकार प्रोग्राम के एड्रेस स्पेस के बाहर पढ़ने का प्रयास, या एड्रेस स्पेस के केवल पढ़ने के लिए खंड में लिखने से विभाजन दोष होता है। | ||
वर्चुअल मेमोरी प्रदान करने के लिए हार्डवेयर | वर्चुअल मेमोरी प्रदान करने के लिए हार्डवेयर मेमोरी विभाजन का उपयोग करने वाले प्रणाली पर, विभाजन त्रुटि तब होती है जब हार्डवेयर गैर-उपस्थित खंड को संदर्भित करने का प्रयास करता है, [[डेटा खंड]] की सीमाओं के बाहर किसी स्थान को संदर्भित करता है। उस खंड के लिए दी गई अनुमतियों द्वारा केवल [[पेजिंग]] का उपयोग करने वाले प्रणाली पर, [[अमान्य पृष्ठ दोष]] सामान्यतः विभाजन दोष की ओर जाता है, एवं विभाजन दोष एवं पृष्ठ दोष दोनों ही वर्चुअल मेमोरी मैनेजमेंट प्रणाली द्वारा उठाए गए दोष हैं। विभाजन दोष पृष्ठ दोषों से स्वतंत्र रूप से भी हो सकते हैं। वैध पृष्ठ तक अवैध पहुंच विभाजन त्रुटि है, किन्तु अमान्य पृष्ठ त्रुटि नहीं है, एवं विभाजन दोष पृष्ठ के मध्य में हो सकते हैं (इसलिए कोई पृष्ठ त्रुटि नहीं है), उदाहरण के लिए [[ बफ़र अधिकता ]]जो पृष्ठ के अंदर रहता है किन्तु अवैध रूप से मेमोरी को अधिलेखित कर देता है। | ||
हार्डवेयर स्तर पर, [[स्मृति प्रबंधन इकाई]] (MMU) द्वारा अवैध पहुंच (यदि संदर्भित | हार्डवेयर स्तर पर, [[स्मृति प्रबंधन इकाई|मेमोरी प्रबंधन इकाई]] (MMU) द्वारा अवैध पहुंच (यदि संदर्भित मेमोरी उपस्थित है) द्वारा इसकी मेमोरी सुरक्षा सुविधा के भाग के रूप में, या अमान्य पृष्ठ दोष (यदि संदर्भित मेमोरी उपस्थित नहीं है) द्वारा प्रारम्भ में त्रुटि उठाई जाती है। यदि समस्या अमान्य तार्किक पता नहीं है जबकि अमान्य भौतिक पता है, तो इसके अतिरिक्त बस त्रुटि उठाई जाती है, चूंकि ये सदैव भिन्न नहीं होते हैं। | ||
ऑपरेटिंग प्रणाली के स्तर पर, यह त्रुटि पकड़ी जाती है एवं उस सिग्नल के लिए प्रक्रिया के हैंडलर को सक्रिय करते हुए, आपत्तिजनक प्रक्रिया को संकेत दिया जाता है। भिन्न-भिन्न ऑपरेटिंग प्रणाली में भिन्न-भिन्न सिग्नल नाम होते हैं जो इंगित करते हैं कि विभाजन त्रुटि हुई है। यूनिक्स जैसे ऑपरेटिंग प्रणाली पर, SIGSEGV नामक सिग्नल (विभाजन उल्लंघन से संक्षिप्त) को आपत्तिजनक प्रक्रिया के लिए भेजा जाता है। [[Microsoft Windows|माइक्रोसॉफ़्ट विंडोज़]] पर, आपत्तिजनक प्रक्रिया को स्टेटस_एक्सेस_विओलेशन (STATUS_ACCESS_VIOLATION) अपवाद प्रबंधन प्राप्त होता है। | ऑपरेटिंग प्रणाली के स्तर पर, यह त्रुटि पकड़ी जाती है एवं उस सिग्नल के लिए प्रक्रिया के हैंडलर को सक्रिय करते हुए, आपत्तिजनक प्रक्रिया को संकेत दिया जाता है। भिन्न-भिन्न ऑपरेटिंग प्रणाली में भिन्न-भिन्न सिग्नल नाम होते हैं जो इंगित करते हैं कि विभाजन त्रुटि हुई है। यूनिक्स जैसे ऑपरेटिंग प्रणाली पर, SIGSEGV नामक सिग्नल (विभाजन उल्लंघन से संक्षिप्त) को आपत्तिजनक प्रक्रिया के लिए भेजा जाता है। [[Microsoft Windows|माइक्रोसॉफ़्ट विंडोज़]] पर, आपत्तिजनक प्रक्रिया को स्टेटस_एक्सेस_विओलेशन (STATUS_ACCESS_VIOLATION) अपवाद प्रबंधन प्राप्त होता है। | ||
== कारण == | == कारण == | ||
जिन परिस्थितियों में विभाजन का उल्लंघन होता है एवं वे स्वयं को कैसे प्रकट करते हैं, वे हार्डवेयर एवं ऑपरेटिंग प्रणाली के लिए विशिष्ट हैं। भिन्न-भिन्न हार्डवेयर दी गई प्रतिज्ञा के लिए भिन्न-भिन्न दोष उत्पन्न करते हैं, एवं भिन्न-भिन्न ऑपरेटिंग प्रणाली इन्हें भिन्न-भिन्न सिग्नल में परिवर्तित करते हैं जो प्रक्रियाओं पर पारित होते हैं। निकटस्थ कारण मेमोरी एक्सेस उल्लंघन है, जबकि अंतर्निहित कारण सामान्यतः किसी प्रकार का [[सॉफ्टवेयर बग]] है। [[मूल कारण विश्लेषण]] का निर्धारण - बग को डिबग करना - कुछ स्थितियों में सरल हो सकता है, जहां प्रोग्राम निरंतर विभाजन त्रुटि का कारण बनता है (उदाहरण के लिए, शून्य सूचक को संदर्भित करना), जबकि अन्य स्थितियों में बग को पुन: प्रस्तुत करना एवं प्रत्येक रन पर आवंटन | जिन परिस्थितियों में विभाजन का उल्लंघन होता है एवं वे स्वयं को कैसे प्रकट करते हैं, वे हार्डवेयर एवं ऑपरेटिंग प्रणाली के लिए विशिष्ट हैं। भिन्न-भिन्न हार्डवेयर दी गई प्रतिज्ञा के लिए भिन्न-भिन्न दोष उत्पन्न करते हैं, एवं भिन्न-भिन्न ऑपरेटिंग प्रणाली इन्हें भिन्न-भिन्न सिग्नल में परिवर्तित करते हैं जो प्रक्रियाओं पर पारित होते हैं। निकटस्थ कारण मेमोरी एक्सेस उल्लंघन है, जबकि अंतर्निहित कारण सामान्यतः किसी प्रकार का [[सॉफ्टवेयर बग]] है। [[मूल कारण विश्लेषण]] का निर्धारण - बग को डिबग करना - कुछ स्थितियों में सरल हो सकता है, जहां प्रोग्राम निरंतर विभाजन त्रुटि का कारण बनता है (उदाहरण के लिए, शून्य सूचक को संदर्भित करना), जबकि अन्य स्थितियों में बग को पुन: प्रस्तुत करना एवं प्रत्येक रन पर आवंटन मेमोरी पर निर्भर करना कठिन हो सकता है (उदाहरण के लिए, झूलने वाले सूचक को संदर्भित करना)। | ||
विभाजन दोष के कुछ विशिष्ट कारण निम्नलिखित हैं: | विभाजन दोष के कुछ विशिष्ट कारण निम्नलिखित हैं: | ||
* गैर-उपस्थित | * गैर-उपस्थित मेमोरी पते तक पहुँचने का प्रयास (प्रक्रिया के पता स्थान के बाहर) करता है। | ||
* | * मेमोरी तक पहुँचने का प्रयास करने का कार्यक्रम के पास अधिकार नहीं है (जैसे कि प्रक्रिया के संदर्भ में कर्नेल संरचनाएँ)। | ||
* रीड-ओनली मेमोरी (जैसे कोड खंड) लिखने का प्रयास करता है। | * रीड-ओनली मेमोरी (जैसे कोड खंड) लिखने का प्रयास करता है। | ||
ये परिवर्तन में प्रायः प्रोग्रामिंग त्रुटियों के कारण होते हैं, जिसके परिणाम स्वरूप अमान्य मेमोरी एक्सेस होती है। | ये परिवर्तन में प्रायः प्रोग्रामिंग त्रुटियों के कारण होते हैं, जिसके परिणाम स्वरूप अमान्य मेमोरी एक्सेस होती है। | ||
* अशक्त सूचक को संदर्भित करना, जो सामान्यतः ऐसे पते की ओर संकेत करता है जो प्रक्रिया के स्थान का भाग नहीं है। | * अशक्त सूचक को संदर्भित करना, जो सामान्यतः ऐसे पते की ओर संकेत करता है जो प्रक्रिया के स्थान का भाग नहीं है। | ||
* गैर-प्रारंभिक सूचक ([[जंगली सूचक]], जो यादृच्छिक | * गैर-प्रारंभिक सूचक ([[जंगली सूचक]], जो यादृच्छिक मेमोरी पते को इंगित करता है) को संदर्भित या असाइन करना है | ||
* फ्रीड सूचक को डिफ्रेंसिंग या असाइन करना (झूलने वाला सूचक, जो उस मेमोरी को इंगित करता है जिसे मुक्त/डिलीट किया गया है)। | * फ्रीड सूचक को डिफ्रेंसिंग या असाइन करना (झूलने वाला सूचक, जो उस मेमोरी को इंगित करता है जिसे मुक्त/डिलीट किया गया है)। | ||
* बफर | * बफर अधिकता | ||
* [[ स्टैक ओवरफ़्लो |ढेर | * [[ स्टैक ओवरफ़्लो |ढेर अधिकता]] | ||
* ऐसे प्रोग्राम को निष्पादित करने का प्रयास करना जो उचित रूप से संकलित नहीं होता है। | * ऐसे प्रोग्राम को निष्पादित करने का प्रयास करना जो उचित रूप से संकलित नहीं होता है। | ||
C कोड में, विभाजन दोष प्रायः सूचक उपयोग में त्रुटियों के कारण होते हैं, विशेष रूप से [[सी गतिशील स्मृति आवंटन|C गतिशील | C कोड में, विभाजन दोष प्रायः सूचक उपयोग में त्रुटियों के कारण होते हैं, विशेष रूप से [[सी गतिशील स्मृति आवंटन|C गतिशील मेमोरी आवंटन]] में अशक्त सूचक को संदर्भित करना, जिसके परिणाम स्वरूप [[अपरिभाषित व्यवहार]] होता है, सामान्यतः विभाजन दोष का कारण होगा। ऐसा इसलिए है, क्योंकि शून्य सूचक वैध मेमोरी पता नहीं हो सकता है। दूसरी ओर, वाइल्ड सूचक्स एवं डैंगलिंग सूचक्स उस मेमोरी की ओर संकेत देते हैं जो उपस्थित हो भी सकती है एवं नहीं भी, एवं पढ़ने योग्य या लिखने योग्य हो भी सकती है एवं नहीं भी, एवं इस प्रकार क्षणिक बग का परिणाम हो सकता है। उदाहरण के लिए: | ||
<syntaxhighlight lang=c> | <syntaxhighlight lang=c> | ||
char *p1 = NULL; // Null pointer | char *p1 = NULL; // Null pointer | ||
Line 49: | Line 43: | ||
इनमें से किसी भी चर को अपनिर्देशन करने से विभाजन दोष हो सकता है। नल सूचक को अपनिर्देशन करने से सामान्यतः सेगदोष होता है, जबकि वाइल्ड सूचक से पढ़ने के अतिरिक्त यादृच्छिक डेटा हो सकता है, किन्तु कोई सेगदोष नहीं होता है, एवं डैंगलिंग सूचक से पढ़ने के परिणाम स्वरूप वैध डेटा हो सकता है। एवं यादृच्छिक डेटा, क्योंकि यह अधिलेखित किया गया है। | इनमें से किसी भी चर को अपनिर्देशन करने से विभाजन दोष हो सकता है। नल सूचक को अपनिर्देशन करने से सामान्यतः सेगदोष होता है, जबकि वाइल्ड सूचक से पढ़ने के अतिरिक्त यादृच्छिक डेटा हो सकता है, किन्तु कोई सेगदोष नहीं होता है, एवं डैंगलिंग सूचक से पढ़ने के परिणाम स्वरूप वैध डेटा हो सकता है। एवं यादृच्छिक डेटा, क्योंकि यह अधिलेखित किया गया है। | ||
== | == संचालन करना == | ||
विभाजन त्रुटि या बस त्रुटि के लिए डिफ़ॉल्ट क्रिया उस प्रक्रिया की असामान्य समाप्ति है जिसने इसे ट्रिगर किया। डिबगिंग में सहायता के लिए | विभाजन त्रुटि या बस त्रुटि के लिए डिफ़ॉल्ट क्रिया उस प्रक्रिया की असामान्य समाप्ति है जिसने इसे ट्रिगर किया। डिबगिंग में सहायता के लिए [[कोर फ़ाइल]] उत्पन्न की जा सकती है, एवं अन्य प्लेटफ़ॉर्म-निर्भर क्रियाएं भी की जा सकती हैं। उदाहरण के लिए, ग्रसिक्युरिटी पैच का उपयोग करने वाले [[लिनक्स]] प्रणाली बफर अधिकता का उपयोग करके संभावित हस्तक्षेप के प्रयासों की निरिक्षण के लिए SIGSEGV संकेतों को लॉग कर सकते हैं। | ||
कुछ प्रणालियों पर, जैसे कि लिनक्स एवं विंडोज, यह संभव है कि कार्यक्रम स्वयं | कुछ प्रणालियों पर, जैसे कि लिनक्स एवं विंडोज, यह संभव है कि कार्यक्रम स्वयं विभाजन दोष को संभाले।<ref>{{Cite web|url=https://feepingcreature.github.io/handling.html|title=Cleanly recovering from Segfaults under Windows and Linux (32-bit, x86)|access-date=2020-08-23}}</ref> आर्किटेक्चर एवं ऑपरेटिंग प्रणाली के आधार पर, रनिंग प्रोग्राम न केवल ईवेंट को नियंत्रण कर सकता है, इसकी स्थिति के विषय में कुछ जानकारी निकाल सकता है जैसे [[स्टैक ट्रेस]] प्राप्त करना, [[प्रोसेसर रजिस्टर]] मान, स्रोत कोड की लाइन जब इसे ट्रिगर किया गया था, मेमोरी एड्रेस जो था अमान्य रूप से एक्सेस किया गया<ref>{{Cite web|url=https://github.com/vmarkovtsev/DeathHandler|title=Implementation of the SIGSEGV/SIGABRT handler which prints the debug stack trace.|website=[[GitHub]]|access-date=2020-08-23}}</ref> एवं क्या कार्रवाई पढ़ी गई या लिखी गई थी।<ref>{{Cite web|url=https://stackoverflow.com/questions/17671869/how-to-identify-read-or-write-operations-of-page-fault-when-using-sigaction-hand|title=How to identify read or write operations of page fault when using sigaction handler on SIGSEGV?(LINUX)|access-date=2020-08-23}}</ref> चूंकि विभाजन त्रुटि का सामान्यतः अर्थ है कि प्रोग्राम में बग है जिसे ठीक करने की आवश्यकता है, ऐसी विफलता का कारण परीक्षण, डिबगिंग एवं प्लेटफॉर्म का अनुकरण करना भी संभव है, जहां मेमोरी तक सीधी पहुंच की आवश्यकता है। पश्चात के विषय में, प्रणाली को त्रुटि होने के पश्चात भी प्रोग्राम को चलाने की अनुमति देने में सक्षम होना चाहिए। इस विषय में, जब प्रणाली अनुमति देता है, तो घटना को संभालना एवं निष्पादन निरंतर रखने के लिए असफल निर्देश के लिए प्रोसेसर प्रोग्राम काउंटर को बढ़ाना संभव होता है।<ref>{{Cite web|url=https://devarea.com/linux-writing-fault-handlers/|title=LINUX – WRITING FAULT HANDLERS|access-date=2020-08-23}}</ref> | ||
चूंकि | |||
Line 61: | Line 54: | ||
=== रीड ओनली मेमोरी में लिखना === | === रीड ओनली मेमोरी में लिखना === | ||
रीड-ओनली मेमोरी में लिखने से विभाजन दोष होता है। कोड त्रुटियों के स्तर पर, यह तब होता है जब प्रोग्राम | रीड-ओनली मेमोरी में लिखने से विभाजन दोष होता है। कोड त्रुटियों के स्तर पर, यह तब होता है जब प्रोग्राम स्वयं के कोड खंड या डेटा खंड के रीड-ओनली भाग को लिखता है, क्योंकि ये OS द्वारा रीड-ओनली मेमोरी में लोड किए जाते हैं। | ||
यहां [[एएनएसआई सी]] कोड का | यहां [[एएनएसआई सी]] (ANSI C) कोड का उदाहरण दिया गया है जो सामान्यतः मेमोरी सुरक्षा वाले प्लेटफॉर्म पर विभाजन त्रुटि का कारण बनता है। यह स्ट्रिंग शाब्दिक को संशोधित करने का प्रयास करता है, जो एएनएसआई सी मानक के अनुसार अपरिभाषित व्यवहार है। अधिकांश [[ संकलक ]] इसे संकलित समय पर नहीं पकड़ेंगे, एवं इसके अतिरिक्त इसे निष्पादन योग्य कोड में संकलित करेंगे जो ध्वंस (क्रैश) हो जाएगा। | ||
<syntaxhighlight lang=c> | <syntaxhighlight lang=c> | ||
Line 72: | Line 65: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
जब इस कोड वाले प्रोग्राम को संकलित किया जाता है, तो स्ट्रिंग हैलो वर्ल्ड को प्रोग्राम | जब इस कोड वाले प्रोग्राम को संकलित किया जाता है, तो स्ट्रिंग हैलो वर्ल्ड को प्रोग्राम निष्पादनीय फ़ाइल के रोडाटा खंड में रखा जाता है। डेटा खंड का केवल-पढ़ने के लिए खंड जब लोड किया जाता है, तो ऑपरेटिंग प्रणाली इसे अन्य स्ट्रिंग्स एवं निरंतर (प्रोग्रामिंग) डेटा के साथ मेमोरी के केवल-पढ़ने के लिए खंड में रखता है। जब निष्पादित किया जाता है, तो चर, s, स्ट्रिंग के स्थान को इंगित करने के लिए उपसमुच्चय किया जाता है, एवं चर के माध्यम से मेमोरी में H वर्ण लिखने का प्रयास किया जाता है, जिससे विभाजन दोष उत्पन्न होता है। ऐसे प्रोग्राम को संकलक के साथ संकलित करना जो संकलन समय पर केवल-पढ़ने के लिए स्थानों के कार्यभार का परिक्षण नहीं करता है, एवं इसे यूनिक्स-जैसे ऑपरेटिंग प्रणाली पर चलाने से निम्न [[रनटाइम त्रुटि]] उत्पन्न होती है। | ||
<syntaxhighlight lang="console"> | <syntaxhighlight lang="console"> | ||
Line 79: | Line 72: | ||
Segmentation fault | Segmentation fault | ||
</syntaxhighlight> | </syntaxhighlight> | ||
[[जीडीबी]] से कोर फ़ाइल का [[पश्व-अनुरेखन]]: | [[जीडीबी]] (GDB) से कोर फ़ाइल का [[पश्व-अनुरेखन]]: | ||
<syntaxhighlight lang=c> | <syntaxhighlight lang=c> | ||
Line 86: | Line 79: | ||
6 *s = 'H'; | 6 *s = 'H'; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
इस कोड को वर्ण सूचक के | इस कोड को वर्ण सूचक के अतिरिक्त सरणी का उपयोग करके सही किया जा सकता है, क्योंकि यह ढेर पर मेमोरी आवंटित करता है एवं इसे स्ट्रिंग अक्षर के मान में प्रारंभ करता है। | ||
<syntaxhighlight lang=c> | <syntaxhighlight lang=c> | ||
char s[] = "hello world"; | char s[] = "hello world"; | ||
s[0] = 'H'; // equivalently, *s = 'H'; | s[0] = 'H'; // equivalently, *s = 'H'; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
स्ट्रिंग अक्षर को संशोधित नहीं किया जाना चाहिए (यह C मानक में अपरिभाषित व्यवहार है), C में वे हैं <code>static char []</code> प्रकार,<ref>{{cite book|title=ISO/IEC 9899:1990 - Programming languages -- C|section=6.1.4 String literals}}</ref><ref>{{cite book|title=ISO/IEC 9899:1999 - Programming languages -- C|section=6.4.5 String literals}}</ref><ref>{{cite book|title=ISO/IEC 9899:2011 - Programming languages -- C|section=6.4.5 String literals|url=http://www.iso-9899.info/n1570.html#6.4.5p6}}</ref> इसलिए मूल कोड में कोई निहित रूपांतरण नहीं है (जो इंगित करता है a <code>char *</code> उस सरणी में), जबकि C ++ में वे हैं <code>static const char []</code> प्रकार, एवं इस प्रकार निहित रूपांतरण होता है, इसलिए संकलक सामान्यतः इस विशेष त्रुटि को पकड़ लेते है। | |||
=== अशक्त सूचक | === अशक्त सूचक डिरेफरेंस === | ||
C एवं C-जैसी भाषाओं में, अशक्त संकेतको का उपयोग बिना किसी वस्तु के संकेतक एवं त्रुटि संकेतक के रूप में किया जाता है, एवं अशक्त सूचक (अशक्त सूचक के माध्यम से पढ़ना या लिखना) को संदर्भित करना अधिक ही सामान्य कार्यक्रम त्रुटि है। C मानक यह नहीं कहता है कि शून्य सूचक [[स्मृति पता|मेमोरी पता]] 0 के सूचक के समान है, चूंकि व्यवहार में ऐसा हो सकता है। अधिकांश ऑपरेटिंग प्रणाली नल सूचक के एड्रेस को इस प्रकार से मैप करते हैं कि इसे एक्सेस करने से विभाजन त्रुटि हो जाती है। सी मानक द्वारा इस व्यवहार का आश्वासन नहीं है। अशक्त सूचक को संदर्भित करना C में अपरिभाषित व्यवहार है, एवं अनुरूप कार्यान्वयन को यह मानने की अनुमति है कि कोई भी सूचक जो अशक्त है, अशक्त नहीं है। | |||
<syntaxhighlight lang=c> | <syntaxhighlight lang=c> | ||
Line 100: | Line 93: | ||
printf("%d", *ptr); | printf("%d", *ptr); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
यह | यह मानक कोड शून्य सूचक बनाता है, एवं इसके मान तक पहुँचने का प्रयास करता है (मान पढ़ें)। ऐसा करने से कई ऑपरेटिंग प्रणाली पर रनटाइम में विभाजन त्रुटि हो जाती है। अशक्त सूचक को विस्थापित करना एवं तत्पश्चात उसे निर्दिष्ट करना ( गैर-उपस्थित लक्ष्य के लिए मान लिखना) भी सामान्यतः विभाजन दोष का कारण बनता है।<syntaxhighlight lang=c> | ||
<syntaxhighlight lang=c> | |||
int *ptr = NULL; | int *ptr = NULL; | ||
*ptr = 1; | *ptr = 1; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
निम्नलिखित कोड में | निम्नलिखित कोड में नल सूचक डिरेफरेंस सम्मिलित है, किन्तु जब संकलित किया जाता है तो प्रायः विभाजन त्रुटि नहीं होती है, क्योंकि मूल्य अप्रयुक्त होता है एवं इस प्रकार डीरेफरेंस को प्रायः [[मृत कोड उन्मूलन]] द्वारा अनुकूलित किया जाएगा। | ||
<syntaxhighlight lang=c> | <syntaxhighlight lang=c> | ||
int *ptr = NULL; | int *ptr = NULL; | ||
Line 114: | Line 104: | ||
=== बफर | === बफर अधिकता === | ||
{{Main| | {{Main|बफ़र अधिकता}} | ||
निम्न कोड वर्ण सरणी तक पहुँचता है <code>s</code> इसकी ऊपरी सीमा से | निम्न कोड वर्ण सरणी तक पहुँचता है,<code>s</code> इसकी ऊपरी सीमा से भिन्न संकलक एवं प्रोसेसर के आधार पर, इसका परिणाम विभाजन दोष हो सकता है। | ||
<syntaxhighlight lang=c> | <syntaxhighlight lang=c> | ||
char s[] = "hello world"; | char s[] = "hello world"; | ||
Line 124: | Line 114: | ||
=== | === स्टैक अधिकता === | ||
{{Main| | {{Main|स्टैक अधिकता}} | ||
आधार | |||
आधार विषय के बिना उदाहरण [[प्रत्यावर्तन]] है। | |||
<syntaxhighlight lang="c"> | <syntaxhighlight lang="c"> | ||
Line 134: | Line 125: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
जो [[ स्टैक ओवरफ़्लो ]] का कारण बनता है जिसके | जो [[ स्टैक ओवरफ़्लो | स्टैक अधिकता]] का कारण बनता है, जिसके परिणाम स्वरूप विभाजन त्रुटि होती है।<ref>[https://stackoverflow.com/questions/2685413/what-is-the-difference-between-a-segmentation-fault-and-a-stack-overflow/2685434#2685434 What is the difference between a segmentation fault and a stack overflow?] at [[Stack Overflow]]</ref> भाषा, संकलक द्वारा किए गए अनुकूलन एवं कोड की स्थिर संरचना के आधार पर अनंत पुनरावर्तन आवश्यक रूप से स्टैक अधिकता का परिणाम नहीं हो सकता है। इस विषय में, अगम्य कोड (रिटर्न स्टेटमेंट) का व्यवहार अपरिभाषित है, इसलिए संकलक इसे समाप्त कर सकता है एवं [[टेल कॉल]] अनुकूलन का उपयोग कर सकता है जिसके परिणाम स्वरूप कोई स्टैक उपयोग नहीं हो सकता है। अन्य अनुकूलन में पुनरावर्तन को पुनरावृत्ति में अनुवाद करना सम्मिलित हो सकता है, जो उदाहरण फ़ंक्शन की संरचना को देखते हुए प्रोग्राम को सदैव के लिए चलाने में परिणाम देगा, जबकि संभवतः इसके ढेर को अतिप्रवाह नहीं करेगा। | ||
== यह भी देखें == | == यह भी देखें == | ||
Line 146: | Line 137: | ||
==बाहरी संबंध== | ==बाहरी संबंध== | ||
* [https://www.encious.com/process Process: focus boundary and segmentation fault]{{dead link|date=July 2022}} | * [https://www.encious.com/process Process: focus boundary and segmentation fault]{{dead link|date=July 2022}} | ||
* [http://www.faqs.org/qa/qa-673.html A FAQ: User contributed answers regarding the definition of a segmentation fault] | * [http://www.faqs.org/qa/qa-673.html A FAQ: User contributed answers regarding the definition of a segmentation fault] | ||
Line 153: | Line 143: | ||
* [http://www.opengroup.org/onlinepubs/009695399/basedefs/signal.h.html The Open Group Base Specifications Issue 6 signal.h] | * [http://www.opengroup.org/onlinepubs/009695399/basedefs/signal.h.html The Open Group Base Specifications Issue 6 signal.h] | ||
[[Category:All articles with dead external links]] | |||
[[Category:Articles with dead external links from July 2022]] | |||
[[Category: | [[Category:Articles with hatnote templates targeting a nonexistent page]] | ||
[[Category:CS1 English-language sources (en)]] | |||
[[Category:Collapse templates]] | |||
[[Category: | |||
[[Category:Created On 26/04/2023]] | [[Category:Created On 26/04/2023]] | ||
[[Category:Lua-based templates]] | |||
[[Category:Machine Translated Page]] | |||
[[Category:Missing redirects]] | |||
[[Category:Navigational boxes| ]] | |||
[[Category:Navigational boxes without horizontal lists]] | |||
[[Category:Pages with broken file links]] | |||
[[Category:Pages with script errors]] | |||
[[Category:Sidebars with styles needing conversion]] | |||
[[Category:Template documentation pages|Documentation/doc]] | |||
[[Category:Templates Vigyan Ready]] | |||
[[Category:Templates generating microformats]] | |||
[[Category:Templates that add a tracking category]] | |||
[[Category:Templates that are not mobile friendly]] | |||
[[Category:Templates that generate short descriptions]] | |||
[[Category:Templates using TemplateData]] | |||
[[Category:Wikipedia metatemplates]] | |||
[[Category:उदाहरण सी कोड वाले लेख]] | |||
[[Category:कंप्यूटर त्रुटियां]] | |||
[[Category:स्मृति प्रबंधन]] |
Latest revision as of 15:12, 30 October 2023
कम्प्यूटिंग में, विभाजन दोष या एक्सेस उल्लंघन दोष (कंप्यूटिंग), या विफलता की स्थिति है, जो मेमोरी सुरक्षा के साथ हार्डवेयर द्वारा उठाया जाता है, ऑपरेटिंग प्रणाली (OS) को सूचित करता है, सॉफ्टवेयर ने प्रतिबंधित क्षेत्र तक पहुंचने का प्रयास किया है। मेमोरी ( मेमोरी एक्सेस उल्लंघन) मानक x86 कंप्यूटरों पर, यह सामान्य सुरक्षा दोष का रूप है। ऑपरेटिंग प्रणाली आधार, प्रतिक्रिया में, सामान्यतः कुछ सुधारात्मक कार्रवाई करता है, सामान्यतः प्रक्रिया को संकेत (कंप्यूटिंग) भेजकर त्रुटि को आपत्तिजनक प्रक्रिया (कंप्यूटिंग) पर भेज देता है। प्रक्रियाएं कुछ स्थितियों में कस्टम सिग्नल हैंडलर स्थापित कर सकती हैं, जिससे उन्हें स्वयं ठीक होने की अनुमति मिलती है,[1] अन्यथा ओएस डिफ़ॉल्ट सिग्नल हैंडलर का उपयोग किया जाता है, सामान्यतः प्रक्रिया की असामान्य समाप्ति (प्रोग्राम क्रैश (कंप्यूटिंग)), एवं कभी-कभी कोर निपात होता है।
विभाजन दोष C (प्रोग्रामिंग भाषा) जैसी भाषाओं में लिखे गए प्रोग्रामों में त्रुटि का सामान्य वर्ग है जो निम्न-स्तरीय मेमोरी एक्सेस प्रदान करता है एवं कोई सुरक्षा निरिक्षण नहीं करता है। वे मुख्य रूप से आभासी मेमोरी एड्रेसिंग के लिए सूचक (कंप्यूटर प्रोग्रामिंग) के उपयोग में त्रुटियों के कारण उत्पन्न होते हैं, विशेष रूप से अवैध पहुंच के कारण अन्य प्रकार की मेमोरी एक्सेस त्रुटि बस त्रुटि है, जिसके विभिन्न कारण भी हैं, किन्तु वर्तमान में यह अधिक दुर्लभ है; ये मुख्य रूप से गलत भौतिक मेमोरी एड्रेसिंग के कारण होते हैं, या गलत प्रविधि से मेमोरी एक्सेस के कारण होते हैं, ये ऐसे मेमोरी संदर्भ होते हैं जिन्हें हार्डवेयर एड्रेस नहीं कर सकता है, उन रेफरेंस के जिन्हें एड्रेस करने की अनुमति नहीं होती है।
कई प्रोग्रामिंग भाषा विभाजन दोषों से बचने एवं मेमोरी सुरक्षा में सुधार के लिए चित्रित किए गए तंत्रों को नियोजित कर सकती हैं। उदाहरण के लिए, जंग (प्रोग्रामिंग भाषा) स्वामित्व आधारित को नियोजित करता है।[2] मेमोरी सुरक्षा सुनिश्चित करने के लिए प्रतिरूप[3] अन्य भाषाएँ, जैसे कि लिस्प (प्रोग्रामिंग भाषा) एवं जावा (प्रोग्रामिंग भाषा), जंक संग्रह (कंप्यूटर विज्ञान) को नियोजित करती हैं,[4] जो मेमोरी त्रुटियों के कुछ वर्गों से बचती है, जिससे विभाजन दोष हो सकते हैं।[5]
सिंहावलोकन
विभाजन दोष तब होता है जब कोई प्रोग्राम मेमोरी स्थान तक पहुंचने का प्रयास करता है जिसे एक्सेस करने की अनुमति नहीं है, या किसी मेमोरी स्थान मेंइस प्रकार प्रवेश करने का प्रयास करता है, जिसकी अनुमति नहीं है (उदाहरण के लिए, रीड ओनली मेमोरी में लिखने का प्रयास केवल पढ़ने योग्य स्थान, या ऑपरेटिंग प्रणाली के भाग को ओवरराइट करने के लिए)।
शब्द विभाजन के कंप्यूटिंग में विभिन्न उपयोग हैं; विभाजन दोष के संदर्भ में, 1950 के दशक से उपयोग किया जाने वाला शब्द, यह किसी प्रोग्राम के एड्रेस स्पेस को संदर्भित करता है।[6] मेमोरी सुरक्षा के साथ, केवल प्रोग्राम का स्वयं का स्थान ही पढ़ने योग्य होता है, एवं इसमें से केवल कॉल स्टैक एवं प्रोग्राम के डेटा खंड के लिखने योग्य होता है, जबकि केवल पढ़ने के लिए डेटा एवं कोड खंड लिखने योग्य नहीं होते हैं। इस प्रकार प्रोग्राम के एड्रेस स्पेस के बाहर पढ़ने का प्रयास, या एड्रेस स्पेस के केवल पढ़ने के लिए खंड में लिखने से विभाजन दोष होता है।
वर्चुअल मेमोरी प्रदान करने के लिए हार्डवेयर मेमोरी विभाजन का उपयोग करने वाले प्रणाली पर, विभाजन त्रुटि तब होती है जब हार्डवेयर गैर-उपस्थित खंड को संदर्भित करने का प्रयास करता है, डेटा खंड की सीमाओं के बाहर किसी स्थान को संदर्भित करता है। उस खंड के लिए दी गई अनुमतियों द्वारा केवल पेजिंग का उपयोग करने वाले प्रणाली पर, अमान्य पृष्ठ दोष सामान्यतः विभाजन दोष की ओर जाता है, एवं विभाजन दोष एवं पृष्ठ दोष दोनों ही वर्चुअल मेमोरी मैनेजमेंट प्रणाली द्वारा उठाए गए दोष हैं। विभाजन दोष पृष्ठ दोषों से स्वतंत्र रूप से भी हो सकते हैं। वैध पृष्ठ तक अवैध पहुंच विभाजन त्रुटि है, किन्तु अमान्य पृष्ठ त्रुटि नहीं है, एवं विभाजन दोष पृष्ठ के मध्य में हो सकते हैं (इसलिए कोई पृष्ठ त्रुटि नहीं है), उदाहरण के लिए बफ़र अधिकता जो पृष्ठ के अंदर रहता है किन्तु अवैध रूप से मेमोरी को अधिलेखित कर देता है।
हार्डवेयर स्तर पर, मेमोरी प्रबंधन इकाई (MMU) द्वारा अवैध पहुंच (यदि संदर्भित मेमोरी उपस्थित है) द्वारा इसकी मेमोरी सुरक्षा सुविधा के भाग के रूप में, या अमान्य पृष्ठ दोष (यदि संदर्भित मेमोरी उपस्थित नहीं है) द्वारा प्रारम्भ में त्रुटि उठाई जाती है। यदि समस्या अमान्य तार्किक पता नहीं है जबकि अमान्य भौतिक पता है, तो इसके अतिरिक्त बस त्रुटि उठाई जाती है, चूंकि ये सदैव भिन्न नहीं होते हैं।
ऑपरेटिंग प्रणाली के स्तर पर, यह त्रुटि पकड़ी जाती है एवं उस सिग्नल के लिए प्रक्रिया के हैंडलर को सक्रिय करते हुए, आपत्तिजनक प्रक्रिया को संकेत दिया जाता है। भिन्न-भिन्न ऑपरेटिंग प्रणाली में भिन्न-भिन्न सिग्नल नाम होते हैं जो इंगित करते हैं कि विभाजन त्रुटि हुई है। यूनिक्स जैसे ऑपरेटिंग प्रणाली पर, SIGSEGV नामक सिग्नल (विभाजन उल्लंघन से संक्षिप्त) को आपत्तिजनक प्रक्रिया के लिए भेजा जाता है। माइक्रोसॉफ़्ट विंडोज़ पर, आपत्तिजनक प्रक्रिया को स्टेटस_एक्सेस_विओलेशन (STATUS_ACCESS_VIOLATION) अपवाद प्रबंधन प्राप्त होता है।
कारण
जिन परिस्थितियों में विभाजन का उल्लंघन होता है एवं वे स्वयं को कैसे प्रकट करते हैं, वे हार्डवेयर एवं ऑपरेटिंग प्रणाली के लिए विशिष्ट हैं। भिन्न-भिन्न हार्डवेयर दी गई प्रतिज्ञा के लिए भिन्न-भिन्न दोष उत्पन्न करते हैं, एवं भिन्न-भिन्न ऑपरेटिंग प्रणाली इन्हें भिन्न-भिन्न सिग्नल में परिवर्तित करते हैं जो प्रक्रियाओं पर पारित होते हैं। निकटस्थ कारण मेमोरी एक्सेस उल्लंघन है, जबकि अंतर्निहित कारण सामान्यतः किसी प्रकार का सॉफ्टवेयर बग है। मूल कारण विश्लेषण का निर्धारण - बग को डिबग करना - कुछ स्थितियों में सरल हो सकता है, जहां प्रोग्राम निरंतर विभाजन त्रुटि का कारण बनता है (उदाहरण के लिए, शून्य सूचक को संदर्भित करना), जबकि अन्य स्थितियों में बग को पुन: प्रस्तुत करना एवं प्रत्येक रन पर आवंटन मेमोरी पर निर्भर करना कठिन हो सकता है (उदाहरण के लिए, झूलने वाले सूचक को संदर्भित करना)।
विभाजन दोष के कुछ विशिष्ट कारण निम्नलिखित हैं:
- गैर-उपस्थित मेमोरी पते तक पहुँचने का प्रयास (प्रक्रिया के पता स्थान के बाहर) करता है।
- मेमोरी तक पहुँचने का प्रयास करने का कार्यक्रम के पास अधिकार नहीं है (जैसे कि प्रक्रिया के संदर्भ में कर्नेल संरचनाएँ)।
- रीड-ओनली मेमोरी (जैसे कोड खंड) लिखने का प्रयास करता है।
ये परिवर्तन में प्रायः प्रोग्रामिंग त्रुटियों के कारण होते हैं, जिसके परिणाम स्वरूप अमान्य मेमोरी एक्सेस होती है।
- अशक्त सूचक को संदर्भित करना, जो सामान्यतः ऐसे पते की ओर संकेत करता है जो प्रक्रिया के स्थान का भाग नहीं है।
- गैर-प्रारंभिक सूचक (जंगली सूचक, जो यादृच्छिक मेमोरी पते को इंगित करता है) को संदर्भित या असाइन करना है
- फ्रीड सूचक को डिफ्रेंसिंग या असाइन करना (झूलने वाला सूचक, जो उस मेमोरी को इंगित करता है जिसे मुक्त/डिलीट किया गया है)।
- बफर अधिकता
- ढेर अधिकता
- ऐसे प्रोग्राम को निष्पादित करने का प्रयास करना जो उचित रूप से संकलित नहीं होता है।
C कोड में, विभाजन दोष प्रायः सूचक उपयोग में त्रुटियों के कारण होते हैं, विशेष रूप से C गतिशील मेमोरी आवंटन में अशक्त सूचक को संदर्भित करना, जिसके परिणाम स्वरूप अपरिभाषित व्यवहार होता है, सामान्यतः विभाजन दोष का कारण होगा। ऐसा इसलिए है, क्योंकि शून्य सूचक वैध मेमोरी पता नहीं हो सकता है। दूसरी ओर, वाइल्ड सूचक्स एवं डैंगलिंग सूचक्स उस मेमोरी की ओर संकेत देते हैं जो उपस्थित हो भी सकती है एवं नहीं भी, एवं पढ़ने योग्य या लिखने योग्य हो भी सकती है एवं नहीं भी, एवं इस प्रकार क्षणिक बग का परिणाम हो सकता है। उदाहरण के लिए:
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 द्वारा रीड-ओनली मेमोरी में लोड किए जाते हैं।
यहां एएनएसआई सी (ANSI C) कोड का उदाहरण दिया गया है जो सामान्यतः मेमोरी सुरक्षा वाले प्लेटफॉर्म पर विभाजन त्रुटि का कारण बनता है। यह स्ट्रिंग शाब्दिक को संशोधित करने का प्रयास करता है, जो एएनएसआई सी मानक के अनुसार अपरिभाषित व्यवहार है। अधिकांश संकलक इसे संकलित समय पर नहीं पकड़ेंगे, एवं इसके अतिरिक्त इसे निष्पादन योग्य कोड में संकलित करेंगे जो ध्वंस (क्रैश) हो जाएगा।
int main(void)
{
char *s = "hello world";
*s = 'H';
}
जब इस कोड वाले प्रोग्राम को संकलित किया जाता है, तो स्ट्रिंग हैलो वर्ल्ड को प्रोग्राम निष्पादनीय फ़ाइल के रोडाटा खंड में रखा जाता है। डेटा खंड का केवल-पढ़ने के लिए खंड जब लोड किया जाता है, तो ऑपरेटिंग प्रणाली इसे अन्य स्ट्रिंग्स एवं निरंतर (प्रोग्रामिंग) डेटा के साथ मेमोरी के केवल-पढ़ने के लिए खंड में रखता है। जब निष्पादित किया जाता है, तो चर, s, स्ट्रिंग के स्थान को इंगित करने के लिए उपसमुच्चय किया जाता है, एवं चर के माध्यम से मेमोरी में H वर्ण लिखने का प्रयास किया जाता है, जिससे विभाजन दोष उत्पन्न होता है। ऐसे प्रोग्राम को संकलक के साथ संकलित करना जो संकलन समय पर केवल-पढ़ने के लिए स्थानों के कार्यभार का परिक्षण नहीं करता है, एवं इसे यूनिक्स-जैसे ऑपरेटिंग प्रणाली पर चलाने से निम्न रनटाइम त्रुटि उत्पन्न होती है।
$ gcc segfault.c -g -o segfault
$ ./segfault
Segmentation fault
जीडीबी (GDB) से कोर फ़ाइल का पश्व-अनुरेखन:
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';
स्ट्रिंग अक्षर को संशोधित नहीं किया जाना चाहिए (यह C मानक में अपरिभाषित व्यवहार है), C में वे हैं static char []
प्रकार,[11][12][13] इसलिए मूल कोड में कोई निहित रूपांतरण नहीं है (जो इंगित करता है a char *
उस सरणी में), जबकि C ++ में वे हैं static const char []
प्रकार, एवं इस प्रकार निहित रूपांतरण होता है, इसलिए संकलक सामान्यतः इस विशेष त्रुटि को पकड़ लेते है।
अशक्त सूचक डिरेफरेंस
C एवं C-जैसी भाषाओं में, अशक्त संकेतको का उपयोग बिना किसी वस्तु के संकेतक एवं त्रुटि संकेतक के रूप में किया जाता है, एवं अशक्त सूचक (अशक्त सूचक के माध्यम से पढ़ना या लिखना) को संदर्भित करना अधिक ही सामान्य कार्यक्रम त्रुटि है। C मानक यह नहीं कहता है कि शून्य सूचक मेमोरी पता 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