2010-03-30 12 views
8

एक स्टैक मेमोरी युक्त डेटा का एक संगत ब्लॉक है। एक रजिस्टर स्टैक पॉइंटर (एसपी) अंक स्टैक के शीर्ष पर बुलाया जाता है। स्टैक के नीचे एक निश्चित पते पर है।ढेर के नीचे कैसे निर्धारित किया जाता है?

स्टैक नीचे कर्नेल द्वारा तय किया गया है?

उत्तर

1

यह ढेर के कार्यान्वयन का हिस्सा होगा। यदि आप (उदाहरण के लिए) सी में एक स्टैक लागू कर रहे हैं, तो आप स्टैक पॉइंटर और तत्वों की वर्तमान संख्या को स्टोर कर सकते हैं। या ढेर के आधार है, की तरह कुछ के साथ ढेर सूचक:

typedef struct { 
    int *sp_empty; 
    int *sp; 
    int *sp_full; 
} tIntStack; 

tIntStack stk; 

// Initialise 20-element stack. 
stk.sp = stk.sp_empty = malloc (sizeof(int) * 20); 
stk.sp_full = &(stack[20]); 

// Push a value x, detecting overflow.  
if (stk.sp == stk.sp_full) { error here} 
*(stk.sp) = x; 
stk.sp++; 

// Pop a value x, detecting underflow.  
if (stk.sp == stk.sp_empty) { error here} 
stk.sp--; 
x = *(stk.sp); 

आप एक सीपीयू ढेर के बारे में बात कर रहे हैं (पते दिखा और आगे), आप इस तथ्य के आधार पर ढेर अधःप्रवाह पता लगा सकता है कि तुम दुर्घटनाग्रस्त हो बुरी तरह।


उदाहरण के लिए, पुराने दिनों में जब प्रोसेसर 64K पता स्थान तक ही सीमित थे, सीपीयू आम तौर पर परीक्षण किया स्मृति जब तक वे पहले बाइट कि बूट अप में (क्या सिर्फ लिखा गया था के रूप में ही पढ़ा नही पाया प्रक्रिया)। वास्तविक भौतिक स्मृति से परे पहला बाइट था, इसलिए उन्होंने एसपी को उसके नीचे एक सेट किया। बेशक, कुछ (छोटी संख्या में) मशीनें में भौतिक रैम का 64K था, इसलिए बस पता स्थान के शीर्ष पर एसपी सेट करें।

प्रक्रिया आजकल, विशाल-पता-अंतरिक्ष में, आभासी स्मृति, बहु-टास्किंग ऑपरेटिंग सिस्टम, एक छोटे से अधिक जटिल है लेकिन यह अभी भी करने पर निर्भर करता (अधिकांश मामलों में):

  • पता अंतरिक्ष एक प्रक्रिया के लिए आवंटित किया गया है।
  • एसपी उस पता स्थान में कहीं भी सेट है।
  • प्रक्रिया रन।

उस बिंदु पर, संभवतः आप कर्नेल के संबंध में अपने आप पर हैं। इसकी ज़िम्मेदारी उस बिंदु पर रुक जाती है जहां आपका कोड कार्य स्विचिंग के अलावा अन्य चल रहा है और अनुरोध के अनुसार सेवाएं प्रदान करता है, लेकिन यह आपके ढेर से कुछ लेना देना नहीं है। यदि आपका बग्गी कोड ढेर या बहती है, तो आपकी समस्या है।

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

+0

'अंडरफ्लो' से आपका क्या मतलब है, मैंने केवल 'अतिप्रवाह' के बारे में सुना है। – Mask

+0

अंडरफ्लो तब होता है जब आप खाली स्टैक के तत्व को पॉप करने का प्रयास करते हैं। अधिकांश प्रणालियों में, इसमें एक अनपेक्षित मेमोरी एड्रेस तक पहुंच शामिल होगी, जिसके परिणामस्वरूप सेगमेंटेशन गलती होगी। –

+0

सिर्फ 'झूठी' मान वापस करने के बजाय विभाजन विभाजन की आवश्यकता क्यों है? – Mask

6

मैं एक लंबे समय तक जवाब टाइप है, लेकिन यह rambled है, तो यहां एक छोटी एक ...

जब एक प्रक्रिया शुरू कर दी है, यह अस्थायी मूल्यों के भंडारण के उद्देश्य के लिए एक ढेर की जरूरत है (यानी स्वचालित आवंटन) है या कार्यों को बुलाए जाने पर फ्रेम ढेर करें। इस ढेर के लिए स्मृति कहीं से आना है।

तो ओएस क्या करता है स्टैक के लिए वर्चुअल मेमोरी में मैपिंग बना रहा है, और इस ब्लॉक के उच्च पते पर स्टैक पॉइंटर असाइन करें।एक पूर्ववर्ती ढेर में, जहां ड्रेफरेंसिंग से पहले स्टैक पॉइंटर कम हो जाता है, प्रारंभिक स्टैक पॉइंटर वास्तव में मैप किए गए स्थान के अंतिम पते से पता होता है।

