macos - 处理 64 位 OS X 应用程序中的马赫异常

标签 macos osx-snow-leopard darwin

我已经能够注册自己的 mach 端口来捕获应用程序中的 mach 异常,并且当我以 32 位为目标时,它可以完美地工作。但是,当我以 64 位为目标时,我的异常处理程序 catch_exception_raise()被调用,但传递给处理程序的异常代码数组是 32 位宽。这在 32 位版本中是预期的,但在 64 位版本中则不然。

在我捕获 EXC_BAD_ACCESS 的情况下第一个代码是错误编号,第二个代码应该是故障地址。由于第二个代码是 32 位宽,因此 64 位故障地址的高 32 位被截断。

我在<mach/exception_types.h>中找到了一个标志我可以传入task_set_exception_ports()MACH_EXCEPTION_CODES从 Darwin 的资料来看,它似乎控制着传递给处理程序的代码的大小。看起来它应该与传入 task_set_exception_ports() 的行为进行处理。 .

但是,当我这样做并触发异常时,我的马赫端口会收到通知,我调用 exc_server()但我的处理程序永远不会被调用,当回复消息发送回内核时,我会得到默认的异常行为。

我的目标是 10.6 SDK。

我真的希望苹果能更好地记录这些东西。有人有什么想法吗?

最佳答案

好吧,我明白了。

要处理 mach 异常,您必须为您感兴趣的异常注册一个 mach 端口。然后,您在另一个线程中等待消息到达该端口。当消息到达时,您调用 exc_server() ,其实现由 System.library 提供。 exec_server() 获取到达的消息并调用您必须提供的三个处理程序之一。 catch_exception_raise()catch_exception_raise_state()catch_exception_raise_state_identity(),具体取决于您传递给 task_set_exception_ports() 的参数。这就是 32 位应用程序的做法。

对于 64 位应用程序,32 位方法仍然有效,但在处理程序中传递给您的数据可能会被截断为 32 位。要将 64 位数据传递给处理程序需要一些额外的工作,这不是很直接,而且据我所知,没有很好的文档记录。我通过查看 GDB 的源代码偶然发现了该解决方案。

当消息到达端口时,您不必调用 exc_server(),而是必须调用 mach_exc_server()。处理程序还必须具有不同的名称,以及 catch_mach_exception_raise()catch_mach_exception_raise_state()catch_mach_exception_raise_state_identity()。处理程序的参数与其 32 位对应参数相同。 问题是 mach_exc_server() 没有像 exc_server() 那样为您提供。要实现 mach_exc_server() 需要使用 MIG(Mach Interface Generator)实用程序。 MIG 采用接口(interface)定义文件并生成一组源文件,其中包括一个服务器函数,该函数将 mach 消息分派(dispatch)给您提供的处理程序。 10.5 和 10.6 SDK 包含用于异常消息的 MIG 定义文件 ,并将生成 mach_exc_server() 函数。然后,您可以将生成的源文件包含在您的项目中,然后就可以开始了。

好的一点是,如果您的目标是 10.6+(也许是 10.5),您可以对 32 位和 64 位使用相同的异常处理。当您设置异常端口时,只需将异常行为与 MACH_EXCEPTION_CODES 进行“或”操作即可。异常代码将以 64 位值的形式出现,但您可以在 32 位版本中将它们截断为 32 位。

我获取了 mach_exc.defs 文件并将其复制到我的源目录,打开终端并使用命令 mig -v mach_exc.defs。这会生成 mach_exc.hmach_excServer.cmach_excUser.c。然后,我将这些文件包含在我的项目中,在我的源文件中添加了服务器函数的正确声明并实现了我的处理程序。然后我构建了我的应用程序并且一切顺利。

嗯,这不是最好的描述,但希望它对其他人有帮助。

关于macos - 处理 64 位 OS X 应用程序中的马赫异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2824105/

相关文章:

c - 在 macOS 上从 dev_t 获取设备文件系统路径

ruby-on-rails - 在 Mountain Lion 上使用 Homebrew 和 Rails 安装 postgresql

java - 如何在 OSX 10.9.4 上安装 Eclipse

cocoa - iTunes Scripting Bridge 显示不起作用

osx-snow-leopard - 是否有一种标准方法可以告诉 brew(Mac OS 的 Homebrew 软件包管理器)构建组合的 32/64 位二进制文​​件?

cocoa - 更改 cocoa 中标题栏的颜色

c++ - Macintosh OS X Mavericks 上/proc/self/exe 的等价物是什么?

linux - 适用于 Mac OS X 或 Linux 的 Java Micro Edition (JME) SDK

c - 如何在没有 XCode IDE 的情况下在 Mac Leopard 上用 C 进行编程?

macos - 安装 Valgrind 时 make 失败