查看 Objective-C 运行时系统源代码,特别是在objc-exception.mm文件中,我发现了表达式“alt handler”和处理 alt 处理程序的函数。我不知道它是什么,但是根据文件注释,如果运行时库是在没有 alt 处理程序支持的情况下编译的,那么只有 zerocost 实现,我也不知道是什么。
那么,当我们谈论 Objective-C 运行时库时,什么是 alt 处理程序,什么是零成本异常处理?
查看 Objective-C 运行时系统源代码,特别是在objc-exception.mm文件中,我发现了表达式“alt handler”和处理 alt 处理程序的函数。我不知道它是什么,但是根据文件注释,如果运行时库是在没有 alt 处理程序支持的情况下编译的,那么只有 zerocost 实现,我也不知道是什么。
那么,当我们谈论 Objective-C 运行时库时,什么是 alt 处理程序,什么是零成本异常处理?
Objective-C 运行时库允许开发人员在系统第二次展开堆栈时指定每个堆栈帧调用的函数,在清理阶段,在它找到刚刚抛出的异常的 catch 子句之后。
因此,对于熟悉 Unwind 库和 ObjC 异常处理系统的人来说,当__objc_personality_v0
针对当前堆栈帧的 Unwind Context 调用Objective-C 个性例程(语境。如果找到 alt 处理程序,则首先调用它。此后,由于 ObjC 异常处理机制使用 C++ ABI 展开堆栈,因此调用 cxx 个性函数 ( __gxx_personality_v0
)。然而,只有在清理阶段而不是搜索阶段调用 objc 个性例程时才会这样做。因此,如果没有找到当前异常的 catch 子句,则不会调用 alt 处理程序(如果有)。
关于零成本部分,cxx 个性函数使用了零成本的异常处理。因此,如果在没有 alt 处理程序支持的情况下编译运行时库,则只有零成本实现,因为__gxx_personality_v0
无论如何都会调用。
Objective-C 库公共 API 提供了两个函数来分别为特定的 Unwind Context:objc_addExceptionHandler
和添加和删除 alt 处理程序objc_removeExceptionHandler
。
路易斯,你是对的,因为有一个函数存储在这个函数上,当抛出异常时,该函数被调用,但是如果找不到异常处理程序,程序会自动终止,你是不正确的(这有点更有趣比起那个来说)。触发异常的那一刻(错误的内存读取,div 为 0,等等),操作系统 (windows/*nix) 会查看其已安装的异常处理程序链并调用它找到的第一个(通过try{}catch{}
堵塞。现在,如果尚未编程,则执行默认处理程序,在大多数情况下,这会结束程序并执行堆栈展开。在内核模式编程中,如果您不安装自己的处理程序,则可以对整个系统进行段错误处理,默认的异常处理程序仅在大部分情况下提供给用户模式程序。
我可以为你写一个非常长的答案,但我为你找到了一个完美的网站,我认为它有助于回答你的问题,这将有助于理解你可以在编译器级别实现异常处理程序的不同方式,特别是回答你的“零成本”异常处理程序和代码中的 SJLJ 技术说明: