2012-01-15 7 views
15

कहें कि मेरे पास लिनक्स में एक एप्लिकेशन है जो साझा पुस्तकालयों का उपयोग करता है (.so फ़ाइलें)। मेरा सवाल यह है कि क्या उन पुस्तकालयों में कोड मुख्य आवेदन के रूप में एक ही ढेर में स्मृति आवंटित करेगा या क्या वे अपने ही ढेर का उपयोग करेंगे?क्या साझा पुस्तकालय आवेदन के समान हीप का उपयोग करते हैं?

तो उदाहरण के लिए, .so फ़ाइल में कुछ फ़ंक्शन malloc पर कॉल करते हैं, क्या यह उसी हीप मैनेजर को एप्लिकेशन या किसी अन्य के रूप में उपयोग करेगा? साथ ही, उन साझा यादों में वैश्विक डेटा के बारे में क्या। यह कहां झूठ बोलता है? मैं उस एप्लिकेशन के बारे में जानता हूं जो बीएसएस और डेटा सेगमेंट में है, लेकिन यह नहीं पता कि यह उन साझा ऑब्जेक्ट फ़ाइलों के लिए कहां है।

+0

क्या आप पूछ रहे हैं कि साझा लाइब्रेरी के अनुभाग मूल निष्पादन योग्य वर्गों के साथ गतिशील लिंकिंग के साथ एकत्र किए गए हैं या नहीं? –

+1

साझा लाइब्रेरी बीएसएस और डेटा सेगमेंट कुछ शेष एप्लिकेशन के बीएसएस और डेटा सेगमेंट को अलग कर देंगे, लेकिन यह सब आपके लिए सिस्टम द्वारा संभाला जाता है। –

उत्तर

25

मेरा सवाल यह है कि क्या उन पुस्तकालयों में कोड मुख्य आवेदन के समान हीप में स्मृति आवंटित करेगा या क्या वे अपने ही ढेर का उपयोग करेंगे?

पुस्तकालय आवेदन (glibc से उदा) के रूप में ही malloc/free का उपयोग करता है - तो हाँ, कार्यक्रम और सभी पुस्तकालयों एकल ढेर का उपयोग करेगा।

पुस्तकालय mmap सीधे का उपयोग करता है, यह स्मृति जो कार्यक्रम में ही द्वारा प्रयुक्त स्मृति नहीं है आवंटित कर सकते हैं।

तो उदाहरण के लिए, .so फ़ाइल में कुछ फ़ंक्शन malloc को कॉल करता है, क्या यह उसी हीप मैनेजर को एप्लिकेशन या किसी अन्य के रूप में उपयोग करेगा?

यदि .so कॉल मॉलोक से कार्य करता है, तो यह मॉलोक प्रोग्राम से बुलाए गए मॉलोक जैसा ही है। आप ढेर प्रबंधकों की

LD_DEBUG=bindings ./your_program 

हाँ, कई उदाहरण (डिफ़ॉल्ट विन्यास के साथ) के साथ/glibc (> 2.1) लिनक्स में लॉग बाध्यकारी प्रतीक देख सकते हैं (समस्या के साथ है एक दूसरे के बारे जानने के बिना नहीं साथ नहीं हो सकते उदाहरण के बीच सिंक्रनाइज़ किए गए ब्रैक-आवंटित ढेर आकार को रखते हुए)। लेकिन एक कॉन्फ़िगरेशन संभव है जब कई उदाहरण सह-अस्तित्व में हो सकते हैं।

अधिकांश क्लासिक मॉलोक कार्यान्वयन (ptmalloc *, dlmalloc, आदि) सिस्टम से स्मृति प्राप्त करने के दो तरीकों का उपयोग कर सकते हैं: brk और mmap। ब्रैक क्लासिक ढेर है, जो रैखिक है और बढ़ सकता है या सिकुड़ सकता है। एमएमएपी कहीं भी बहुत मेमोरी प्राप्त करने की अनुमति देता है; और आप किसी भी क्रम में इस स्मृति को सिस्टम (इसे मुक्त) पर वापस कर सकते हैं।

जब malloc builded है, नि: विधि निष्क्रिय किया जा सकता। फिर malloc केवल mmap एस का उपयोग करके रैखिक ढेर का अनुकरण करेगा या यहां तक ​​कि क्लासिक रैखिक ढेर को अक्षम कर देगा और सभी आवंटन को असम्बद्ध mmaped fragmens से बनाया जाएगा।

तो, कुछ पुस्तकालय में अपना मेमोरी मैनेजर हो सकता है, उदा। brk के साथ संकलित या गैर-मॉलोक मेमोरी मैनेजर के साथ संकलित। यह प्रबंधक उदाहरण के लिए, malloc और free के अलावा अन्य समारोह के नाम होना चाहिए malloc1 और free1 या/निर्यात गतिशील लिंकर को यह नाम नहीं दिखाने के लिए करना चाहिए।

