我应该在C++中了解结构化异常(SEH)?

And*_*w T 42 c++ exception-handling exception seh structured-exception

每个C++开发人员都应该知道哪些关于结构化异常的重要观点?

Ben*_*igt 40

它们是Win32,相当于Unix信号,让你捕获CPU异常,例如访问冲突,非法指令,除以零.

使用正确的编译器选项(/ EHa for Visual C++),C++异常使用相同的机制,因为堆栈展开适用于C++(用户)异常和SEH(OS)异常.

与C++异常不同,SEH不是类型化的,但它们共享相同的数据结构,该结构具有异常代码(原因)以及有关哪些代码出现故障以及CPU寄存器在故障时保留的内容的附加信息.见GetExceptionCodeGetExceptionInformation更多这方面的细节.

此外,SEH具有"第一次机会"处理,允许您展开之前记录或以其他方式处理异常,从而破坏所有局部变量.

  • 解除访问冲突没有什么本质上不安全的.当然,如果访问冲突是由内部数据结构的损坏(特别是影响调用堆栈信息的堆栈溢出)引起的,那么展开可能会失败,但很多(如果不是大多数)SEH异常实际上并不反映堆栈腐败. (5认同)

小智 31

我最近有一个由SEH间接引起的问题,特别是因为我认为每个开发人员都应该注意SEH的一个特性:

当使用SEH时,不会调用析构函数,因此如果在析构函数中有清理代码,则不会清除它.

我们的问题是由一个关键部分引起的,该部分由一个在构造函数中使用Lock并在析构函数中解锁的对象包装.

我们有一个死锁的情况,无法弄清楚为什么,经过大约一个星期的挖掘代码和转储和调试后我们终于明白这是因为有一个异常由COM处理并导致Critical部分保持锁定.我们在项目属性中更改了VS中的编译标志,告诉它甚至为SEH运行析构函数并解决了问题.

因此,即使您可能不在代码中使用SEH,您可能正在使用一个(如COM)并且可能导致意外行为的库.


小智 24

他们应该知道它们不是标准C++的一部分 - 它们是Microsoft的发明,可以用于C++以外的语言.


Rem*_*anu 20

关于Win32™结构化异常处理深度的速成课程

那篇文章是关于加快SEH速度参考.13年后,仍然是最好的.

有关SEH与C++异常处理差异的 MSDN上有一个专门的主题.

如果正在讨论SEH,C++开发人员应该知道的一些事情:

编写C/C++ SEH 异常处理程序:

__try 
{
   // guarded code
}
__except ( expression )
{
   // exception handler code
}
Run Code Online (Sandbox Code Playgroud)

不是 C++异常处理,是用于直接连接SEH的MS特定扩展.它的工作方式与普通的C++异常完全不同.您需要很好地了解SEH才能使用这些.

编写C/C++ SEH 终止处理程序:

__try {
   // guarded code
}
__finally ( expression ) {
   // termination code
}
Run Code Online (Sandbox Code Playgroud)

与SEH处理程序相同,不要将其与C++异常语义混淆.你需要对SEH有一个很好的理解.

_set_se_trasnlator:这是在使用异步异常/ EHa时将SEH异常转换为C++类型异常的函数.

最后,个人意见:C++开发人员应该知道SEH吗?在你的第一个菜鸟.ecxr之后,你会明白当推动C++时,异常仅仅是为了你的方便提供的错觉.唯一发生的事情是SEH.

  • `__finally`没有`(表达式)` (10认同)