2012-10-15 8 views
5

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

इस के लिए कोई समाधान?

उत्तर

-1

ऐसी फ़ाइल तक नहीं पहुंचें जो उपलब्ध नहीं है। जांचें कि फ़ाइल अभी भी है, या ऐसी फ़ाइल का उपयोग करें जिसे अनमाउंट नहीं किया जा सकता है।

+4

मुझे नहीं लगता कि संभावित दौड़ की स्थिति के कारण यह बहुत उपयोगी है। क्या मैप किए गए क्षेत्र तक पहुंचने वाले कोड के आस-पास 'सिगबुस' की अपेक्षा करने और पकड़ने में मदद मिलेगी? या कुछ समान है? –

+1

संख्या 'सिगबुस' जरूरी नहीं है, हालांकि कुछ कार्यान्वयन हैंडलर से लौटने के बाद दोषपूर्ण निर्देश को पुनः प्रयास करते हैं। –

+0

@ सिमॉन रिचटर आपको दोषपूर्ण निर्देश को पुनः प्रयास करने की आवश्यकता नहीं है, आपको केवल यह निर्धारित करने की आवश्यकता है कि आप एक पठन/लिखने के साथ आगे बढ़ नहीं सकते हैं, जिसके बाद आप इस क्षेत्र तक पहुंचने का प्रयास बंद कर देते हैं और कुछ त्रुटि संकेत के साथ कॉलर पर वापस आते हैं। शायद 'setjmp() '/' longjmp() 'दोषपूर्ण निर्देश के पुन: निष्पादन से बचने में सक्षम होगा। –

2

सिग्नल हैंडलर सेट करना सबसे आसान बात यह है कि mmap एड पते के अनुरूप स्मृति स्थानों तक पहुंच की जांच होगी।

आप संकेत संचालकों की sigaction फार्म का उपयोग होता है, बल्कि सरल signal संचालकों से sigaction संचालकों struct __siginfo * पैरामीटर संकेत के पते के लिए इसी में जानकारी प्राप्त करते हैं। यह देखने के लिए जांच की जा सकती है कि यह mmap एड फ़ाइल की पता सीमा के भीतर है या नहीं।

mmap बहुत अच्छा है जब आप डेटा के बफर पढ़ने/लिखने की जटिलताओं से निपटना नहीं चाहते हैं, लेकिन कुछ गलत होने के कारण आपको केवल एक ही त्रुटि (सिग्नल) मिलती है। read/write तंत्र के साथ, आप errno प्राप्त कर सकते हैं और यह निर्धारित कर सकते हैं कि क्या हुआ। इस मामले में यह एक डेवलपर पसंद है।

संकेत प्राप्त करने के बाद एक स्थान पर जाने के लिए तो आप setjmp और longjmp/siglongjmp के उपयोग करने की आवश्यकता होगी -, मैं कहना है इस करना चाहिए चाहते हैं में this question

6

सबसे पहले इस बात का कुछ उपयोग देख का उपयोग न करने के लिएmmap अनावश्यक रूप से "अनुकूलित पढ़ने" या समान के रूप में उपयोग न करें। डिवाइस हटाने के अलावा, अन्य प्रक्रियाओं द्वारा फ़ाइल छंटनी जैसे मुद्दों SIGBUS के साथ गलती तक पहुंच सकते हैं।

यदि आपको वास्तव में mmap का उपयोग करने की आवश्यकता है, तो आप SIGBUS के लिए सिग्नल हैंडलर इंस्टॉल कर सकते हैं। अपने कार्य को मूल रूप से किया जाना चाहिए करने के लिए:

  1. एक वैश्विक (या धागे की स्थानीय, यदि आपके प्रोग्राम मल्टी-थ्रेडेड है) ध्वज को SIGBUS हुआ सेट करें, ताकि दोषयुक्त कोड के बारे में पता हो सकता है।
  2. mmapMAP_FIXED पर दोषपूर्ण पृष्ठ के शीर्ष पर एक नया अनाम पृष्ठ मैप करने के लिए कॉल करें। वैकल्पिक रूप से इसे डेटा से भरें जो मानचित्र को गलती के रूप में एक्सेस करने वाले कोड द्वारा पहचाना जाएगा; यह चरण 1 अनावश्यक बना सकता है।

एक वैकल्पिक दृष्टिकोण स्थापित करने के लिए किया जाएगा एक वैश्विक (या धागे की स्थानीय) jmp_buf नक्शा एक्सेस करने से पहले, और सिग्नल हैंडलर बस longjmp फोन है।

नोट है कि न तो mmap है और न ही longjmp async-संकेत सुरक्षित है, लेकिन सवाल में SIGBUS एक अतुल्यकालिक संकेत हालांकि यह शायद एक विचार किया जाना चाहिए अगर दोषयुक्त पहुँच एक गैर async-संकेत सुरक्षित पुस्तकालय के अन्दर नहीं हुआ है (कार्य sscanf)। जब तक यह आपका स्वयं का कोड है, और लाइब्रेरी फ़ंक्शन नहीं, मानचित्र तक पहुंचने के लिए, आपको या तो सुरक्षित होना चाहिए। और mmap अधिकांश/सभी वास्तविक-दुनिया कार्यान्वयन में एसिंक-सिग्नल-सुरक्षित है, इसलिए आपको औपचारिक रूप से सही नहीं होने पर भी अभ्यास में पहले समाधान के साथ ठीक होना चाहिए।

+2

क्या यह वाक्यांश इस तरह होगा: आंखों की तुलना में 'mmap' के लिए और भी है - क्योंकि पारंपरिक हैंडलिंग पारंपरिक I/O के मुकाबले कहीं अधिक जटिल है। यह जरूरी नहीं है कि _against__mmap' का उपयोग करें ... केवल उन आत्माओं से अवगत रहें जिन्हें आप बुलाते हैं ;-) –

+0

और सुनिश्चित करें कि वे आपकी नाक से बाहर नहीं निकलते हैं .. :-) –

-1

आप http://linux.die.net/man/7/inotify का उपयोग कर फ़ाइल (ओं), डीआईआर (ओं) पर किसी भी बदलाव के बारे में अधिसूचना प्राप्त कर सकते हैं। आप IN_DELETE का उपयोग करने पर विचार कर सकते हैं।

+3

क्या ये अधिसूचना तत्काल होगी पृष्ठ के दोष के रूप में ओपी को रोकने की कोशिश कर रहा है? यदि नहीं, परेशान मत करो। –

+0

ऐसा प्रतीत होता है कि आपको कोई परिवर्तन होने पर पता लगाने के लिए 'read() 'को कॉल करना होगा, लेकिन' read()' रुचि के कुछ भी नहीं लौटने और निम्नलिखित मेमोरी एक्सेस के बीच परिवर्तन हो सकते हैं। यह दौड़ की स्थिति है। इसके अलावा, घटना कतार अतिप्रवाह हो सकता है। तो, यह एक समाधान नहीं है। –

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