2012-09-19 22 views
5

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

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

और तीसरा क्यों स्टैक नीचे बढ़ता है और ऊपर की ओर ढेर करता है। क्या यह प्रक्रिया सभी ओएस के साथ समान है। यह प्रदर्शन को कैसे प्रभावित करता है। हम इसे अन्य तरीकों से क्यों नहीं ले सकते?

कृपया मुझे सही करें, अगर मैं किसी भी कथन में गलत हूं।

धन्यवाद सोहराब

+0

कोई प्रोग्रामिंग प्रश्न नहीं है। – unwind

उत्तर

1

जब कोई प्रक्रिया शुरू होती है तो उसे अपना वर्चुअल एड्रेस स्पेस मिलता है। वर्चुअल एड्रेस स्पेस का आकार आपके ऑपरेटिंग सिस्टम पर निर्भर करता है। सामान्य 32 बिट प्रक्रियाओं में 4 जीआईबी (4 गीगा बाइनरी) पते प्राप्त होते हैं और 64 बिट प्रक्रियाओं को 18 ईआईबी (18 एक्सा बाइनरी) पते मिलते हैं।

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

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

पता स्थान का कितना उपयोग किया जा रहा है और एप्लिकेशन चलाने के दौरान मैप किए गए परिवर्तनों में कितना परिवर्तन होता है। ऑपरेटिंग सिस्टम विशिष्ट उपकरण आपको मॉनीटर करने के लिए वर्तमान में आवंटित स्मृति और वर्चुअल एड्रेस स्पेस की निगरानी करने की अनुमति देंगे।

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

ढेर का आकार (कम से कम प्रारंभिक ढेर) आमतौर पर तय किया जाता है। कंपाइलर्स और/या लिंकर्स में आमतौर पर कुछ झंडे होते हैं जिन्हें आप रनटाइम पर इच्छित स्टैक के आकार को सेट करने के लिए उपयोग कर सकते हैं। आम तौर पर ढेर "पिछड़ा हो जाते हैं" क्योंकि प्रोसेसर स्टैक निर्देशों का काम करता है। ढेर एक दिशा में बढ़ने के साथ-साथ दूसरे में बढ़ने से परिस्थितियों में स्मृति को व्यवस्थित करना आसान हो जाता है जहां आप दोनों को असहज होना चाहते हैं लेकिन यह नहीं पता कि प्रत्येक कितना बढ़ सकता है।

सामान्य रूप से हीप, उस प्रक्रिया को संदर्भित करता है जो प्रक्रिया शुरू होने पर पूर्व-आवंटित नहीं होता है। निम्नतम स्तर पर कई लॉजिकल ऑपरेशंस हैं जो ढेर प्रबंधन से संबंधित हैं (सभी को लागू नहीं किया गया है क्योंकि मैं यहां सभी ऑपरेटिंग सिस्टमों में वर्णन करता हूं)।

जबकि पता स्थान तय किया गया है, कुछ ओएस ट्रैक करते हैं कि वर्तमान में कौन से हिस्सों को इस प्रक्रिया द्वारा पुनः दावा किया गया है। यहां तक ​​कि यदि यह मामला नहीं है, तो प्रक्रिया को स्वयं ही इसका ट्रैक रखने की आवश्यकता है। तो निम्नतम स्तर का संचालन वास्तव में यह तय करना है कि पता स्थान का एक निश्चित क्षेत्र उपयोग किया जा रहा है।

दूसरा निम्न स्तर का ऑपरेशन ओएस को उस क्षेत्र को किसी चीज़ पर मैप करने का निर्देश देना है।सामान्य रूप में यह

  • कुछ स्मृति जाता है कि swappable नहीं

  • स्मृति कि swappable और प्रणाली स्वैप फ़ाइल

  • स्मृति कि swappable है को मैप किया और कुछ अन्य फ़ाइल

    को मैप किया है हो सकता है
  • मेमोरी जो स्वीकार्य है और कुछ अन्य फाइलों को मैप किया गया है केवल पढ़ने के लिए मोड

  • ही मानचित्रण है कि एक और आभासी पते क्षेत्र

  • ही मानचित्रण है कि एक और आभासी पता क्षेत्र के लिए मैप किया गया है करने के लिए मैप किया गया है, लेकिन में केवल पढ़ने के लिए मोड

  • ही मानचित्रण है कि एक और आभासी पता क्षेत्र के लिए मैप किया गया है , लेकिन डिफॉल्ट स्वैप फ़ाइल को मैप किया प्रतिलिपित डेटा से राइट मोड पर नकल में

वहाँ अन्य संयोजन मैं भूल गया हो सकता है, लेकिन जो मुख्य हैं।

बेशक कुल स्थान का उपयोग वास्तव में इस पर निर्भर करता है कि आप इसे कैसे परिभाषित करते हैं। वर्तमान में उपयोग की जाने वाली रैम वर्तमान में मैप किए गए पता स्थान से अलग है। लेकिन जैसा कि मैंने उपरोक्त लिखा है, ऑपरेटिंग सिस्टम निर्भर उपकरण आपको वर्तमान में क्या हो रहा है यह पता लगाने देना चाहिए।

1

वर्गों निष्पादन योग्य फ़ाइल द्वारा पूर्व निर्धारित कर रहे हैं।

इसके अलावा, कोई भी गतिशील रूप से जुड़े पुस्तकालयों में से हो सकता है। एक DLL का कोड और निरंतर डेटा का उपयोग कर कई प्रक्रियाओं भर में साझा करने के लिए और एक बार से अधिक नहीं गिना जाता है, वहीं इसकी प्रक्रिया विशेष गैर निरंतर डेटा हर प्रक्रिया में लिए जिम्मेदार होना चाहिए।

