Reputation: 143
I wrote code
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;
}
and i'm waiting for output
code1
code2
code4
but i have only
code1
and infinite loop.
Why is it?
adding volatile
keyname to s and j didn't fix it.
Upvotes: 0
Views: 2311
Reputation: 618
The infinite loop is caused because the exception is rethrown every time you resume execution. It doesn't matter that you set the value of s = 1
in the filter because the execution is resumed from the instruction that caused the trap, which in this case is the divide by zero. If you reorganize the code as follows you'll see that the exception is continually being thrown:
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;
}
The result should read:
before exception
exception filter with s = 0
exception filter with s = 1
exception filter with s = 2
...
The exception continues to be thrown because execution is resumed on the instruction that divides by zero, not on the instruction that loads the value of s. The steps are:
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
...
I don't think you'll be able to resume from that exception.
Upvotes: 4
Reputation: 2395
If you want the last part to execute try enclosing the whole thing in another
__try {
< your code>
}
__finally{
< code that will be executed at end>
}
For more information look here and here.
The line with 'code 2' would not be displayed because execution is interrupted by the exception on the previous line.
Upvotes: 0