2010-03-30 12 views
5

मेरा आवेदन डेटा लिखने की वांछित स्थिति खोजने के लिए lseek() का उपयोग करता है। फ़ाइल को open() का उपयोग करके सफलतापूर्वक खोला गया है और मेरा एप्लिकेशन lseek() और write() कई बार उपयोग करने में सक्षम था।lseek/लिखना अचानक रिटर्न -1 errno = 9 (खराब फ़ाइल वर्णनकर्ता)

एक भी समय, कुछ उपयोगकर्ताओं के लिए और आसानी से reproducable नहीं, lseek() रिटर्न -1 9. फ़ाइल के errno के साथ इस से पहले बंद नहीं है और filehandle (int) रीसेट नहीं कर रहा है।

इसके बाद, एक और फ़ाइल बनाई गई है; open() ठीक है और lseek() और write() फिर से काम करता है।

इसे और भी खराब बनाने के लिए, इस उपयोगकर्ता ने फिर से पूर्ण अनुक्रम की कोशिश की और सभी ठीक थे।

तो मेरा सवाल यह है कि क्या ओएस किसी कारण से मेरे लिए फाइल हैंडल बंद कर सकता है? इसका कारण क्या हो सकता है? किसी फ़ाइल इंडेक्सर या फ़ाइल स्कैनर किसी प्रकार का?

इसे हल करने का सबसे अच्छा तरीका क्या है; क्या यह छद्म कोड सबसे अच्छा समाधान है? कुछ इसी तरह के साथ

int fd=open(...); 
if (fd>-1) { 
    long result = lseek(fd,....); 
    if (result == -1 && errno==9) { 
     close(fd..); //make sure we try to close nicely 
     fd=open(...); 

     result = lseek(fd,....); 
    } 
} 

किसी अनुभव (कोड लेआउट, इसके लिए काम करता है पैदा करेगा कोई बात नहीं)?

सारांश: किसी दिए गए एफडी के लिए फाइल ढूंढना और लिखना ठीक है और अचानक किसी कारण के बिना errno = 9 वापस देता है।

+0

अगर मैं खोलने की कोशिश करता हूं तो मेरा कोड संकलित नहीं होगा (...); अजीब। –

+1

क्या आप छद्म कोड सही जानते हैं? –

+0

lseek() EBADF साथ विफल रहता है, तो आप यकीन है कि है कि बंद() एक ही फाइल वर्णनकर्ता पर भी EBADF साथ विफल हो जाएगा हो सकता है। और चूंकि आप अपनी पुनः खुली या पुनः मांग कॉल की जांच नहीं करते हैं, इसलिए कुछ भी हो रहा है। –

उत्तर

1

मैं सेटअप आप है, लेकिन इस परिदृश्य पर किस प्रकार, मुझे लगता है कि हो सकता है पता नहीं है इस तरह के एक प्रभाव (या किसी भी इसे के समान) का उत्पादन। मैंने इसे सत्यापित करने के लिए परीक्षण नहीं किया है, इसलिए कृपया इसे नमक के अनाज से लें।

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

उम्मीद है कि इससे मदद मिलती है।

+0

आप यहां हैं। ठीक है, जहां सभी फाइल हैंडल। फ़ाइल हैंडल का कोई बंद नहीं है। मेरे कोड में कोई समस्या नहीं थी बस ओएसएक्स को अमान्य चिह्नित करना। फ़ाइल को फिर से खोलने से एफडी आईडी भी वापस आ गई। मजेदार सामान। –

2

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

आपका छद्म कोड सबसे खराब समाधान है, क्योंकि यह आपको समस्या को ठीक करने का प्रभाव देगा, जबकि बग अभी भी लुप्त हो गया है।

मेरा सुझाव है कि आप डीबग प्रिंट्स (यानी printf() कॉल) जोड़ें जहां भी आप फ़ाइल या सॉकेट खोलें और बंद करें। इसके अलावा, Valgrind आज़माएं।

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

+0

इस प्रतिक्रिया की अपेक्षा कर रहा था, जो निश्चित रूप से सबसे स्पष्ट है। कोई मुर्गा नहीं है, लेकिन मुझे यकीन है कि मेमोरी रिसाव नहीं है। फ़ाइल हैंडल आईडी वही है (चेक) और lseek और ठीक काम करने से पहले लिखो। लेखन कार्यों के बीच गतिशील (स्मृति के अनुसार) कुछ भी नहीं चल रहा है। सभी फाइल आईओ कोड लॉग इन किया जा रहा है (एनएसएलओएल) और सब कुछ ठीक हो रहा है, अचानक कुछ स्थितियों में (दूसरी बार पुन: उत्पन्न नहीं) -1 -1 त्रुटि = 9 के साथ होता है। आपको यह मानना ​​होगा कि जब भी एफडी नहीं बदलेगा तो यह सबसे अधिक संभावना है कि errno = 9 सही दिखाई देगा? किसी कारण से यह करता है। –

+0

@ थॉमस: +1 मैं और अधिक सहमत नहीं हो सका। बग को ठीक किया जाना चाहिए, छुपा नहीं है। @ जीर, आप कैसे सुनिश्चित कर सकते हैं कि आपके पास ढेर या ढेर भ्रष्टाचार नहीं है? यह एक भयानक बग की तरह लगता है जिसे –

