xcode - 调试 Mac/Cocoa 文件描述符泄漏

标签 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 之外进行文件 I/O 的每个位置,看起来我所有的打开调用都与关闭保持平衡,启动和停止的调用也是如此NSURL 上的安全资源访问。

  1. 为什么这不会在 Xcode 中发生?
  2. 如何追踪不平衡调用发生的位置?
  3. 这个错误有可能是转移注意力吗?

我尝试使用文件事件预设在 Xcode 之外的 Instruments 中运行,并且能够重现其中的错误,但看起来没有任何方法可以获取我的信息所使用工具的需求(文件事件、读/写、文件属性、目录 I/O)。

最佳答案

我最终能够使用 Instruments 找出根本原因。我按 FD 列对文件属性仪器的事件列表进行排序,并且能够看到同一文件描述符有许多“打开”事件(有些事件针对同一文件和不同的描述符),没有任何“关闭”事件。我能够追踪到我使用的库中的违规代码。我在 unit tests 中转载了它,使用此方法并比较一些代码运行之前和之后:

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

关于xcode - 调试 Mac/Cocoa 文件描述符泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25005213/

相关文章:

ios - 看到其他玩家 nextpeer

objective-c - 在 NSString 中搜索确切的词

objective-c - 雪豹下不显示核心动画层

ios - 子类 UICollectionViewCell 不更新图像

ios - Xcode 中的小数位显示不正确?

c++ - 使用 iPad 上的所有可用内存

ios - 从 Xcode 启动 iOS 模拟器并出现黑屏,随后 Xcode 挂起且无法停止任务

客户端/服务器 : Integer always received as 1 (C-programming)

macos - OSX 10.9 Mavericks 上的 Perl DBI/DBD 问题

macos - Mac系统上检测框架使用情况?