इसके अलावा, प्रक्रिया में गतिशील रूप से आवंटित स्मृति हो सकती है।

आगे, यदि प्रक्रिया में कई धागे हैं, तो उनमें से प्रत्येक का अपना ढेर होगा।

और क्या है, प्रक्रिया में प्रति-थ्रेड, प्रति-प्रक्रिया और प्रति-लाइब्रेरी डेटा संरचनाएं और कर्नेल में इसकी ओर से (थ्रेड-लोकल स्टोरेज, कमांड लाइन पैरा, विभिन्न संसाधनों को संभालने के लिए, , उन संसाधनों के लिए संरचनाएं और साथ ही बहुत आगे)।

यह जानते हुए भी सब कुछ कैसे कार्यान्वित किया जाता है के बिना वास्तव में पूरी प्रक्रिया को आकार की गणना करने के लिए मुश्किल है। हालांकि, आपको एक उचित अनुमान मिल सकता है।

W.r.t. According to my understanding when some buffer overflows happens then the address gets corrupted. यह जरूरी नहीं है कि यह सच है। सबसे पहले, क्या पता है? यह बफर के पास स्मृति में क्या होता है इस पर निर्भर करता है। यदि कोई पता है, तो यह बफर ओवरफ़्लो के दौरान अधिलेखित हो सकता है। लेकिन वहाँ एक और बफर अगर है कि आसपास आप की एक तस्वीर है, तस्वीर के पिक्सल अधिलेखित हो सकता है।

आप जब स्मृति जिसके लिए आप आवश्यक अनुमति नहीं है तक पहुँचने का प्रयास विभाजन या पेज दोष प्राप्त कर सकते हैं (उदाहरण के लिए कर्नेल भाग कि मैप किया गया है या अन्यथा प्रक्रिया पता स्थान में से अब तक)। या यह केवल पढ़ने के लिए स्थान हो सकता है। या स्थान भौतिक स्मृति में कोई मैपिंग नहीं हो सकता है।

यह कहना मुश्किल है कि ढेर और ढेर का स्थान और लेआउट प्रदर्शन के बारे में जानने के बिना प्रदर्शन को प्रभावित करने जा रहा है। आप अनुमान लगा सकते हैं, लेकिन अटकलें गलत हो सकती हैं।

बीटीडब्ल्यू, आपको वास्तव में अलग-अलग मुद्दों के लिए SO पर अलग-अलग प्रश्न पूछने पर विचार करना चाहिए।

+0

धन्यवाद ... मैं अगली बार इसे ध्यान में रखूंगा ...: -) ... स्पष्टीकरण के लिए धन्यवाद। –

1

"किसी मेमोरी को एक्सेस करने की प्रक्रिया के लिए यह कैसे संभव है जो इसके पता स्थान में नहीं है?"

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

char *p = "some string"; 

while (*p++ != 256) /* Always true. Keeps incrementing p until segfault. */ 
    ; 

इस तरह की सरल त्रुटियों को कम करने के लिए अनदेखा नहीं किया जाता है।

+1

इसे "litotes" कहा जाता है। :) – Mehrdad

+0

धन्यवाद! मैं इस तरह की शब्दावली सीखने से पूरी तरह नफरत नहीं करता :-) – Jens

0

मैं प्रश्न # 2 और # 3 का जवाब दे सकता हूं।

उत्तर # 2

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

उदाहरण के लिए इस परिदृश्य पर विचार करें: आपका ओएस आपकी प्रक्रिया को 0x01000 से 0x09000 तक देता है। तब

int * ptr = 0x01000; 
printf("%d", ptr[0]); // * prints 4 bytes (sizeof(int) bytes) of your address space 
int * ptr = 0x09100; 
printf("%d", ptr[0]); // * You are accessing out of your space: segfault 

अधिकतर segfault के कारणों, जैसा कि आप ने कहा, शून्य की ओर इशारा के उपयोग कर रहे हैं (जो अधिकतर 0x00 पता है, लेकिन कार्यान्वयन निर्भर) या भ्रष्ट पतों का उपयोग।

ध्यान दें कि, लिनक्स i386 पर, आधार और सीमा रजिस्टर का उपयोग नहीं किया जा सकता है जैसा कि आप सोच सकते हैं। वे प्रति-प्रक्रिया सीमाएं नहीं हैं लेकिन वे दो प्रकार के सेगमेंट इंगित करते हैं: उपयोगकर्ता स्थान या कर्नेल स्पेस।

उत्तर # 3

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

फुटनोट

एक आधुनिक ओएस में, एक प्रक्रिया तथाकथित तर्क पता उपयोग करता है। यह पता ओएस द्वारा भौतिक पते के साथ मैप किया गया है।

#include <stdio.h> 

int main() 
{ 
    int a = 10; 
    printf("%p\n", &a); 
    return 0; 
} 

आप इस कार्यक्रम को कई बार (यहां तक ​​कि एक साथ) आप, देखना होगा यहां तक ​​कि विभिन्न उदाहरणों के लिए चलाते हैं, एक ही पते मुद्रित: इस खुद के संकलन इस बस प्रोग्राम का एक नोट है। बेशक यह वास्तविक स्मृति पता नहीं है, लेकिन यह एक तार्किक पता है जिसे आवश्यक होने पर भौतिक पते पर मैप किया जाएगा।

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