关于c++中的结构化异常(SEH),我应该了解什么?

时间:2022-09-11 10:31:46

What important points about Structured Exceptions should every C++ developer know?

每一个c++开发人员都知道什么是结构化异常的重要点?

4 个解决方案

#1


37  

They are the Win32 equivalent to Unix signals, and let you catch CPU exceptions such as access violation, illegal instruction, divide by zero.

它们是等同于Unix信号的Win32,允许您捕获CPU异常,例如访问违规、非法指令,除以0。

With the right compiler options (/EHa for Visual C++), C++ exceptions use the same mechanism as stack unwinding works properly for both C++ (user) exceptions and SEH (OS) exceptions.

对于正确的编译器选项(Visual c++的/EHa), c++异常使用与堆栈展开相同的机制,对于c++异常和SEH (OS)异常都能正常工作。

Unlike C++ exceptions, SEH are not typed but all share the same data structure which has an exception code (the cause) and additional information on what code faulted and what the CPU registers held at the time of the fault. See GetExceptionCode and GetExceptionInformation for more details on this.

与c++异常不同,SEH不是类型化的,而是共享相同的数据结构,该结构具有异常代码(原因)和关于哪些代码出错以及在故障发生时CPU寄存器保存了什么信息。有关这方面的详细信息,请参阅GetExceptionCode和GetExceptionInformation。

Also, SEH has "first-chance" handling, which allows you to log or otherwise handle the exception before unwinding destroys all the local variables.

此外,SEH具有“第一次机会”处理,允许您在展开破坏所有本地变量之前记录或以其他方式处理异常。

#2


26  

I recently had a problem which was caused indirectly by SEH, specifically because of one feature of SEH which I think every developer should be aware of:

我最近遇到了一个由SEH间接导致的问题,特别是因为SEH的一个特性,我认为每个开发者都应该意识到:

When SEH is used destructors are not called, so if you have cleanup code in your destructor it will not be cleaned up.

当SEH被使用时,析构函数没有被调用,因此如果您的析构函数中有清除代码,它将不会被清除。

Our problem was caused by a Critical Section that was wrapped by an object with Lock in the constructor and Unlock in the destructor.

我们的问题是由一个在构造函数中带有锁的对象和在析构函数中解锁的关键部分所引起的。

We had a deadlock situation and couldn't figure out why, and after about a week of digging through the code and dumps and debugging we finally understood it was because there was an exception that was handled by COM and causing the Critical section to stay locked. We changed a compilation flag in VS in the project properties which tell it to run destructors even for SEH and that solved the problem.

我们有一个死锁的情况,不知道为什么,在经过了大约一周的代码、转储和调试之后,我们终于理解了这一点,因为COM处理了一个异常,导致关键部分保持锁定。我们在项目属性的VS中更改了一个编译标志,它告诉它运行析构函数,即使是SEH,这也解决了问题。

So even though you may not use SEH in your code, you may be using a library that does (like COM) and that can cause unexpected behavior.

因此,即使您可能在代码中不使用SEH,但是您可能正在使用一个库(比如COM),它可能会导致意外的行为。

#3


23  

They should know that they are not part of Standard C++ - they are Microsoft invention and can be used in languages other than C++.

他们应该知道,它们不是标准c++的一部分——它们是微软的发明,可以在c++以外的语言中使用。

#4


18  

A Crash Course on the Depths of Win32™ Structured Exception Handling

速成班的深处Win32™结构化异常处理

That article is the reference on getting up to speed with SEH. 13 years later, is still the best there is.

那篇文章是关于如何赶上SEH的参考文献。13年后的今天,仍然是最好的。

There is a dedicated topic on MSDN for SEH vs. C++ Exception Handling Differences.

对于SEH与c++异常处理差异,MSDN上有一个专门的主题。

Some things a C++ developer should know if SEH is being discussed:

c++开发人员应该知道SEH是否正在被讨论:

Writing C/C++ SEH Exception Handlers:

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

__try 
{
   // guarded code
}
__except ( expression )
{
   // exception handler code
}

This is not C++ exception handling, is the MS specific extensions for hooking straight inot SEH. It works very differently from your run-of-the-mill C++ exceptions. You need a good understanding of SEH to use these.

这不是c++异常处理,而是MS特定的扩展,用于直接连接到inot SEH。它的工作方式与普通的c++异常非常不同。您需要对SEH有很好的理解才能使用它们。

Writing C/C++ SEH Termination Handlers:

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

__try {
   // guarded code
}
__finally ( expression ) {
   // termination code
}

Same as with the SEH handler, do not confuse this with C++ exception semantics. You need a good understanding of SEH.

与SEH处理程序一样,不要将其与c++异常语义混淆。你需要很好的理解SEH。

_set_se_trasnlator: this is the function that translates SEH exceptions into C++ type exceptions when asynchronous exceptions are used /EHa.

_set_se_trasn化子:当使用异步异常/EHa时,这个函数将SEH异常转换为c++类型异常。

And finally, a personal opinion: should a C++ developer know SEH? After your first rookie .ecxr you'll understand that when the push come to shove C++ exceptions are just an illusion provided for your convenience. The only thing going on is SEH.

最后,我个人的意见是:c++开发人员应该知道SEH吗?在您的第一个新手。ecxr之后,您将了解到,当出现问题时,c++异常只是为您提供方便的错觉。唯一发生的事情是SEH。

#1


37  

They are the Win32 equivalent to Unix signals, and let you catch CPU exceptions such as access violation, illegal instruction, divide by zero.

它们是等同于Unix信号的Win32,允许您捕获CPU异常,例如访问违规、非法指令,除以0。

With the right compiler options (/EHa for Visual C++), C++ exceptions use the same mechanism as stack unwinding works properly for both C++ (user) exceptions and SEH (OS) exceptions.

对于正确的编译器选项(Visual c++的/EHa), c++异常使用与堆栈展开相同的机制,对于c++异常和SEH (OS)异常都能正常工作。

Unlike C++ exceptions, SEH are not typed but all share the same data structure which has an exception code (the cause) and additional information on what code faulted and what the CPU registers held at the time of the fault. See GetExceptionCode and GetExceptionInformation for more details on this.

与c++异常不同,SEH不是类型化的,而是共享相同的数据结构,该结构具有异常代码(原因)和关于哪些代码出错以及在故障发生时CPU寄存器保存了什么信息。有关这方面的详细信息,请参阅GetExceptionCode和GetExceptionInformation。

Also, SEH has "first-chance" handling, which allows you to log or otherwise handle the exception before unwinding destroys all the local variables.

此外,SEH具有“第一次机会”处理,允许您在展开破坏所有本地变量之前记录或以其他方式处理异常。

#2


26  

I recently had a problem which was caused indirectly by SEH, specifically because of one feature of SEH which I think every developer should be aware of:

我最近遇到了一个由SEH间接导致的问题,特别是因为SEH的一个特性,我认为每个开发者都应该意识到:

When SEH is used destructors are not called, so if you have cleanup code in your destructor it will not be cleaned up.

当SEH被使用时,析构函数没有被调用,因此如果您的析构函数中有清除代码,它将不会被清除。

Our problem was caused by a Critical Section that was wrapped by an object with Lock in the constructor and Unlock in the destructor.

我们的问题是由一个在构造函数中带有锁的对象和在析构函数中解锁的关键部分所引起的。

We had a deadlock situation and couldn't figure out why, and after about a week of digging through the code and dumps and debugging we finally understood it was because there was an exception that was handled by COM and causing the Critical section to stay locked. We changed a compilation flag in VS in the project properties which tell it to run destructors even for SEH and that solved the problem.

我们有一个死锁的情况,不知道为什么,在经过了大约一周的代码、转储和调试之后,我们终于理解了这一点,因为COM处理了一个异常,导致关键部分保持锁定。我们在项目属性的VS中更改了一个编译标志,它告诉它运行析构函数,即使是SEH,这也解决了问题。

So even though you may not use SEH in your code, you may be using a library that does (like COM) and that can cause unexpected behavior.

因此,即使您可能在代码中不使用SEH,但是您可能正在使用一个库(比如COM),它可能会导致意外的行为。

#3


23  

They should know that they are not part of Standard C++ - they are Microsoft invention and can be used in languages other than C++.

他们应该知道,它们不是标准c++的一部分——它们是微软的发明,可以在c++以外的语言中使用。

#4


18  

A Crash Course on the Depths of Win32™ Structured Exception Handling

速成班的深处Win32™结构化异常处理

That article is the reference on getting up to speed with SEH. 13 years later, is still the best there is.

那篇文章是关于如何赶上SEH的参考文献。13年后的今天,仍然是最好的。

There is a dedicated topic on MSDN for SEH vs. C++ Exception Handling Differences.

对于SEH与c++异常处理差异,MSDN上有一个专门的主题。

Some things a C++ developer should know if SEH is being discussed:

c++开发人员应该知道SEH是否正在被讨论:

Writing C/C++ SEH Exception Handlers:

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

__try 
{
   // guarded code
}
__except ( expression )
{
   // exception handler code
}

This is not C++ exception handling, is the MS specific extensions for hooking straight inot SEH. It works very differently from your run-of-the-mill C++ exceptions. You need a good understanding of SEH to use these.

这不是c++异常处理,而是MS特定的扩展,用于直接连接到inot SEH。它的工作方式与普通的c++异常非常不同。您需要对SEH有很好的理解才能使用它们。

Writing C/C++ SEH Termination Handlers:

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

__try {
   // guarded code
}
__finally ( expression ) {
   // termination code
}

Same as with the SEH handler, do not confuse this with C++ exception semantics. You need a good understanding of SEH.

与SEH处理程序一样,不要将其与c++异常语义混淆。你需要很好的理解SEH。

_set_se_trasnlator: this is the function that translates SEH exceptions into C++ type exceptions when asynchronous exceptions are used /EHa.

_set_se_trasn化子:当使用异步异常/EHa时,这个函数将SEH异常转换为c++类型异常。

And finally, a personal opinion: should a C++ developer know SEH? After your first rookie .ecxr you'll understand that when the push come to shove C++ exceptions are just an illusion provided for your convenience. The only thing going on is SEH.

最后,我个人的意见是:c++开发人员应该知道SEH吗?在您的第一个新手。ecxr之后,您将了解到,当出现问题时,c++异常只是为您提供方便的错觉。唯一发生的事情是SEH。