+0

को ठीक करने की आवश्यकता है निश्चित रूप से मैं सहमत हूं, कारण को बेहतर तरीके से ढूंढें। लेकिन पहली नजर में ऐसा लगता है कि कारण मेरे दायरे से बाहर था। यह अभी भी ऐसा लगता है क्योंकि वर्तमान एफडी को किसी अन्य मूल्य के साथ ओवरराइट नहीं किया जा रहा है। –

0

नहीं, ओएस को इस तरह फ़ाइल हैंडल बंद नहीं करना चाहिए, और अन्य अनुप्रयोग (फ़ाइल स्कैनर इत्यादि) सक्षम नहीं होना चाहिए।

समस्या के आसपास काम न करें, इसे स्रोत ढूंढें। यदि आपको नहीं पता कि आपकी समस्या का कारण क्या था, तो आप कभी नहीं जान पाएंगे कि आपका वर्कअराउंड वास्तव में काम करता है।

  1. अपनी धारणाओं की जांच करें।errno कॉल से पहले 0 पर सेट है? क्या एफडी वास्तव में उस बिंदु पर वैध है जब कॉल किया जा रहा है?(मुझे पता है कि आपने कहा है, लेकिन क्या आपने देखा है?)
  2. अपने प्लेटफ़ॉर्म पर puts(strerror(9)); का आउटपुट क्या है?
+0

errno 0 पहले है और अचानक lseek का परिणाम -1 है। एफडी वास्तव में वास्तव में खुला है क्योंकि लिखने एक ही पुनरावृत्ति में पहले काम करते हैं। –

+0

ठीक है, तो अपनी धारणाओं की जांच करने के लिए जाओ। आप मेरे कोड को मुझसे बेहतर जानते हैं। प्रत्येक कॉल से पहले एफडी के मूल्य को प्रिंट करना मेरा अगला कदम होगा। – DevSolar

+0

अच्छा विचार और एक सुझाव भी होता है जब किसी कारण से (नेटवर्क) ड्राइव डिस्कनेक्ट हो जाती है। –

7

तो मेरा सवाल यह है कि क्या ओएस किसी कारण से मेरे लिए फाइल हैंडल बंद कर सकता है? इसका कारण क्या हो सकता है? किसी फ़ाइल इंडेक्सर या फ़ाइल स्कैनर किसी प्रकार का?

नहीं, ऐसा नहीं होगा।

इसे हल करने का सबसे अच्छा तरीका क्या है; यह छद्म कोड सबसे अच्छा समाधान है? (कोड लेआउट कोई बात नहीं, इसके लिए काम करता है पैदा करेगा)

नहीं है, सबसे अच्छा तरीका है बग मिल और इसे ठीक करने के लिए है।

कोई भी इसी तरह के अनुभव का अनुभव करता है?

मैंने देखा है एफडी में कई बार में गड़बड़ हो रही है, मामलों, और दूसरों में शानदार उड़ा में से कुछ में EBADF में जिसके परिणामस्वरूप, यह हो गया है:

  • बफर अतिप्रवाह - कुछ बह निकला और एक 'int fd;' में बकवास मूल्य लिखना चर।
  • मूर्ख कीड़े कि हो सकता है जब वे मतलब धागे के बीच if(fd == foo[i].fd)
  • Raceconditions क्योंकि कुछ कोने मामले किसी if(fd = foo[i].fd) किया था, कुछ धागे गलत फ़ाइल जानकारी, जिसका कुछ अन्य धागे का उपयोग करना चाहता बंद कर देता है।

यदि आप इस समस्या को पुन: उत्पन्न करने का कोई तरीका ढूंढ सकते हैं, तो अपना प्रोग्राम 'स्ट्रेस' के तहत चलाएं, ताकि आप देख सकें कि क्या हो रहा है।

+0

मैं बग खोजने के बारे में सहमत हूं। मैं कुछ और कोड समीक्षा करूंगा लेकिन मैं जांचूंगा कि क्या होता है यदि मैं नेटवर्क ड्राइव डिस्कनेक्ट हो गया हो। शायद यह एक खराब फ़ाइल वर्णनकर्ता का कारण बन जाएगा? –

+0

नज़दीकी निरीक्षण के बाद एफडी बिल्कुल नहीं बदलता है और केवल एक धागा डिस्क आईओ (सभी फाइल हैंडलिंग) कर रहा है। मुझे लगता है कि अगर मैं एफडी बंद नहीं करता हूं, तो एफडी वही रहता है मुझे इरनो और -1 परिणाम सही नहीं होना चाहिए? यह वास्तव में करता है। –

+0

जबकि कुछ विशेष ओएस, कुछ विशेष फाइल सिस्टम/नेटवर्क आईओ का उपयोग करते हुए कुछ कोने केस बग हो सकता है जो ऐसा होने का कारण बनता है, यह अनुमान लगाना होगा। जब यह घटित होता है तो सभी धागे का एक स्ट्रेस बहुत उपयोगी होगा हालांकि – nos

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