简体   繁体   English

使用SEH(结构化异常处理)时观察到的不同行为

[英]Different behaviour observed when using SEH (structured exception handling)

I was doing some experiments with SEH. 我正在用SEH做一些实验。 In my code I wrote the error causing block in __try clause and a handler in __except(). 在我的代码中,我在__try子句中编写了导致错误的块,并在__except()中编写了处理程序。

__try{
Test *pTest = 0;
int k = pTest->GetValue();
cout << "continue after exception" << endl;
}
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION,EXCEPTION_EXECUTE_HANDLER)
{
 cout << "caught!!" << endl;
}
cout << "Exception handled" << endl;

The second parameter to __except() is either of these - __except()的第二个参数是以下任意一个-

EXCEPTION_CONTINUE_SEARCH Exception is not recognized. EXCEPTION_CONTINUE_SEARCH无法识别异常。 Continue to search up the stack for a handler, first for containing try-except statements, then for handlers with the next highest precedence. 继续在堆栈中搜索处理程序,首先是包含try-except语句,然后是具有次高优先级的处理程序。

EXCEPTION_CONTINUE_EXECUTION Exception is recognized but dismissed. EXCEPTION_CONTINUE_EXECUTION识别出异常,但将其消除。 Continue execution at the point where the exception occurred. 在发生异常的地方继续执行。

EXCEPTION_EXECUTE_HANDLER Exception is recognized. EXCEPTION_EXECUTE_HANDLER被识别为异常。 Transfer control to the exception handler by executing the __except compound statement, then continue execution at the point the exception occurred. 通过执行__except复合语句,将控制权转移到异常处理程序,然后在发生异常时继续执行。

When I use EXCEPTION_CONTINUE_EXECUTION/EXCEPTION_EXECUTE_HANDLER it does not continue execution at the point of exception occurrence (may be I am misinterpreting the meaning of point of exception occurrence). 当我使用EXCEPTION_CONTINUE_EXECUTION / EXCEPTION_EXECUTE_HANDLER时,它不会在异常发生时继续执行(可能是我误解了异常发生点的含义)。 When I run it in debug mode, the output is 当我在调试模式下运行它时,输出为

caught
Exception handled

When I run it in release mode, the output is 当我在发布模式下运行它时,输出为

continue after exception
Exception handled

I could not understand why it is behaving differently. 我不明白为什么它的行为方式有所不同。 Anyone please help. 有人请帮忙。

@Joachim points out correctly about the comma operator problem. @Joachim正确指出了有关逗号运算符的问题。

I think, the __except() should look like this: 我认为__except()应该看起来像这样:

__except((GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION) ?
         EXCEPTION_EXECUTE_HANDLER :
         EXCEPTION_CONTINUE_SEARCH)

This will make the exception handler execute if the exception is an access violation. 如果异常是访问冲突,这将使异常处理程序执行。 If it's not, the exception will propagate up to the closest outer __try , if any. 如果不是,则异常将传播到最近的外部__try (如果有)。

I'm fearing that pTest is a pointer to a class and it may not need to be dereferenced in order to execute GetValue() and the compiler recognizes that when optimizations are enabled in the release mode. 我担心pTest是指向类的指针,可能不需要取消引用即可执行GetValue() ,并且编译器会认识到在发布模式下启用优化时会意识到这一点。 Or maybe even it sees GetValue() as useless and does not generate any code to call it. 甚至可能它认为GetValue()无效,并且不生成任何代码来调用它。 It's also possible that the compiler sees that dereferencing a NULL pointer results in undefined behavior and decides to punish your for it at compile time by screwing with your code, it has every right to do it. 编译器也有可能看到取消引用NULL指针会导致未定义的行为,并决定在编译时通过拧入代码来惩罚它,它有权这样做。 gcc is notorious for doing it, for example. 例如,gcc就是臭名昭著的。

The expression 表达方式

GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION,EXCEPTION_EXECUTE_HANDLER

doesn't do what you expect it to. 不按照您的期望去做。 What it does is compare the result of GetExceptionCode() with EXCEPTION_ACCESS_VIOLATION , but the result of the whole expression is EXCEPTION_EXECUTE_HANDLER . 它所做的是将GetExceptionCode()的结果与EXCEPTION_ACCESS_VIOLATION进行比较,但整个表达式的结果为EXCEPTION_EXECUTE_HANDLER

Read more about the comma operator at Wikipedia . 在Wikipedia上了解有关逗号运算符的更多信息。

What you want to do is, probably: 您想做的可能是:

GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION || GetExceptionCode() == EXCEPTION_EXECUTE_HANDLER

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM