2010-11-03 14 views
15

हमने पाया है कि हमारे जटिल आईफोन ऐप (ओबीजेसी, सी ++, जावास्क्रिप्ट/वेबकिट) असामान्य परिस्थितियों में फाइल डिस्क्रिप्टर लीक कर रहे हैं।आईओएस/आईफोन पर: "बहुत सारी खुली फाइलें": खुली फ़ाइलों को सूचीबद्ध करने की आवश्यकता है (जैसे lsof)

मुझे यह जानने की ज़रूरत है कि कौन सी फाइलें (फ़ाइल पथ से) हम खुले रह रहे हैं।

मुझे बीएसडी कमांड "एलएसओफ़" जैसी कुछ चाहिए, जो निश्चित रूप से आईओएस 4 में उपलब्ध नहीं है, कम से कम मेरे लिए नहीं। आदर्श रूप से एक सी या ओबीजेसी समारोह। या शार्क या इंस्ट्रूमेंट्स जैसे टूल। सभी ऐप्स/प्रक्रियाओं के लिए बस हमारे चल रहे ऐप के लिए फ़ाइलों की आवश्यकता नहीं है (जैसा कि lsof के साथ)।

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

उत्तर

26
#import <sys/types.h> 
#import <fcntl.h> 
#import <errno.h> 
#import <sys/param.h> 

+(void) lsof 
{ 
    int flags; 
    int fd; 
    char buf[MAXPATHLEN+1] ; 
    int n = 1 ; 

    for (fd = 0; fd < (int) FD_SETSIZE; fd++) { 
     errno = 0; 
     flags = fcntl(fd, F_GETFD, 0); 
     if (flags == -1 && errno) { 
      if (errno != EBADF) { 
       return ; 
      } 
      else 
       continue; 
     } 
     fcntl(fd , F_GETPATH, buf) ; 
     NSLog(@"File Descriptor %d number %d in use for: %s",fd,n , buf) ; 
     ++n ; 
    } 
} 
+1

यह स्निपेट एक unity3d बग डीबग करने के तीन पूर्ण दिन समाप्त हुआ। आपको बहुत - बहुत धन्यवाद! – utahwithak

+0

क्या आप आईओएस के लिए खुली फाइलों की सीमा जानते हैं? मुझे केवल 32 खुली फाइलों के साथ समान समस्या मिल रही है! –

+2

बेवकूफ सवाल के लिए खेद है, लेकिन मुझे यह स्निपेट कहां रखना चाहिए और मैं अपने ऐप के लिए इसका उपयोग कैसे कर सकता हूं? – lub0v

2

क्या आप सिम्युलेटर में चल रही समस्या को पुन: उत्पन्न कर सकते हैं?

यदि हां, तो आप वास्तव में "lsof" इस्तेमाल कर सकते हैं ...


अद्यतन:

:

ठीक है, आप सिम्युलेटर, तो विचार # 2 का उपयोग नहीं कर सकते हैं

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

+0

हमने अभी तक सिम्युलेटर में पुन: पेश नहीं किया है। और हम डिवाइस के खिलाफ सही चीज करने के लिए उपकरण नहीं प्राप्त कर सकते हैं। धन्यवाद। –

0

मेरा सुझाव है कि आप अपने ऐप को जेलब्रोकन आईफोन पर चलाएं और वर्तमान में खुले फ़ाइलों को देखने के लिए पृष्ठभूमि और मोबाइल टर्मिनल का उपयोग करें।

आप यहाँ lsof का एक iPhone द्विआधारी प्राप्त कर सकते हैं: http://modmyi.com/cydia/package.php?id=6945

+0

धन्यवाद।हमारे यहां एक आखिरी जेलब्रोकन डिवाइस है। लेकिन यह और यह जेलब्रेकिंग पुरानी है और यह lsof इंस्टॉल को बर्दाश्त नहीं कर रहा था। –

2

तुम सिर्फ रोकना नहीं कर सकते सभी फाइल अपने खुद के समारोह के साथ खुलता है, कहते हैं कि my_fopen, और उनके नाम के साथ वर्णनकर्ता स्टोर, ताकि आप भी है जब कई फाइलें खोली गईं, आप यह देखने के लिए अपनी सूची के माध्यम से जा सकते हैं कि सभी वर्णनकर्ता क्या ले रहे हैं?

+0

+1 यह एक उत्कृष्ट रणनीति है –

+0

हाँ, मैंने इसे एक पीएसपी गेम पर इस्तेमाल किया क्योंकि मैं एक ही समस्या में आ रहा था (सिस्टम द्वारा लीक की गई फाइलें हैंडल "माफ करना, दोस्त, कोई और फाइल नहीं खोल सकता")। –

+0

क्या आपका मतलब है fopen के बजाय my_fopen को कॉल करें? हम कर सकते हैं अगर हम सीधे सभी फाइलें खोलने के लिए फॉपेन का इस्तेमाल करते थे, लेकिन हम सी ++ (एफएसटीएम), ओबीजेसी, और शायद (अप्रत्यक्ष रूप से) जावास्क्रिप्ट/वेबकिट से फ़ाइलें खोलते हैं। और सॉकेट एफडी का भी उपभोग करते हैं। क्या आप कुछ लो-स्तरीय हुक, या फॉपेन को बदलने के लिए कुछ लिंकर चाल का सुझाव दे रहे हैं? धन्यवाद। –

1

Instruments.app आपकी मदद करने में सक्षम हो सकता है (/ डेवलपर/अनुप्रयोग/इंस्ट्रूमेंट्सएप)। इंस्ट्रूमेंट्स में सिस्टम उपयोग उपकरण का उपयोग करके अपना ऐप चलाएं, और यह आपको दिखाएगा कि आपको क्या पता होना चाहिए। सबसे अच्छा, इसका उपयोग आपके डिवाइस पर ऐप चलाने के दौरान किया जा सकता है, बिना जेलबैक किए।

+0

हम इस मामले में डिवाइस के खिलाफ सही चीज करने के लिए उपकरण नहीं प्राप्त कर सकते हैं। धन्यवाद –

2

यदि उपकरण आपके उद्देश्यों के लिए अच्छा काम नहीं कर रहे हैं, तो मेरी अगली अनुशंसा आपके ऐप को सिम्युलेटर में चलाने के लिए होगी, और फ़ाइल डिस्क्रिप्टर को खोलने और बंद करने के लिए कमांड लाइन पर fs_usage का उपयोग करें। इस तरह कुछ:

  1. टर्मिनल में, "sudo fs_usage -f filesys MyAppName" चलाएं, MyAppName को आपके ऐप के नाम से बदल दें।
  2. अपना ऐप लॉन्च करें।
  3. फ़ाइल डिस्क्रिप्टर को खोलें और fs_usage द्वारा आउटपुट आउटपुट को बंद करें यह देखने के लिए कि आप कौन सी फाइलें खोल रहे हैं।
संबंधित मुद्दे