on iOS/iPhone: "Too many open files": need to list open files (like lsof)

For future reference, I ran into a similar problem on an iPhone 11 with iOS 13; I was creating too many file descriptors (FDs) by creating too many files and sockets. My solution was to increase FDs at runtime with setrlimit().

First I got the FD limits on my iPhone 11, with the following code:

// This goes somewhere in your code
struct rlimit rlim;

if (getrlimit(RLIMIT_NOFILE, &rlim) == 0) {
    std::cout << "Soft limit: " << rlim.rlim_cur << std::endl;
    std::cout << "Hard limit: " << rlim.rlim_max << std::endl;
} else {
    std::cout << "Unable to get file descriptor limits" << std::endl;
}

After running getrlimit(), I could confirm that on iOS 13, the soft limit is 256 FDs, and the hard limit is infinite FDs. Since I was creating > 300 FDs between files and sockets, my app was crashing.

In my case I couldn't decrease the number of FDs, so I decided to increase the FD soft limit instead, with this code:

// This goes somewhere in your code
struct rlimit rlim;

rlim.rlim_cur = NEW_SOFT_LIMIT;
rlim.rlim_max = NEW_HARD_LIMIT;

if (setrlimit(RLIMIT_NOFILE, &rlim) == -1) {
    std::cout << "Unable to set file descriptor limits" << std::endl;
}

NOTE: You can find more information on gettrlimit() and setrlimit() here and here.


Can you reproduce the problem running in the simulator?

If so, then you could actually use "lsof"...


update:

Ok, if you can't use the simulator, then idea #2:

When you get the "too many open files" error, call a function that iterates through all open file descriptors and dumps some information about each (for example the length and the first few bytes).


#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 ; 
    }
}

Tags:

C

Ios

Iphone