Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xcode/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xcode macOS:删除文件时的断点_Xcode_Debugging_Cocoa_Nsfilemanager_Unlink - Fatal编程技术网

Xcode macOS:删除文件时的断点

Xcode macOS:删除文件时的断点,xcode,debugging,cocoa,nsfilemanager,unlink,Xcode,Debugging,Cocoa,Nsfilemanager,Unlink,在我用Objective-C编写的旧macOS应用程序中,我正在调试一个重复出现的问题,即在系统框架调用期间过早删除文件包。为了获得线索,我希望在删除文件时让调试器中断。为此,我在Xcode中的以下符号处设置了符号断点: unlink unlinkat -[NSFileManager removeItemAtPath:error:] -[NSFileManager removeItemAtURL:error:] 所有这些断点都按预期解析为实际断点,当文件按预期删除时,它们按预期中断。但在麻烦的

在我用Objective-C编写的旧macOS应用程序中,我正在调试一个重复出现的问题,即在系统框架调用期间过早删除文件包。为了获得线索,我希望在删除文件时让调试器中断。为此,我在Xcode中的以下符号处设置了符号断点:

unlink
unlinkat
-[NSFileManager removeItemAtPath:error:]
-[NSFileManager removeItemAtURL:error:]
所有这些断点都按预期解析为实际断点,当文件按预期删除时,它们按预期中断。但在麻烦的过早删除文件期间,不会发生中断

macOS中是否有其他可以删除文件的函数,我应该为其添加断点

背景资料:

在对新复制(如文件>复制)但从未在保存的文档包之前调用
[super saveDocument]
时,我的自定义NSDocument子类中会出现此问题。此类文档包驻留在
~/Library/Autosave Information/
中,当一切正常时,将一直保留在那里,直到出现“保存”面板并随后被取消。但是,在错误情况下,当用户单击“保存”“文件”>“保存”(或自动保存)时,软件包会立即消失,这显然会导致稍后的错误,表明删除的软件包无法移动到“保存”面板返回的路径

