Xcode 调试Mac/Cocoa文件描述符泄漏
我的沙盒Mac应用程序(显然)正在泄漏文件资源(句柄?)。向其中添加文件(并将其中一些文件转换为其他格式)时,它将在出现以下基本错误时失败:Xcode 调试Mac/Cocoa文件描述符泄漏,xcode,macos,cocoa,instruments,file-descriptor,Xcode,Macos,Cocoa,Instruments,File Descriptor,我的沙盒Mac应用程序(显然)正在泄漏文件资源(句柄?)。向其中添加文件(并将其中一些文件转换为其他格式)时,它将在出现以下基本错误时失败:-[NSFileManager copyItemAtPath:toPath:error:: NSUnderlyingError=0x600000440a50 "The operation couldn’t be completed. Too many open files" 我可以在Xcode外部(使用调试构建)可靠地复制它,但不能在内部。看起来某个地方的
-[NSFileManager copyItemAtPath:toPath:error:
:
NSUnderlyingError=0x600000440a50 "The operation couldn’t be completed. Too many open files"
我可以在Xcode外部(使用调试构建)可靠地复制它,但不能在内部。看起来某个地方的文件正在打开,但从未关闭。每次在同一个文件上删除同一文件夹时都会发生这种情况,如果我将该文件取出,则会发生下一次。我记录了在NSFileManager
之外执行文件I/O的每个位置,看起来我所有打开的调用都与关闭相平衡,我在NSURLs
上启动和停止安全资源访问的调用也是如此
我尝试在Xcode之外的仪器中运行文件活动预设,并能够重现其中的错误,但似乎没有任何方法可以从所使用的仪器(文件活动、读/写、文件属性、目录I/O)获取我需要的信息.我最终能够使用仪器找出根本原因。我按照FD列对文件属性仪器的事件列表进行了排序,能够看到同一文件描述符有许多“打开”事件(有些是同一文件和不同描述符的事件),而没有任何“关闭”事件。我能够在我使用的库中找到有问题的代码。我在中复制了它,使用此方法并在运行某些代码之前和之后进行比较:
- (NSInteger)numberOfOpenFileHandles {
int pid = [[NSProcessInfo processInfo] processIdentifier];
NSPipe *pipe = [NSPipe pipe];
NSFileHandle *file = pipe.fileHandleForReading;
NSTask *task = [[NSTask alloc] init];
task.launchPath = @"/usr/sbin/lsof";
task.arguments = @[@"-P", @"-n", @"-p", [NSString stringWithFormat:@"%d", pid]];
task.standardOutput = pipe;
[task launch];
NSData *data = [file readDataToEndOfFile];
[file closeFile];
NSString *lsofOutput = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
// NSLog(@"LSOF:\n%@", lsofOutput);
return [lsofOutput componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]].count;
}
使用活动监视器,选择流程,查看>检查流程,选择打开的文件和端口选项卡。或者做
sudolsof-p
。看看您是否可以判断哪些文件或端口打开太多次。也许这会使代码的哪一部分负责变得显而易见。也许,从Xcode启动时不会失败,因为Xcode会增加打开文件描述符的资源限制。请参阅ulimit
shell内置命令和getrlimit()
和setrlimit()
。