При каких обстоятельствах EXCEPTION_RECORD ссылается на другое вложенное исключение?
Документация для _EXCEPTION_RECORD
говорит об одном из его членов, 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
там?
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
укажет на исходное исключение.