На iOS/iPhone: "Слишком много открытых файлов": нужно указывать открытые файлы (например, lsof)

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

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

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

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

Ответы

Ответ 1

#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

Можете ли вы воспроизвести проблему, запущенную в симуляторе?

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


обновление:

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

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

Ответ 3

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

Ответ 4

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

  • В терминале запустите "sudo fs_usage -f filesys MyAppName", заменив имя MyAppName на имя вашего приложения.
  • Запустите приложение.
  • Посмотрите на дескриптор файла, чтобы открыть и закрыть команды, выводимые fs_usage, чтобы увидеть, какие файлы вы покидаете.

Ответ 5

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

Ответ 6

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

Здесь вы можете получить двоичный код iPhone lsof: http://modmyi.com/cydia/package.php?id=6945