NSURL资源泄漏导致权限被拒绝?

时间:2015-03-03 03:59:06

标签: objective-c macos cocoa nsfilemanager appstore-sandbox

我的Mac应用程序会复制用户拖入的文件。该应用程序是沙盒。我现在有一个bug,我可以在Xcode中可靠地重现,但是我无法追踪它的来源。

当我添加一定数量的文件时,应用程序突然无法访问后来的文件。所有源文件都从同一个父目录向下一级,并且其间的所有文件夹都具有相同的权限,并使用ls -l进行验证。该应用程序会保留应用程序范围的Destination Directory书签,在创建.directoryName并开始文件复制之前可以访问该书签。

我收到错误:

  

错误Domain = NSCocoaErrorDomain Code = 513“”Filename.ext“无法复制,因为您无权访问”.directoryName“。” UserInfo = 0x6080000eaf80 {NSSourceFilePathErrorKey = / Users / Username / Parent Directory / Subdir / Filename.ext,NSUserStringVariant =(      复制   ),NSDestinationFilePath = / Users / Username / Desktop / Destination Directory / .directoryName / Filename.ext,NSFilePath = / Users / Username / Parent Directory / Subdir / Filename.ext,NSUnderlyingError = 0x6080004567a0“操作无法完成。操作不允许“}

我在调试时完成了以下操作:

  1. 尝试退出并重新启动后,尝试自行添加Subdir/Filename.ext
  2. 已验证(使用lsof和活动监视器)我没有泄漏文件句柄(我知道过去曾为我造成类似问题)
  3. 使用符号断点验证每次调用-[NSURL startAccessingSecurityScopedResource]与调用-[NSURL stopAccessingSecurityScopedResource](以及他们的CF等价物)的平衡
  4. 确定Filename.ext和其他失败的文件在没有其他文件的情况下成功添加
  5. 在调试器内外调试和发布版本中也会出现相同的行为
  6. 我尝试以root身份运行,但我的应用程序不会以这种方式运行。在调试器中运行时,我得到EXC_BAD_INSTRUCTION异常,并在命令行上使用sudo运行它会导致崩溃(可能是同一个)
  7. 这种行为似乎表明某种资源泄漏,但它并不是我能够检测到的任何东西。还有什么想法可能导致这个问题吗?

    更新

    我还没有准备好宣布答案,但是在用户将文件放入应用程序后,我开始在代码的不同部分出现这些权限错误。我注意到日志的一些方法,我会看到如下消息:

      

    从粘贴板使用itemIdentifier(1)的沙箱扩展名失败!

    追踪此错误导致我提出其他人问的问题:Sandboxed Mac app exhausting security scoped URL resources

    不幸的是,accepted answer说(释义)“强硬的no no”。似乎Cocoa和沙盒机制本身正在泄漏安全范围令牌(虽然我无法通过符号断点进行验证,并且知道没有其他方法可以检查)。在沙盒文件上执行某些(未知)数量的文件操作后,您将开始收到此错误,唯一的解决方案是退出并重新启动。

    我希望至少有一些方法可以提示用户在关闭时重新启动,但我不确定是否有任何方法可以衡量这些句柄的使用情况。或者,更好的是,如果我在完成处理删除的文件后手动清理,但我不确定这是如何工作的,因为我需要使用NSFilenamesPboardType粘贴板类型来获取多个文件的路径。我尝试从这些创建NSURL并停止安全范围访问,但这没有效果。

    更新2

    我为此提交了一张DTS票据,因为它正在影响用户,并且没有明确的解决方法。我会更新问题(也许会给出答案?),因为我发现了更多。

    来自Apple DTS团队的回复

    显然,这是一个已知问题,没有可用的解决方法。我提交了一个雷达:rdar://20652066,如果你想欺骗它。

1 个答案:

答案 0 :(得分:0)

这是在El Capitan(10.11)版本中修复的(可能是第一版,但我不确定)。当我针对更新的SDK构建我的应用程序时,行为恢复正常。