2012-03-07 23 views
6

स्पष्ट होने के लिए, यह एक कार्यान्वयन प्रश्नसीगफॉल्ट भेजने की बजाय सिस्टम कॉल EFAULT क्यों लौटाता है?

के बजाय एक डिज़ाइन है, मैं इस बारे में तर्क जानना चाहता हूं कि क्यों POSIX इस तरह से व्यवहार करता है। POSIX सिस्टम कॉल करता है जब अमान्य मेमोरी लोकेशन दिया जाता है EFAULT को उपयोगकर्तास्पेस प्रोग्राम को क्रैश करने के बजाय (sigsegv भेजकर), जो उनके व्यवहार को उपयोगकर्ता स्पेस फ़ंक्शंस के साथ असंगत बनाता है।

क्यों? क्या यह सिर्फ स्मृति कीड़े को छिपाता नहीं है? क्या यह एक ऐतिहासिक गलती है या इसके लिए कोई अच्छा कारण है?

+0

/sigbus अधिक भावना भी कर (लिनक्स जो साख से पहले वास्तविक नकल कर रही है की जाँच करता है इस के लिए एक copy_to_user_space समारोह (और इसके विपरीत), है)। अभी मैं 2 कस्टम सिस्कोल के साथ खेल रहा हूं जिसमें उपयोगकर्ताओं (धीमे) उपयोगकर्ताओं के इम्यूलेशन भी हो सकते हैं। मैं नहीं देखता कि वास्तविक सिस्कल और अनुकरण को अलग-अलग व्यवहार क्यों करना चाहिए यदि वे अमान्य बफर पास कर चुके हैं। यहां तक ​​कि POSIX भी ओपियनियन का प्रतीत होता है कि उपयोगकर्ताओं को यह ध्यान रखना नहीं चाहिए कि सिस्टम फ़ंक्शन एक वास्तविक सिस्कोल या उपयोगकर्ता स्पेस फ़ंक्शन है या नहीं। मेरा संबंधित प्रश्न: https: //stackoverflow.com/questions/44239545/generating-segfault-from-a-custom-syscall/44251112 – PSkocik

उत्तर

2

क्योंकि सिस्टम कॉल कर्नेल द्वारा निष्पादित किया जाता है, उपयोगकर्ता प्रोग्राम द्वारा नहीं - जब सिस्टम कॉल होता है, तो उपयोगकर्ता प्रक्रिया रोकती है और कर्नेल को समाप्त करने की प्रतीक्षा करती है।

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

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

संक्षेप में: अधिकतर ऐतिहासिक, लेकिन तर्क के लिए वास्तविक तर्क है। EINTR की तरह, यह इससे निपटने के लिए कोई भी परेशान नहीं करता है।

+1

सिग्नल में 'सार्थक प्रोग्राम काउंटर संलग्न करें' से आपका क्या मतलब है? आपका मतलब है कि यह नहीं पता होगा कि उपयोगकर्ता के सिग्नल हैंडलर को निष्पादित करने के बाद फिर से शुरू करना है? क्या यह सिस्टम कॉल के ठीक बाद नहीं होगा? –

+0

हां, फिर से शुरू करने के बारे में थोड़ा अनदेखा करें --- इसके बारे में कुछ और सोचना, यह वास्तव में प्रासंगिक नहीं है। (क्योंकि अगर कर्नेल एक सीजी गलती को फिक्र कर रहा है, तो यह आसानी से रजिस्टर स्थिति को नकली कर सकता है।) मुझे लगता है कि यहां मुख्य मुद्दा यह है: कर्नेल आपको एक सीईजी गलती नहीं भेज रहा है क्योंकि _no seg fault वास्तव में हुआ है। –

2

ठीक है, आप क्या होगा होने के लिए। एक सिस्टम कॉल सिस्टम के लिए एक अनुरोध है। यदि आप पूछते हैं: "मुन्चेन को नौका कब छोड़ती है?" क्या आप प्रोग्राम को क्रैश करना चाहते हैं, या वापसी = -1 को errno = ENOHARBOR के साथ प्राप्त करना चाहते हैं? यदि आप अपनी कार को अपने हैंडबैग में रखने के लिए sytem से पूछते हैं, तो क्या आप अपने हैंडबैग को नष्ट करना चाहते हैं, या +1 की वापसी EBAGTOOSMALL पर सेट की गई है?

एक तकनीकी विवरण है: syscalls से पहले या बाद में, सिस्टम कॉल में प्रवेश/छोड़ते समय उपयोगकर्ता/सिस्टम-फ़्रैंड से/तर्कों को परिवर्तित (प्रतिलिपि) किया जाना चाहिए। ज्यादातर सुरक्षा कारणों से सिस्टम उपयोगकर्ता-स्थान में लिखने में बहुत अनिच्छुक है। मेरे लिए एक SIGSEGV

+1

मैं पहले से ही कहता हूं कि प्रश्न में अधिक समझदारी होगी - ऐप को एक सेगफॉल्ट सिग्नल भेजना। –

+0

आह शायद, मैंने आपके प्रश्न को गलत समझा।एक * तकनीकी * समस्या है copyfromuser(), copytouser() (linux case में) कर्नेल-मोड से निष्पादित की जाती है, इसलिए जांच को कर्नेल द्वारा "मैन्युअल रूप से" निष्पादित किया जाना चाहिए, कोई सेग संभव नहीं है, कर्नेल * आपके लिए यह प्रतिलिपि कर सकता है। तो औपचारिक रूप से, यह एक सेगमेंटेशन उल्लंघन नहीं है (यह * होगा, यदि उपयोगकर्ता स्पेस से किया गया हो) इसके अलावा: उपयोगकर्ता प्रक्रिया के दृश्य से, एक सिस्कल वापसी मूल्य के साथ केवल एक कार्य है। सिग्नल कुछ एसिंक्रोनस घटना का प्रतिनिधित्व करना चाहिए। – wildplasser