साथ ही, उन साझा यादों में वैश्विक डेटा के बारे में क्या। यह कहां झूठ बोलता है?मैं उस एप्लिकेशन के बारे में जानता हूं जो बीएसएस और डेटा सेगमेंट में है, लेकिन यह नहीं पता कि यह उन साझा ऑब्जेक्ट फ़ाइलों के लिए कहां है।

आपको प्रोग्राम के बारे में सोचना चाहिए और साथ ही ईएलएफ फाइलों के बारे में भी सोचना चाहिए। प्रत्येक ईएलएफ फ़ाइल में "प्रोग्राम हेडर" (readelf -l elf_file) है। ईएलएफ से मेमोरी में डेटा लोड करने का तरीका प्रोग्राम हेडर के प्रकार पर निर्भर करता है। यदि प्रकार "LOAD" है, तो फ़ाइल का संबंधित भाग निजी रूप से mmap ed (Sic!) स्मृति में होगा। आमतौर पर, 2 लोड सेगमेंट होते हैं; आर + एक्स (पढ़ें + निष्पादित) झंडे के साथ कोड के लिए पहला और दूसरा आर + डब्ल्यू (पढ़ें + लिखें) झंडे वाले डेटा के लिए है। .bss और .data (वैश्विक डेटा) अनुभाग दोनों लिखें सक्षम ध्वज के साथ लोड लोड के खंड में रखा गया है।

दोनों निष्पादन योग्य और साझा लाइब्रेरी में लोड सेगमेंट हैं। कुछ खंडों में memory_size> file_size है। इसका मतलब है कि खंड स्मृति में विस्तारित किया जाएगा; यह के पहले भाग, ELF फ़ाइल, और आकार (memory_size-FILE_SIZE) के दूसरे भाग से डेटा शून्य (*bss के लिए वर्गों) से भर दिया जाएगा से भर दिया जाएगा mmap(/dev/zero) और memset(0)

जब कर्नेल या गतिशील लिंकर भार ELF का उपयोग कर स्मृति में फ़ाइल, वे साझा करने के बारे में नहीं सोचेंगे। उदाहरण के लिए, आप दो बार एक ही प्रोग्राम शुरू करना चाहते हैं। पहली प्रक्रिया एमएलएपी के साथ ईएलएफ फाइल के केवल पढ़ने के हिस्से को लोड करेगी; दूसरी प्रक्रिया एक ही एमएमएपी करेगी (यदि एएसएलआर सक्रिय है - दूसरा एमएमएपी अलग वर्चुअल एड्रेस में होगा)। यह भौतिक मेमोरी में डेटा की एक प्रतिलिपि रखने के लिए पेज कैश (वीएफएस उपप्रणाली) का कार्य है (COPY-on-WRITE उर्फ ​​गाय के साथ); और mmap बस प्रत्येक प्रक्रिया में वर्चुअल एड्रेस से मैपिंग्स को एक भौतिक स्थान में सेट करेगा। अगर कोई प्रक्रिया मेमोरी पेज बदल देगी; यह अद्वितीय निजी भौतिक स्मृति के लिए लिखने पर प्रतिलिपि बनाई जाएगी।

लोड हो रहा है कोड glibc/elf/dl-load.c (_dl_map_object_from_fd) ld.so के लिए और linux-kernel/fs/binfmt_elf.c में कर्नेल के ELF लोडर (elf_map, load_elf_binary) के लिए है। PT_LOAD के लिए एक खोज करें।

तो, वैश्विक डेटा और बीएसएस डेटा हमेशा प्रत्येक प्रक्रिया में निजी रूप से मिमी किया जाता है, और वे गाय से संरक्षित होते हैं।

ढेर और ढेर brk की तरह प्रक्रिया (मुख्य थ्रेड के ढेर के लिए) में नि: + mmap (ढेर) के साथ और पूर्ण रूप से अपने ओएस कर्नेल द्वारा चलाने के समय में आवंटित किए जाते हैं। अतिरिक्त थ्रेड के ढेर mmappthread_create में आवंटित किए जाते हैं।

+0

धन्यवाद, आपका उत्तर बहुत उपयोगी था। – MetallicPriest

+0

धातुकर्मी, किस भाग में यह अधिक सहायक था? – osgx

+0

osgx - दूसरा एक और सहायक था। – MetallicPriest

8

प्रतीक तालिकाएं लिनक्स में पूरी प्रक्रिया में साझा की जाती हैं। प्रक्रिया के किसी भी हिस्से के लिए malloc() अन्य सभी भागों के समान है। तो हाँ, अगर किसी प्रक्रिया के सभी हिस्सों में malloc() के माध्यम से ढेर तक पहुंच जाती है तो वे एक ही ढेर साझा करेंगे।

+0

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

+0

मॉलोक 'brk' और 'mmap' दोनों के माध्यम से स्मृति आवंटित कर सकता है। मॉलोक लाइब्रेरी का केवल एक उदाहरण ब्रैक के साथ मेमोरी प्रबंधित कर सकता है; लेकिन अगर कोई अन्य मॉलोक उदाहरण जुड़ा हुआ है, तो यह अलग ढेर का अनुकरण करने के लिए एमएमएपी का उपयोग कर सकता है। – osgx

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