我们发现我们复杂的iPhone应用程序(ObjC,C++,JavaScript/WebKit)在异常情况下泄露了文件描述符.
我需要知道我们要打开哪些文件(通过文件路径).
我想要像BSD命令"lsof"这样的东西,当然,这在iOS 4中是不可用的,至少对我来说不行.理想情况下是C或ObjC功能.或者像鲨鱼或乐器这样的工具.只需要我们正在运行的应用程序的文件,而不是(与lsof一样)所有应用程序/进程.
我们用文件做各种各样的事情,并且"太多打开文件"失败的代码在很长时间内没有变化,并且由于情况不同寻常,这可能在几个月前就已经悄然发生.因此,没有必要提醒我查看打开文件的代码并确保关闭它们.我已经知道了.用一些lsof-esque来缩小范围会很好.谢谢.
Ric*_*ers 29
#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 ;
}
}
Run Code Online (Sandbox Code Playgroud)
为了将来参考,我在装有 iOS 13 的 iPhone 11 上遇到了类似的问题;我通过创建太多文件和套接字来创建太多文件描述符 (FD)。我的解决方案是在运行时增加 FD setrlimit()。
首先我得到了我的iPhone 11上的FD限制,代码如下:
// 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;
}
Run Code Online (Sandbox Code Playgroud)
运行后getrlimit(),我可以确认,在iOS 13上,软限制是256个FD,硬限制是无限个FD。由于我在文件和套接字之间创建了超过 300 个 FD,因此我的应用程序崩溃了。
就我而言,我无法减少 FD 的数量,因此我决定增加 FD 软限制,代码如下:
// 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;
}
Run Code Online (Sandbox Code Playgroud)
注意:您可以在此处gettrlimit()和此处找到更多信息。setrlimit()
| 归档时间: |
|
| 查看次数: |
11426 次 |
| 最近记录: |