जब प्रक्रिया स्टैक पर कुछ डालने की कोशिश करती है, तो इसके परिणामस्वरूप इस मेमोरी क्षेत्र तक पहुंच होती है, जिसमें कोई भौतिक रैम मैप नहीं होता है। यह पेज गलती का कारण बनता है, जिसके परिणामस्वरूप ओएस में स्वैप ड्राइव या पेज फ़ाइल में रैम के कम-से-कम (या इसके करीब) पृष्ठ को लात मारना पड़ता है, और भौतिक रैम पेज को स्टैक पेज पर एक्सेस किया जा रहा है। अब भौतिक RAM है, ओएस रिटर्न और प्रक्रिया जारी है, धक्का डेटा को ढेर स्मृति में डाल रहा है।

तो क्या होता है यदि आप स्टैक से सबकुछ पॉप करते हैं और फिर फिर से पॉप करने का प्रयास करते हैं? वह आखिरी पॉप, जहां स्टैक पॉइंटर अपने शुरुआती मूल्य पर है, परिणामस्वरूप वर्चुअल मेमोरी एड्रेस तक पहुंच है जो स्टैक पर मैप किया गया है। यह एक सेगमेंटेशन गलती का कारण बनता है, जिसका अर्थ है कि प्रक्रिया ने स्मृति को एक्सेस करने का प्रयास किया है, जिसे कभी आवंटित नहीं किया जाता है। ओएस प्रक्रिया को समाप्त करने और जो कुछ भी कर सकता है उसे साफ करके जवाब देता है।

स्टैक के अंत से पहले एक पृष्ठ को मानचित्र क्यों न करें? क्योंकि इसके परिणामस्वरूप अनियमित RAM पढ़ना होगा, जिसमें भौतिक RAM के उस पृष्ठ का उपयोग करने के लिए जो कुछ भी उपयोग किया जाता है। कोई रास्ता नहीं है यह एक सही तरीके से कार्य करने वाला प्रोग्राम (यह कहने के लिए कि यह एक बड़ा सुरक्षा जोखिम कैसे है) का उत्पादन कर सकता है, इसलिए कार्यक्रम को मारना अभी भी सबसे अच्छा है।

+0

अच्छा जवाब। मुझे यह देखना अच्छा लगेगा कि * लंबा * संस्करण क्या है। :-) –

+0

वर्चुअल मेमोरी अनिवार्य रूप से हार्ड डिस्क है, जो बहुत धीमी है, इसलिए मुझे लगता है कि यह केवल तभी उपयोग किया जाता है जब रैम पर्याप्त नहीं होता है, है ना? – Mask

+0

@ मास्क, वर्चुअल मेमोरी * नहीं * बस हार्ड डिस्क है। यह आपकी प्रक्रिया को देखता है और वास्तविक भौतिक स्मृति पता स्थान के बीच एक डिस्कनेक्ट है।आपके पास डिस्क पर स्वैपिंग या पेजिंग के बिना वर्चुअल मेमोरी हो सकती है, इस स्थिति में आपको स्थिति-स्वतंत्र कोड के बारे में चिंता करने की आवश्यकता नहीं है - आपको लगता है कि आपका कोड उसी स्मृति पते पर चलाएगा चाहे वह वास्तव में भौतिक स्मृति में कहां है। वर्चुअल मेमोरी के बिना आप पेजिंग भी कर सकते हैं यदि एकाधिक प्रक्रियाएं उसी पते का उपयोग करना चाहती हैं। – paxdiablo

0

मुझे लगता है कि आपका मतलब है "प्रक्रिया की स्मृति स्थान में तय", और "समग्र स्मृति में तय नहीं"। आप cat /proc/<pid-here>/maps के उत्पादन में तरह

bfbce000-bfbe3000 rw-p bffeb000 00:00 0   [stack] 

एक लाइन की खोज करके जहां ढेर नीचे किसी भी हाल ही में लिनक्स सिस्टम में है देख सकते हैं। ढेर के नीचे, इस मामले में, 0xbffeb000 पर है। मेरी प्रणाली में, सभी ढेर की बोतलें bffca000 bffcb000 bffdd000 bffe0000 bffe4000 bffe6000 bffeb000 (~ 200 प्रक्रियाओं के माध्यम से लूपिंग के बाद) में से एक में गिरती प्रतीत होती है।

मुझे लगता है कि इन मानों को कर्नेल में गहरा सौंपा गया है, जहां भी प्रक्रियाएं पहली बार बनाई गई हैं।

+0

मुझे लगता है कि स्टैक पते को यादृच्छिक रूप से कुछ यादृच्छिक रूप से काम करने के लिए स्टैक ओवरफ्लो शोषण के लिए कठिन बना दिया जाता है। –

+0

@ माइक मुझे मेमोरी-मैप किए गए पतों में कुछ प्रकार का यादृच्छिकरण चल रहा है, लेकिन अगर ढेर को यादृच्छिक रूप से याद किया जा रहा है, तो 200 नमूने से 7 मान वास्तव में बहुत ही खराब यादृच्छिकता है :-) – tucuxi

+0

अब आप इसका जिक्र करते हैं, यह सी 0000000 के करीब अंतरिक्ष में मैप किए जाने वाले कुछ और की तरह दिखता है और जिसमें एक असंगत आकार (54, 53, 35, 32, 28, 26, या 21 4k पेज) है। –

0

वास्तव में, ढेर के नीचे कुछ है। निम्नलिखित स्टैक के बाद, argv सरणी के तत्व हैं, फिर env सरणी के तत्व। उसके बाद एक बाधा है, फिर libc कोड।

संबंधित मुद्दे

 संबंधित मुद्दे