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

时间:2013-02-26 10:48:42

标签: c++ windows exception seh

我正在用SEH做一些实验。在我的代码中,我在__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;

__except()的第二个参数是 -

EXCEPTION_CONTINUE_SEARCH无法识别异常。继续在堆栈中搜索一个处理程序,首先是包含try-except语句,然后是下一个最高优先级的处理程序。

EXCEPTION_CONTINUE_EXECUTION异常被识别但被驳回。在异常发生的地方继续执行。

EXCEPTION_EXECUTE_HANDLER识别异常。通过执行__except复合语句将控制转移到异常处理程序,然后在异常发生时继续执行。

当我使用EXCEPTION_CONTINUE_EXECUTION / EXCEPTION_EXECUTE_HANDLER时,它不会在异常发生时继续执行(可能是我误解了异常发生点的含义)。 当我在调试模式下运行它时,输出是

caught
Exception handled

当我在发布模式下运行时,输出为

continue after exception
Exception handled

我无法理解为什么表现不同。有人请帮忙。

2 个答案:

答案 0 :(得分:4)

@Joachim正确指出了逗号运算符问题。

我认为,__except()应如下所示:

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

如果异常是访问冲突,这将使异常处理程序执行。如果不是,则异常将传播到最近的外部__try,如果有的话。

我担心pTest是指向类的指针,为了执行GetValue(),可能不需要取消引用它,并且编译器会识别出在发布模式下启用优化时。或者甚至可能将GetValue()视为无用,并且不会生成任何代码来调用它。编译器也可能看到解除引用NULL指针会导致未定义的行为,并决定在编译时通过拧紧代码来惩罚它,它完全有权这样做。例如,gcc因这样做而臭名昭着。

答案 1 :(得分:1)

表达式

GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION,EXCEPTION_EXECUTE_HANDLER

不符合您的预期。它的作用是将GetExceptionCode()的结果与EXCEPTION_ACCESS_VIOLATION进行比较,但整个表达式的结果为EXCEPTION_EXECUTE_HANDLER

详细了解逗号运算符at Wikipedia

你想做的事情可能是:

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