c++ - 嵌套 __try...__ except 子句,这是如何工作的?

标签 c++ try-catch seh

我正在处理一个函数和一个子函数,子函数在函数内被调用。两者都有一个 __try .. __ except 子句,我想看看函数的一般异常处理,以及子函数的具体异常处理,换句话说:

int function(){
__try{
  do_something();
  return subfunction();
  } __except (Exception_Execute_Handler_Something()){
  show("general exception");
  }

int subfunction(){
  __try{
    return do_something_else();
  } __except (Exception_Execute_Handler_Something_Else()){
    show("specific case");
  }

在这种情况下:
do_something() 出错时,我会看到“一般异常”。
do_something_else() 出错时,我也会看到“一般异常”,这不是我想要的。

我想要的是:
do_something() 出错时,我想看到“一般异常。
do_something_else() 出错时,我想查看“具体案例”。

根据本·沃伊特的评论进行编辑

确实有一个异常过滤器,当前正在检查异常代码以决定是否继续,如下所示:

if (Exception->ExceptionCode == STATUS_ACCESS_VIOLATION)
  return EXCEPTION_CONTINUE_SEARCH;

但是,我对异常处理的两个输入参数ExceptionRecordContextRecord的结构和/或内容一无所知。在此,我举例说明了这些参数在我的特定情况下的样子:

异常记录:

-   ExceptionRecord 0x0eecdec8 {ExceptionCode=3221225620 ExceptionFlags=0 ExceptionRecord=0x00000000 <NULL> ...}    _EXCEPTION_RECORD *
    ExceptionCode   3221225620  unsigned long // I guess this means division by zero
    ExceptionFlags  0   unsigned long
+   ExceptionRecord 0x00000000 <NULL>   _EXCEPTION_RECORD *
    ExceptionAddress    0x002c1993 {<Application>.exe!CClass::Main_Method(CInputClass & params), Line 46}   void *
    NumberParameters    0   unsigned long
+   ExceptionInformation    0x0eecdedc {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}    unsigned long[15]

上下文记录:

-   ContextRecord   0x0eecdf18 {ContextFlags=65543 Dr0=0 Dr1=0 ...} _CONTEXT *
    ContextFlags    65543   unsigned long
    Dr0 0   unsigned long
    Dr1 0   unsigned long
    Dr2 0   unsigned long
    Dr3 0   unsigned long
    Dr6 0   unsigned long
    Dr7 0   unsigned long
-   FloatSave   {ControlWord=0 StatusWord=0 TagWord=0 ...}  _FLOATING_SAVE_AREA
    ControlWord 0   unsigned long
    StatusWord  0   unsigned long
    TagWord 0   unsigned long
    ErrorOffset 0   unsigned long
    ErrorSelector   0   unsigned long
    DataOffset  0   unsigned long
    DataSelector    0   unsigned long
+   RegisterArea    0x0eecdf50 ""   unsigned char[80] // all are zero
    Spare0  0   unsigned long
    SegGs   43  unsigned long
    SegFs   83  unsigned long
    SegEs   43  unsigned long
    SegDs   43  unsigned long
    Edi 80923496    unsigned long
    Esi 250405956   unsigned long
    Ebx 0   unsigned long
    Edx 0   unsigned long
    Ecx 0   unsigned long
    Eax 1   unsigned long
    Ebp 250405884   unsigned long
    Eip 2890131 unsigned long
    SegCs   35  unsigned long
    EFlags  66118   unsigned long
    Esp 250405880   unsigned long
    SegSs   43  unsigned long
+   ExtendedRegisters   0x0eecdfe4 "\x2 \x1"    unsigned char[512] // at first sight, not readable

现在我的问题变成了:

如果我已经在另一个 __try..__ except 子句中,我会返回 EXCEPTION_CONTINUE_SEARCH

有谁知道我可以使用上面提到的 ExceptionRecord 或 ContextRecord 属性中的哪一个来确定我是否已经在另一个__try..__ except 中子句?

再次提供更多信息后进行新编辑

我刚刚发现EXCEPTION_DISPOSITION,存在于C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.16.27023\include\excpt.h。其中包含函数_except_handler(),它返回一个EXCEPTION_DISPOSITION枚举,它可以是ExceptionNestedException(我相信这就是我正在寻找的)为)。
那么现在问题就变成了:

What parameters do I need to fill in in the function _except_handler() in order to know if I'm dealing with a nested exception (or does somebody know an easier way to get this done)?

最佳答案

您编写的代码无法编译。而不是:

__except { ... }

你需要:

__except (EXCEPTION_EXECUTE_HANDLER) { ... }

然后它就会按预期工作。

Live demo

关于c++ - 嵌套 __try...__ except 子句,这是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56282869/

相关文章:

erlang - 如何在Erlang中进行尝试/捕获

c++ - 在 Visual Studio 2010 中混合使用异常处理模型会产生什么后果?

Java C++代码转换

c++ - 如何通过 QSqlTableModel 保存更改数据库?

java - 从 try 中获取一个变量

windows - C++ try-catch block 不捕获硬件异常

c - C 中未调用异常处理程序

c++ - 为什么程序会无限循环?

c++ - 关于 C/C++ 编译器优化,我可以假设什么?

c++ - 读取功能失败时的成功消息