在 macOS 上的 C++ 插件中拦截 signals/mach 异常

Intercepting signals/mach exceptions in a C++ plugin on macOS

我正在为某个主机应用程序开发一套插件,同时针对 Windows 和 Mac (OSX+)。这些插件是用 C++ 编写的。我想向它们添加崩溃和异常报告处理,以防插件变得流氓。这样做是为了在插件行为不当的情况下不会导致整个主机应用程序崩溃,而是获得一些反馈并跳过那个插件调用(并使后续插件调用成为一种无操作)。考虑记录一些状态并在其上打一个错误代码+文本。从那时起,插件切换到请求详细信息的错误状态 returns 此状态。

这是一个很大的遗留代码库,随着时间的推移已经有了很大的改进,但仍然存在一些粗糙的边缘,所以像“只是不要崩溃”这样的答案不是我要找的: ) 这也无济于事我更像是一个 Windows 开发人员而不是 macOS 开发人员,所以我可能忽略了一些非常明显的事情。

我研究了信号处理程序,但我从中了解到它们是进程范围的。即:对插件不友好,尤其是当主机可以同时使用这些插件中的多个时(谁将首先捕获并因此处理信号?)。并且主机应用程序已经有自己的崩溃处理程序,可能使用信号处理程序,所以安装我们自己的应用程序会让我认为谁负责?另外,我的报告选项在此类处理程序中极为有限;如果可能的话,我想在这里有更多的自由(比如使用 std::strings 和他们暗示的 new/delete)。

然后还有Mach异常处理。但是当结合 'plugin'...

进行谷歌搜索时,我完全无法获得有用的结果

有没有人对走哪条路有什么建议,或者哪个选项更适合我的情况?

macOS 上的唯一选项是信号处理程序和 Mach 异常处理程序。

这两种机制都是 process-wide,因此无论出现什么问题都会报告。

如果安装了新的信号处理程序,旧的将不会 运行。 sigaction() API 与之前安装的 return 相同,因此可以 运行 和新安装的一样。然后可能会再次安装另一个信号处理程序并替换你的。

这里有一个非常有用的 post 详细介绍了如何实现信号处理程序 - https://developer.apple.com/forums/thread/113742

Mach 异常处理程序的情况几乎相同,调用 task_set_exception_ports() 将覆盖之前设置的处理程序,因此一旦您的新处理程序具有 运行 如果您想恢复这些处理程序传播异常。 Mach 异常处理程序的一大优点是它们可以 运行 在一个单独的进程中,您可以在其中自由使用 std::strings 等,但代价是更难以检查崩溃进程的状态。

关于 Mach 异常处理的文档很少,最好的参考是各种 open-source 崩溃报告框架。

总的来说,很难正确实现崩溃检测,我建议不要在插件中这样做。它比 SEH 复杂很多。