In the following code, the function foo
calls itself recursively once. The inner call causes an access violation to be raised. The outer call catches the exception.
#include <windows.h>
#include <stdio.h>
void foo(int cont)
{
__try
{
__try
{
__try
{
if (!cont)
*(int *)0 = 0;
foo(cont - 1);
}
__finally
{
printf("inner finally %d\n", cont);
}
}
__except (!cont? EXCEPTION_CONTINUE_SEARCH: EXCEPTION_EXECUTE_HANDLER)
{
printf("except %d\n", cont);
}
}
__finally
{
printf("outer finally %d\n", cont);
}
}
int main()
{
__try
{
foo(1);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
printf("main\n");
}
return 0;
}
The expected output here should be
inner finally 0
outer finally 0
inner finally 1
except 1
outer finally 1
However, outer finally 0
is conspicuously missing from the real output. Is this a bug or is there some detail I'm overlooking?
For completeness, happens with VS2015, compiling for x64. Surprisingly it doesn't happen on x86, leading me to believe that it is really a bug.
RaiseException
? – Overspend*(int*)0=0;
produces the instructionmov dword ptr [0],0
. SEH is a system service, and the OS makes the outcome well defined. – IchthyosisRaiseException
. – Q