【问题标题】:Debugging a Mac/Cocoa file descriptor leak调试 Mac/Cocoa 文件描述符泄漏
【发布时间】:2014-09-20 05:29:54
【问题描述】:

我的沙盒 Mac 应用程序(显然)泄漏了文件资源(句柄?)。在向其中添加文件(并将其中一些文件转换为其他格式)时,它会在 -[NSFileManager copyItemAtPath:toPath:error:] 上失败,并出现以下基本错误:

NSUnderlyingError=0x600000440a50 "The operation couldn’t be completed. Too many open files"

我可以在 Xcode 外部(使用 Debug 构建)可靠地重现此内容,但不能在内部重现。看起来某处的文件正在打开并且从未关闭。当我删除同一个文件夹时,每次都会在同一个文件上发生这种情况,或者如果我取出该文件,则下一个文件会发生这种情况。我记录了我能想到的在NSFileManager 之外进行文件 I/O 的每个地方,看起来我所有的打开调用都与关闭平衡,就像我在 @ 上启动和停止安全资源访问的调用一样987654324@.

  1. 为什么这不会发生在 Xcode 内部?
  2. 如何追踪不平衡呼叫发生的位置?
  3. 错误是否可能是一个红鲱鱼?

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

【问题讨论】:

  • 使用活动监视器,选择进程,查看>检查进程,选择打开文件和端口选项卡。或者sudo lsof -p <the PID of the process>。看看你是否能分辨出哪个文件或端口打开了太多次。也许这会让代码的哪一部分负责。从 Xcode 启动时,它可能不会失败,因为 Xcode 提高了打开文件描述符的资源限制。请参阅ulimit shell 内置命令和getrlimit()setrlimit()

标签: xcode macos cocoa instruments file-descriptor


【解决方案1】:

我最终能够使用 Instruments 找出根本原因。我按 FD 列对 File Attributes 仪器的事件列表进行了排序,并且能够看到同一个文件描述符有许多“打开”事件(有些是同一个文件和不同的描述符),没有任何“关闭”事件。我能够将有问题的代码追踪到我使用的库中。我在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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-09
    • 2015-09-23
    • 2011-01-15
    • 2020-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多