64位的Windows ABI定义了一个通用的exception处理机制 ,我相信这个机制是跨C ++exception和结构化exception共享的,即使在其他语言中也是如此。
如果我正在编写x86-64汇编程序以在nasm
编译并链接到C或C ++库,那么在生成展开信息等方面,我需要在Windows上进行哪些调整?
我不打算直接在汇编代码中生成任何exception,但我想如果用户提供的缓冲区是无效的,代码可能会得到访问冲突。
我希望尽可能最less的写这个工作,特别是因为看起来nasm
对生成展开信息的支持很差,使用MASM
不是这个跨平台项目的一个选项。 我确实需要使用(因此保存和恢复)非易失性寄存器。
作为一般规则,Windows x64需要所有功能来提供展开信息。 唯一的例外是不修改rsp
叶函数,也不修改任何非易失性寄存器。
从您的问题的上下文来看,您真正想知道的是不为您的x64 Windows上的非叶装配函数提供展开信息的实际后果。 由于C ++异常是基于SEH异常实现的,所以当我讨论下面的异常时,我的意思是所有的“本地”(访问冲突,抛出使用RaiseException
等等)和C ++异常。 这是我头顶的一个列表:
请注意,这一点很重要,不是抛出异常,或者直接在函数中发生访问冲突。 假设你的汇编代码调用了一个C ++函数,它引发了一个异常。 即使你的程序集函数的调用者有一个匹配的catch
块,它也将永远无法捕捉异常,因为在没有展开数据的情况下,展开将停止在你的函数中。
基本上,如果你的函数出现在调用堆栈上(调试器在显示调用栈,分析器等时)
Unhandled Exception Filters
将不会被回调,如果一个异常被抛出,并且你的汇编函数在调用堆栈上 这干扰了任何依赖于UEFs的东西。 自定义的崩溃处理程序,例如。 或者更相关的东西: std::terminate
在这种情况下不会被调用,如果你的程序抛出了一个C ++异常,那是未处理的(因为它是由C ++标准决定的)。 MSVC运行时使用UEF来实现这一点,所以这不会工作。
你在开发第三方库吗? 如果是这样的话,以上几点的重要性将取决于客户的使用情况。