на iOS / iPhone: «Слишком много открытых файлов»: необходимо перечислить открытые файлы (например, lsof) - PullRequest
16 голосов
/ 03 ноября 2010

Мы обнаружили, что наше сложное приложение для iPhone (ObjC, C ++, JavaScript / WebKit) пропускает дескрипторы файлов при необычных обстоятельствах.

Мне нужно знать, какие файлы (по пути к файлу) мы оставляем открытыми.

Мне нужно что-то вроде команды BSD "lsof", которая, конечно, недоступна в iOS4, по крайней мере, не для меня.В идеале функция C или ObjC.Или инструмент, как акула или инструменты.Просто нужны файлы для нашего работающего приложения, а не (как с lsof) для всех приложений / процессов.

Мы делаем все с файлами, и код, который не работает с "Too many open files"не менялись веками, и поскольку обстоятельства необычны, это могло подкрасться несколько месяцев назад.Поэтому нет необходимости напоминать мне о том, что нужно просматривать код, который открывает файлы, и обязательно закрывать их.Я это уже знаю.Было бы хорошо, чтобы сузить это с чем-то lsof-esque.Спасибо.

Ответы [ 6 ]

28 голосов
/ 16 ноября 2011
#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 ; 
    }
}
2 голосов
/ 08 ноября 2010

Если инструменты не работают в ваших целях, моей следующей рекомендацией будет запустить ваше приложение в симуляторе и использовать fs_usage в командной строке для отслеживания файловых дескрипторов, которые вы открываете и закрываете. Примерно так:

  1. В Терминале запустите «sudo fs_usage -f filesys MyAppName», заменив MyAppName именем вашего приложения.
  2. Запустите ваше приложение.
  3. Посмотрите на дескриптор файлов, открывающий и закрывающий команды fs_usage, чтобы увидеть, какие файлы вы оставляете открытыми.
2 голосов
/ 04 ноября 2010

Разве вы не можете просто перехватить все открытые файлы с помощью собственной функции, скажем, my_fopen, и сохранить дескрипторы вместе с их именами, чтобы, когда у вас открылось слишком много файлов, вы могли просмотреть список и посмотреть, все дескрипторы?

2 голосов
/ 03 ноября 2010

Можете ли вы воспроизвести проблему с запуском в симуляторе?

Если это так, то вы можете использовать "lsof" ...


Обновление:

Хорошо, если вы не можете использовать симулятор, тогда идея №2:

Когда вы получаете сообщение об ошибке «слишком много открытых файлов», вызывайте функцию, которая перебирает все дескрипторы открытых файлов и выводит некоторую информацию о каждом (например, длину и первые несколько байтов).

1 голос
/ 06 ноября 2010

Instruments.app может вам помочь (/Developer/Applications/Instruments.app).Запустите ваше приложение, используя инструмент «Использование системы» в Instruments, и оно, вероятно, покажет вам, что вам нужно знать.Лучше всего то, что его можно использовать во время работы приложения на устройстве без джейлбрейка.

0 голосов
/ 03 ноября 2010

Я предлагаю вам запустить свое приложение на взломанном iPhone и использовать Backgrounder и MobileTerminal, чтобы взглянуть на открытые в данный момент файлы.

Вы можете получить бинарный файл для iPhone от lsof здесь: http://modmyi.com/cydia/package.php?id=6945

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...