2017-09-16 9 views
6

हिस्सों में बंटा हुआ ढेर कैसे काम करते हैं? यह प्रश्न Boost.Coroutine पर भी लागू होता है, इसलिए मैं यहां सी ++ टैग का उपयोग कर रहा हूं। मुख्य संदेह इस article यह वे क्या ढेर के नीचे कुछ जगह रखने के लिए और जाँच अगर यह स्मृति वहाँ आवंटित संकेत हैंडलर किसी प्रकार का पंजीकरण करके भ्रष्ट हो गया है है की तरह लग रहा से आता है (शायद mmap और mprotect के माध्यम से?) और फिर जब वे पता लगाते हैं कि वे अंतरिक्ष से बाहर हो गए हैं तो वे अधिक स्मृति आवंटित करते हैं और फिर वहां से जारी रखते हैं। इसकैसे करते हिस्सों में बंटा हुआ ढेर काम

  1. इस उपयोगकर्ता के बारे में 3 प्रश्न नहीं है? वे कैसे नियंत्रित करते हैं कि नया स्टैक आवंटित किया जाता है और इसके बारे में जागरूक होने के लिए कार्यक्रम को कैसे संकलित किया जाता है?

    एक पुश निर्देश मूल रूप से केवल स्टैक पॉइंटर में एक मान जोड़ रहा है और फिर स्टैक पर एक रजिस्टर में मूल्य संग्रहीत कर रहा है, तो पुश निर्देश कैसे पता चल सकता है कि नया स्टैक कहां शुरू होता है और संगत रूप से पॉप कैसे जान सकता है जब इसे स्टैक पॉइंटर को पुराने स्टैक पर ले जाना होता है?

  2. उन्होंने यह भी कहते हैं कि

    हम एक नया स्टैक खंड मिल गया है के बाद, हम goroutine समारोह है कि ढेर

    से बाहर चलाने के लिए इसका क्या मतलब है हमें वजह से पुन: प्रारंभ पुन: प्रयास करने से ? क्या वे पूरे गोराउटिन को पुनरारंभ करते हैं? क्या यह संभवतः गैर निर्धारक व्यवहार नहीं करेगा?

  3. वे कैसे पता लगाता है कि कार्यक्रम ढेर लंघन है करते हैं? यदि वे नीचे कैनरी-आइश मेमोरी एरिया रखते हैं तो क्या होता है जब उपयोगकर्ता प्रोग्राम एक सरणी बनाता है जो उस पर बहती है? क्या इससे स्टैक ओवरफ़्लो नहीं हो सकता है और यह एक संभावित सुरक्षा भेद्यता है?

कार्यान्वयन जाओ के लिए अलग हैं और बूस्ट मुझे पता है कि कैसे उनमें से या तो इस स्थिति

+2

संस्करण 1.3 – tkausl

+0

@tkausl हम्म में संगत स्टैक्स का उपयोग करना शुरू करें .. बस इसके बारे में पढ़ें और यह निश्चित रूप से ऐसा कुछ लगता है जिसके लिए भाषा से समर्थन की आवश्यकता होगी, और Boost.Coroutine जैसी लाइब्रेरी के रूप में कार्यान्वित करना कठिन होगा। सही? संगत स्टैक दृष्टिकोण को समझना आसान लगता है हालांकि – Curious

+0

@ क्रूर: हाँ इसे भाषा समर्थन की आवश्यकता है - गो के पास एक अलग स्टैक लेआउट है और सी/सी ++ से सम्मेलन कॉलिंग है। – JimB

उत्तर

5

मैं तुम्हें एक संभावित क्रियान्वयन की एक त्वरित स्केच दे देंगे से निपटने के लिए खुश होगी।

पहले, मान सबसे ढेर फ्रेम कुछ आकार की तुलना में छोटे होते हैं। जो बड़े हैं, उनके लिए हम पर्याप्त स्टैक स्पेस सुनिश्चित करने के लिए प्रवेश पर लंबे निर्देश अनुक्रम का उपयोग कर सकते हैं। आइए मान लीजिए कि हम एक आर्किटेक्चर पर हैं जिसमें 4k पेज हैं और हम तेज़ पथ द्वारा संभाले गए अधिकतम आकार के स्टैक फ्रेम के रूप में 4k-1 चुन रहे हैं।

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

संकेत हैंडलर (या समतुल्य) निर्धारित करने के लिए यह निर्देश है कि गलती और पता इसे करने के लिए लिख रहा था की पता से एक ढेर विस्तार गलती है में सक्षम हो गया है। यह निर्धारित है क्योंकि निर्देश किसी फ़ंक्शन के प्रस्ताव में है और वर्तमान थ्रेड के लिए स्टैक के गार्ड पेज में लिखा गया पता है। प्रोलॉग में होने वाले निर्देशों को कार्यों की शुरुआत में निर्देशों के एक बहुत ही विशिष्ट पैटर्न की आवश्यकता होती है, या संभवतः कार्यों के बारे में मेटाडेटा को बनाए रखना।(संभवतः ट्रेसबैक टेबल का उपयोग करना।)

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

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

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

गो वास्तव में सही ढंग से समझने पर गार्ड पेज का उपयोग नहीं करता है। इसके बजाय फ़ंक्शन प्रोलॉग स्पष्ट रूप से स्टैक सीमा की जांच करता है और यदि नया स्टैक फ्रेम फिट नहीं होगा तो यह स्टैक को बढ़ाने के लिए एक फ़ंक्शन को कॉल करता है।

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

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

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

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

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