EXCEPTION_CONTINUE_EXECUTION странное поведение

Я написал код

void SEHtest(int i) {
int s = 0;
__try {
cout << "code1" << endl;
int j = 1 / s;
cout << "code2" << endl;
} __except((s = 1, i)) {
cout << "code3" << endl;
}
cout << "code4" << endl;
return;
}
int main() {
SEHtest(-1);
return 0;
}

и я жду выхода

code1
code2
code4

но у меня есть только

code1

и бесконечный цикл.

Почему это?

добавление volatile keyname to s и j не исправили это.

0

Решение

Бесконечный цикл вызван тем, что исключение перезапускается каждый раз, когда вы возобновляете выполнение. Неважно, что вы устанавливаете значение s = 1 в фильтре, потому что выполнение возобновляется из инструкции, вызвавшей ловушку, которая в данном случае является делением на ноль. Если вы реорганизуете код следующим образом, вы увидите, что исключение постоянно генерируется:

int ExceptionFilter(int& s) {
cout << "exception filter with s = " << s << endl;
s++;
return -1; // EXCEPTION_CONTINUE_EXECUTION
}

void SEHtest() {
int s = 0;
__try {
cout << "before exception" << endl;
int j = 1 / s;
cout << "after exception" << endl;
} __except(ExceptionFilter(s)) {
cout << "exception handler" << endl;
}
cout << "after try-catch" << endl;
return;
}

int main() {
SEHtest();
return 0;
}

Результат должен гласить:

before exception
exception filter with s = 0
exception filter with s = 1
exception filter with s = 2
...

Исключение продолжает создаваться, потому что выполнение возобновляется по команде, которая делится на ноль, а не по команде, которая загружает значение s. Шаги:

1  set a register to 0
2  store that register in s (might be optimized out)
3  enter try block
4  output "before exception"5  load a register from s
6  divide 1 by register (trigger exception)
7  jump to exception filter
8  in filter increment/change s
9  filter returns -1
10 execution continues on line 6 above
6  divide 1 by register (trigger exception)
7  jump to exception filter
8  in filter increment/change s
9  filter returns -1
10 execution continues on line 6 above
...

Я не думаю, что вы сможете вернуться из этого исключения.

3

Другие решения

Если вы хотите, чтобы последняя часть была выполнена, попробуйте заключить ее в другую.

__try {
< your code>
}
__finally{
< code that will be executed at end>
}

Для получения дополнительной информации смотрите Вот а также Вот.

Строка с кодом 2 не будет отображаться, потому что выполнение прерывается исключением из предыдущей строки.

0

По вопросам рекламы [email protected]