EXCEPTION_CONTINUE_EXECUTION strange behavour

2.1k views Asked by At

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.

2

There are 2 answers

1
JP Flouret On BEST ANSWER

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.

2
DNT On

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.