我还尝试在该包出现后,在单击文件>保存之前,将其POSIX权限更改为octal 500。我的想法是它不能被删除,我还打开了所有的异常和错误断点,希望神秘的删除程序能在调试器控制台上发出嘎嘎声。结果:软件包没有被删除,正如我所假设的,保存操作成功了。但没有任何声音。因此,这个神秘的删除器确实是个问题,但显然它既隐蔽又宽容:(

2019年7月19日更新:

在找到其他事情做了5天之后,我决定咬紧牙关,按照Ken Thomases的建议使用DTrace。它起了作用,向我显示主题文件包中的所有文件都是通过调用
libsystem\u kernel.dylib\u unlink
删除的,而
-[NSFileManager removietematpath:error:
又调用了DTrace

我不知道为什么我在这些函数上的断点没有因为这些调用而中断,除了可能在堆栈跟踪的底部有一条线索,提到“xpc”。这个文件删除是否可能是由xpc助手进程完成的?DTrace是否也探测被探测进程的助手进程?这将非常令人惊讶

以下是DTrace会议记录摘要:

Air2 jk$ sudo dtrace -n 'syscall::unlink*:entry,syscall::rmdir:entry,syscall::rename:entry { printf("time=%d  arg=%s\n", timestamp/1000000000, copyinstr(arg0)); ustack(100); }' -p `pgrep MyApp`
Password:
dtrace: description 'syscall::unlink*:entry,syscall::rmdir:entry,syscall::rename:entry ' matched 4 probes
CPU     ID                    FUNCTION:NAME
  1    178                     unlink:entry time=6562  arg=/Users/jk/Library/Autosave Information/Unsaved MyApp Document.bmco

              libsystem_kernel.dylib`__unlink+0xa
              libremovefile.dylib`__removefile_tree_walker+0x147
              libremovefile.dylib`removefile+0x99
              Foundation`-[NSFilesystemItemRemoveOperation main]+0xba
              Foundation`__NSOPERATION_IS_INVOKING_MAIN__+0x11
              Foundation`-[NSOperation start]+0x2db
              Foundation`-[NSFileManager removeItemAtPath:error:]+0x54
              AppKit`__90-[NSDocumentController(NSInternal) _autoreopenDocumentsFromRecords:withCompletionHandler:]_block_invoke_2+0x90
              AppKit`__89-[NSDocumentController reopenDocumentForURL:withContentsOfURL:display:completionHandler:]_block_invoke_2+0xa6
              AppKit`___NSMainRunLoopPerformBlockInModes_block_invoke+0x19
              CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__+0xc
              CoreFoundation`__CFRunLoopDoBlocks+0x17b
              CoreFoundation`__CFRunLoopRun+0xae8
              CoreFoundation`CFRunLoopRunSpecific+0x1f3
              HIToolbox`RunCurrentEventLoopInMode+0x124
              HIToolbox`ReceiveNextEventCommon+0x164
              HIToolbox`_BlockUntilNextEventMatchingListInModeWithFilter+0x40
              AppKit`_DPSNextEvent+0x3de
              AppKit`-[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:]+0x548
              ViewBridge`-[NSViewServiceApplication nextEventMatchingMask:untilDate:inMode:dequeue:]+0x5f
              AppKit`-[NSApplication run]+0x292
              AppKit`NSApplicationMain+0x309
              libxpc.dylib`_xpc_objc_main.cold.3+0x38
              libxpc.dylib`_xpc_objc_main+0x203
              libxpc.dylib`_xpc_copy_xpcservice_dictionary
              ViewBridge`xpc_connection_handler
              ViewBridge`NSViewServiceApplicationMain+0xbff
              com.apple.appkit.xpc.openAndSavePanelService`main+0xc0
              libdyld.dylib`start+0x1
              com.apple.appkit.xpc.openAndSavePanelService`0x1
(该成绩单中的调用显然试图取消与文件包的链接,我认为这可能会失败,因为文件包不是空的。接下来是几个类似的调用,遍历文件包树,删除每个节点,最后重复该调用删除文件包,显然成功。)

更新2019-08-06


虽然我们现在知道问题的低级原因,但我们仍然不知道高级原因。我发现问题(过早删除
~/Library/Autosave Information
中的临时文档文件)只发生在macOS 10.15 Beta 4-5(当前版本)中只有在关闭app Sandbox的情况下才能构建应用程序。当app Sandbox打开时,相关的
自动保存信息
位于应用程序容器中的不同位置,因此这应该是一个很好的线索!通过一个小的演示应用程序,核心数据,基于文档,这个问题很容易重现,我已经向苹果提交了一个简短的视频eo.如果任何人有苹果的线路,请将他们的注意力转移到FB6937676!

重命名操作将使源路径不再引用文件(看起来源路径上的文件已被删除)。它还可以取消链接/删除目标路径上的文件,尽管它将替换为源路径上的文件。因此,这将是
rename()
rename()
rename ex\u np()
,以及
rename atx\u np()

当然,
rmdir()


显然,有一个隐藏的
delete()
系统调用。它被描述为“使用Carbon语义从文件系统中删除一个名称”。框架可能正在使用它。

谢谢你,肯。我为你提到的所有六个函数都添加了断点(包括
rmdir
,因为我刚刚记得我的文档是一个包)。但仍然没有中断。我在苹果开源XNU内核中发现了
delete()
函数。它确实有一个非常奇怪的声明:
int delete(user\u addr\u t path)no\u SYSCALL\u STUB;}{private delete(Carbon semantics)
。断点导航器不会将symbol
delete
解析为
delete()
。相当隐蔽。我明天会进一步研究它。您可以使用的另一个工具是DTrace。它在很大程度上被系统完整性保护(SIP)所阉割,但您可以在不完全禁用SIP的情况下重新启用它。然后,您可以使用
errinfo
dtruss
现成的基于DTrace的工具。如果这些工具没有提供您要查找的确切信息,您可以直接使用
DTrace
和一行或小脚本来获取更多信息。谢谢。@kenthomass与往常一样正确。DTraCE在某种程度上工作在断点失败的地方。我在编辑中解释了这个问题。我很高兴你找到了罪犯。我确实认为保存面板已经过时了,但不会想到它会删除任何东西!当你警告你正在重写现有文档时,你选择替换吗?g XPC服务中的系统调用:它根本不遵循流程。默认情况下,
syscall
提供程序观察整个系统,而不是指定的流程。您必须在探测器上设置一个类似于
/pid=$target/
的条件,以关注t