在什么情况下EXCEPTION_RECORD链接到另一个嵌套异常?

时间:2018-08-09 10:01:46

标签: c++ exception structured-exception nested-exceptions

_EXCEPTION_RECORD的{​​{3}}说出其中一个成员struct _EXCEPTION_RECORD *ExceptionRecord

  

指向关联的EXCEPTION_RECORD结构的指针。可以将异常记录链接在一起,以在发生嵌套异常时提供其他信息。

但是,我无法引发这种嵌套结构化异常的情况。到目前为止,这是我尝试过的:

#include <iostream>
#include <windows.h>

void Handle0(LPEXCEPTION_POINTERS pex) {
    std::cout << "chain0 = " << pex->ExceptionRecord->ExceptionRecord << std::endl;
}

void Handle1(LPEXCEPTION_POINTERS pex) {
    std::cout << "chain1 = " << pex->ExceptionRecord->ExceptionRecord << std::endl;
    __try {
        throw 3;
    } __except( Handle0(GetExceptionInformation()), EXCEPTION_EXECUTE_HANDLER ) {}
}

int main() {
    __try {
        throw 3;
    } __except( Handle1(GetExceptionInformation()), EXCEPTION_EXECUTE_HANDLER ) {}
    return 0;
}

pex->ExceptionRecord->ExceptionRecord始终为nullptr。在什么情况下我可以链接到那里的嵌套_EXCEPTION_RECORD

1 个答案:

答案 0 :(得分:0)

根据MSDN

在处理异常期间引发异常时 在...本机代码中过滤...引发嵌套异常, ExceptionRecord结构中的EXCEPTION_RECORD字段(返回 GetExceptionInformation)设置,并且ExceptionFlags字段设置 0x10位。以下示例说明了这种差异 行为:

#include <windows.h>
#include <stdio.h>
#include <assert.h>

#ifndef false
#define false 0
#endif

int *p;

int filter(PEXCEPTION_POINTERS ExceptionPointers) {
   PEXCEPTION_RECORD ExceptionRecord =
                     ExceptionPointers->ExceptionRecord;

   if ((ExceptionRecord->ExceptionFlags & 0x10) == 0) {
      // not a nested exception, throw one
      *p = 0; // throw another AV
   }
   else {
      printf("Caught a nested exception\n");
      return 1;
    }

   assert(false);

   return 0;
}

void f(void) {
   __try {
      *p = 0;   // throw an AV
   }
   __except(filter(GetExceptionInformation())) {
      printf_s("We should execute this handler if "
                 "compiled to native\n");
    }
}

int main() {
   __try {
      f();
   }
   __except(1) {
      printf_s("The handler in main caught the "
               "exception\n");
    }
}

我认为,如果您尝试继续不可延续的异常,也会设置该值。在这种情况下,EXCEPTION_RECORD将代表EXCEPTION_NONCONTINUABLE_EXCEPTION,而其ExceptionRecord将指向原始异常。