【发布时间】:2017-03-02 09:12:13
【问题描述】:
背景背景:
我有一个为 macOS 10.11+ 构建的应用程序。这个应用程序需要运行一些可能偶尔会崩溃的第三方代码(The Libsass compiler)。为了避免关闭我的整个应用程序,我创建了一个运行此代码的 XPC 服务(使用 NSXPCConnection 和 Xcode 中的标准 XPC 服务模板)。
我的问题:
XPC 服务似乎正在将运行我的代码的线程的堆栈大小设置为512kb,这是 macOS 对主线程其他线程的默认设置。 (主线程的栈大小默认为8MB。)
Libsass 编译器有时会在某些涉及深度递归(因此有很多堆栈帧)的文件上发生堆栈溢出而崩溃。
注意: 我知道这是问题所在,因为如果我在应用程序的主线程上运行 exact 相同的 Libsass 序列(不使用 XPC),一切正常,并且堆栈溢出永远不会发生。
我需要什么:
一种增加 XPC 服务执行工作的线程堆栈大小的方法。
我尝试过的:
我已经将-Wl,-stack_size,4000000 添加到我的 XPC 服务目标的“其他链接器标志”构建设置中。这会将堆栈大小设置为 64MB(允许的最大值)。构建后,我在 Finder 中检查 XPC 包,并使用以下命令验证链接器是否正确应用了此标志:
otool -lV codekit-libsass-service.xpc/Contents/MacOS/codekit-libsass-service | grep stack
产生这个输出:stacksize 67108864,表示堆栈大小确实设置为64MB。
问题在于,这仅适用于服务的 main 线程,而我的 XPC 方法似乎没有在服务的主线程上调用。我通过使用[NSThread isMainThread] 验证了这一点,当在我的 XPC 方法中调用它时返回false。
所以,我然后尝试强制使用 dispatch_async(dispatch_get_main_queue() ^{...}); 在主线程上完成的工作,但是,-isMainThread 仍然从 within 该块返回 false .此外,如果我使用[NSThread currentThread] stackSize],我会得到524288,这表明运行此代码的线程有一个512kb 堆栈。太棒了。
我还尝试使用setrlimit() 在运行时动态提高堆栈大小。这并没有解决问题。
我已经阅读了很多文档。 XPC 服务使用哪些线程以及它们如何使用它们的细节似乎是我们不应该担心的实现细节。
【问题讨论】:
标签: objective-c cocoa stack-overflow xpc nsxpcconnection