|
|
/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
xcpt4.c
Abstract:
This module implements user mode exception tests.
Author:
David N. Cutler (davec) 18-Sep-1990
Environment:
Kernel mode only.
Revision History:
--*/
#include "ki.h"
#pragma hdrstop
#include "setjmpex.h"
#include "float.h"
#pragma warning(disable:4532)
#pragma warning(disable:4702) // unreachable code
#pragma optimize("",off)
//
// Define switch constants.
//
#define BLUE 0
#define RED 1
//
// Define guaranteed fault.
//
#define FAULT *(volatile int *)0
//
// Define function prototypes.
//
VOID addtwo ( IN LONG First, IN LONG Second, IN PLONG Place );
VOID bar1 ( IN NTSTATUS Status, IN PLONG Counter );
VOID bar2 ( IN PLONG BlackHole, IN PLONG BadAddress, IN PLONG Counter );
ULONG64 Catch ( IN PEXCEPTION_RECORD ExceptionRecord );
VOID dojump ( IN jmp_buf JumpBuffer, IN PLONG Counter );
LONG Echo( IN LONG Value );
VOID eret ( IN NTSTATUS Status, IN PLONG Counter );
VOID except1 ( IN PLONG Counter );
ULONG except2 ( IN PEXCEPTION_POINTERS ExceptionPointers, IN PLONG Counter );
ULONG except3 ( IN PEXCEPTION_POINTERS ExceptionPointers, IN PLONG Counter );
VOID foo1 ( IN NTSTATUS Status );
VOID foo2 ( IN PLONG BlackHole, IN PLONG BadAddress );
VOID fret ( IN PLONG Counter );
BOOLEAN Tkm ( VOID );
VOID Test61Part2 ( IN OUT PLONG Counter );
VOID PerformFpTest( VOID );
double SquareDouble ( IN double op );
VOID SquareDouble17E300 ( OUT PVOID ans );
LONG test66sub ( IN PLONG Counter );
LONG test67sub ( IN PLONG Counter );
VOID xcpt4 ( VOID )
{
PLONG BadAddress; PCHAR BadByte; PLONG BlackHole; LONG Index1; ULONG Index2 = RED; jmp_buf JumpBuffer; LONG Counter; EXCEPTION_RECORD ExceptionRecord; double doubleresult;
//
// Announce start of exception test.
//
DbgPrint("Start of exception test\n");
//
// Initialize exception record.
//
ExceptionRecord.ExceptionCode = STATUS_INTEGER_OVERFLOW; ExceptionRecord.ExceptionFlags = 0; ExceptionRecord.ExceptionRecord = NULL; ExceptionRecord.NumberParameters = 0;
//
// Initialize pointers.
//
BadAddress = (PLONG)NULL; BadByte = (PCHAR)NULL; BadByte += 1; BlackHole = &Counter;
//
// Simply try statement with a finally clause that is entered sequentially.
//
DbgPrint(" test1..."); Counter = 0; try { Counter += 1;
} finally { if (abnormal_termination() == FALSE) { Counter += 1; } }
if (Counter != 2) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Simple try statement with an exception clause that is never executed
// because there is no exception raised in the try clause.
//
DbgPrint(" test2..."); Counter = 0; try { Counter += 1;
} except (Counter) { Counter += 1; }
if (Counter != 1) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Simple try statement with an exception handler that is never executed
// because the exception expression continues execution.
//
DbgPrint(" test3..."); Counter = 0; try { Counter -= 1; RtlRaiseException(&ExceptionRecord);
} except (Counter) { Counter -= 1; }
if (Counter != - 1) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Simple try statement with an exception clause that is always executed.
//
DbgPrint(" test4..."); Counter = 0; try { Counter += 1; RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
} except (Counter) { Counter += 1; }
if (Counter != 2) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Simple try statement with an exception clause that is always executed.
//
DbgPrint(" test5..."); Counter = 0; try { Counter += 1; *BlackHole += *BadAddress;
} except (Counter) { Counter += 1; }
if (Counter != 2) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Simply try statement with a finally clause that is entered as the
// result of an exception.
//
DbgPrint(" test6..."); Counter = 0; try { try { Counter += 1; RtlRaiseException(&ExceptionRecord);
} finally { if (abnormal_termination() != FALSE) { Counter += 1; } }
} except (Counter) { if (Counter == 2) { Counter += 1; } }
if (Counter != 3) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Simply try statement with a finally clause that is entered as the
// result of an exception.
//
DbgPrint(" test7..."); Counter = 0; try { try { Counter += 1; *BlackHole += *BadAddress;
} finally { if (abnormal_termination() != FALSE) { Counter += 1; } }
} except (Counter) { if (Counter == 2) { Counter += 1; } }
if (Counter != 3) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Simple try that calls a function which raises an exception.
//
DbgPrint(" test8..."); Counter = 0; try { Counter += 1; foo1(STATUS_ACCESS_VIOLATION);
} except ((GetExceptionCode() == STATUS_ACCESS_VIOLATION) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { Counter += 1; }
if (Counter != 2) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Simple try that calls a function which raises an exception.
//
DbgPrint(" test9..."); Counter = 0; try { Counter += 1; foo2(BlackHole, BadAddress);
} except ((GetExceptionCode() == STATUS_ACCESS_VIOLATION) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { Counter += 1; }
if (Counter != 2) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Simple try that calls a function which calls a function that
// raises an exception. The first function has a finally clause
// that must be executed for this test to work.
//
DbgPrint(" test10..."); Counter = 0; try { bar1(STATUS_ACCESS_VIOLATION, &Counter);
} except ((GetExceptionCode() == STATUS_ACCESS_VIOLATION) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { Counter -= 1; }
if (Counter != 98) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Simple try that calls a function which calls a function that
// raises an exception. The first function has a finally clause
// that must be executed for this test to work.
//
DbgPrint(" test11..."); Counter = 0; try { bar2(BlackHole, BadAddress, &Counter);
} except ((GetExceptionCode() == STATUS_ACCESS_VIOLATION) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { Counter -= 1; }
if (Counter != 98) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// A try within an except
//
DbgPrint(" test12..."); Counter = 0; try { foo1(STATUS_ACCESS_VIOLATION);
} except ((GetExceptionCode() == STATUS_ACCESS_VIOLATION) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { Counter += 1; try { foo1(STATUS_SUCCESS);
} except ((GetExceptionCode() == STATUS_SUCCESS) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { if (Counter != 1) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded..."); }
Counter += 1; } }
if (Counter != 2) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// A try within an except
//
DbgPrint(" test13..."); Counter = 0; try { foo2(BlackHole, BadAddress);
} except ((GetExceptionCode() == STATUS_ACCESS_VIOLATION) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { Counter += 1; try { foo1(STATUS_SUCCESS);
} except ((GetExceptionCode() == STATUS_SUCCESS) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { if (Counter != 1) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded..."); }
Counter += 1; } }
if (Counter != 2) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// A goto from an exception clause that needs to pass
// through a finally
//
DbgPrint(" test14..."); Counter = 0; try { try { foo1(STATUS_ACCESS_VIOLATION);
} except ((GetExceptionCode() == STATUS_ACCESS_VIOLATION) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { Counter += 1; goto t9; }
} finally { Counter += 1; }
t9:; if (Counter != 2) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// A goto from an finally clause that needs to pass
// through a finally
//
DbgPrint(" test15..."); Counter = 0; try { try { Counter += 1;
} finally { Counter += 1; goto t10; }
} finally { Counter += 1; }
t10:; if (Counter != 3) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// A goto from an exception clause that needs to pass
// through a finally into the outer finally clause.
//
DbgPrint(" test16..."); Counter = 0; try { try { try { Counter += 1; foo1(STATUS_INTEGER_OVERFLOW);
} except (EXCEPTION_EXECUTE_HANDLER) { Counter += 1; goto t11; }
} finally { Counter += 1; } t11:; } finally { Counter += 1; }
if (Counter != 4) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// A goto from an finally clause that needs to pass
// through a finally into the outer finally clause.
//
DbgPrint(" test17..."); Counter = 0; try { try { Counter += 1;
} finally { Counter += 1; goto t12; } t12:; } finally { Counter += 1; }
if (Counter != 3) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// A return from an except clause
//
DbgPrint(" test18..."); Counter = 0; try { Counter += 1; eret(STATUS_ACCESS_VIOLATION, &Counter);
} finally { Counter += 1; }
if (Counter != 4) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// A return from a finally clause
//
DbgPrint(" test19..."); Counter = 0; try { Counter += 1; fret(&Counter);
} finally { Counter += 1; }
if (Counter != 5) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// A simple set jump followed by a long jump.
//
DbgPrint(" test20..."); Counter = 0; if (setjmp(JumpBuffer) == 0) { Counter += 1; longjmp(JumpBuffer, 1);
} else { Counter += 1; }
if (Counter != 2) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// A set jump followed by a long jump out of a finally clause that is
// sequentially executed.
//
DbgPrint(" test21..."); Counter = 0; if (setjmp(JumpBuffer) == 0) { try { Counter += 1;
} finally { Counter += 1; longjmp(JumpBuffer, 1); }
} else { Counter += 1; }
if (Counter != 3) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// A set jump within a try clause followed by a long jump out of a
// finally clause that is sequentially executed.
//
DbgPrint(" test22..."); Counter = 0; try { if (setjmp(JumpBuffer) == 0) { Counter += 1;
} else { Counter += 1; }
} finally { Counter += 1; if (Counter == 2) { Counter += 1; longjmp(JumpBuffer, 1); } }
if (Counter != 5) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// A set jump followed by a try/except, followed by a try/finally where
// the try body of the try/finally raises an exception that is handled
// by the try/excecpt which causes the try/finally to do a long jump out
// of a finally clause. This will create a collided unwind.
//
DbgPrint(" test23..."); Counter = 0; if (setjmp(JumpBuffer) == 0) { try { try { Counter += 1; RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
} finally { Counter += 1; longjmp(JumpBuffer, 1); }
} except(EXCEPTION_EXECUTE_HANDLER) { Counter += 1; }
} else { Counter += 1; }
if (Counter != 3) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// A set jump followed by a try/except, followed by a several nested
// try/finally's where the inner try body of the try/finally raises an
// exception that is handled by the try/except which causes the
// try/finally to do a long jump out of a finally clause. This will
// create a collided unwind.
//
DbgPrint(" test24..."); Counter = 0; if (setjmp(JumpBuffer) == 0) { try { try { try { try { Counter += 1; RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
} finally { Counter += 1; }
} finally { Counter += 1; longjmp(JumpBuffer, 1); }
} finally { Counter += 1; }
} except(EXCEPTION_EXECUTE_HANDLER) { Counter += 1; }
} else { Counter += 1; }
if (Counter != 5) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// A set jump followed by a try/except, followed by a try/finally which
// calls a subroutine which contains a try finally that raises an
// exception that is handled to the try/except.
//
DbgPrint(" test25..."); Counter = 0; if (setjmp(JumpBuffer) == 0) { try { try { try { Counter += 1; dojump(JumpBuffer, &Counter);
} finally { Counter += 1; }
} finally { Counter += 1; }
} except(EXCEPTION_EXECUTE_HANDLER) { Counter += 1; }
} else { Counter += 1; }
if (Counter != 7) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// A set jump followed by a try/except, followed by a try/finally which
// calls a subroutine which contains a try finally that raises an
// exception that is handled to the try/except.
//
DbgPrint(" test26..."); Counter = 0; if (setjmp(JumpBuffer) == 0) { try { try { try { try { Counter += 1; dojump(JumpBuffer, &Counter);
} finally { Counter += 1; }
} finally { Counter += 1; longjmp(JumpBuffer, 1); }
} finally { Counter += 1; }
} except(EXCEPTION_EXECUTE_HANDLER) { Counter += 1; }
} else { Counter += 1; }
if (Counter != 8) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Test nested exceptions.
//
DbgPrint(" test27..."); Counter = 0; try { try { Counter += 1; except1(&Counter);
} except(except2(GetExceptionInformation(), &Counter)) { Counter += 2; }
} except(EXCEPTION_EXECUTE_HANDLER) { Counter += 3; }
if (Counter != 55) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Simple try that causes an integer overflow exception.
//
DbgPrint(" test28..."); Counter = 0; try { Counter += 1; addtwo(0x7fff0000, 0x10000, &Counter);
} except ((GetExceptionCode() == STATUS_INTEGER_OVERFLOW) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { Counter += 1; }
if (Counter != 2) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Simple try that raises an misaligned data exception.
//
#if 0
DbgPrint(" test29..."); Counter = 0; try { Counter += 1; foo2(BlackHole, (PLONG)BadByte);
} except ((GetExceptionCode() == STATUS_DATATYPE_MISALIGNMENT) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { Counter += 1; }
if (Counter != 2) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
#endif
//
// Continue from a try body with an exception clause in a loop.
//
DbgPrint(" test30..."); Counter = 0; for (Index1 = 0; Index1 < 10; Index1 += 1) { try { if ((Index1 & 0x1) == 0) { continue;
} else { Counter += 1; }
} except (EXCEPTION_EXECUTE_HANDLER) { Counter += 40; }
Counter += 2; }
if (Counter != 15) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Continue from a try body with an finally clause in a loop.
//
DbgPrint(" test31..."); Counter = 0; for (Index1 = 0; Index1 < 10; Index1 += 1) { try { if ((Index1 & 0x1) == 0) { continue;
} else { Counter += 1; }
} finally { Counter += 2; }
Counter += 3; }
if (Counter != 40) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Continue from doubly nested try body with an exception clause in a
// loop.
//
DbgPrint(" test32..."); Counter = 0; for (Index1 = 0; Index1 < 10; Index1 += 1) { try { try { if ((Index1 & 0x1) == 0) { continue;
} else { Counter += 1; }
} except (EXCEPTION_EXECUTE_HANDLER) { Counter += 10; }
Counter += 2;
} except (EXCEPTION_EXECUTE_HANDLER) { Counter += 20; }
Counter += 3; }
if (Counter != 30) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Continue from doubly nested try body with an finally clause in a loop.
//
DbgPrint(" test33..."); Counter = 0; for (Index1 = 0; Index1 < 10; Index1 += 1) { try { try { if ((Index1 & 0x1) == 0) { continue;
} else { Counter += 1; }
} finally { Counter += 2; }
Counter += 3;
} finally { Counter += 4; }
Counter += 5; }
if (Counter != 105) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Continue from a finally clause in a loop.
//
DbgPrint(" test34..."); Counter = 0; for (Index1 = 0; Index1 < 10; Index1 += 1) { try { if ((Index1 & 0x1) == 0) { Counter += 1; }
} finally { Counter += 2; continue; }
Counter += 4; }
if (Counter != 25) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Continue from a doubly nested finally clause in a loop.
//
DbgPrint(" test35..."); Counter = 0; for (Index1 = 0; Index1 < 10; Index1 += 1) { try { try { if ((Index1 & 0x1) == 0) { Counter += 1; }
} finally { Counter += 2; continue; }
Counter += 4;
} finally { Counter += 5; }
Counter += 6; }
if (Counter != 75) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Continue from a doubly nested finally clause in a loop.
//
DbgPrint(" test36..."); Counter = 0; for (Index1 = 0; Index1 < 10; Index1 += 1) { try { try { if ((Index1 & 0x1) == 0) { Counter += 1; }
} finally { Counter += 2; }
Counter += 4;
} finally { Counter += 5; continue; }
Counter += 6; }
if (Counter != 115) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Break from a try body with an exception clause in a loop.
//
DbgPrint(" test37..."); Counter = 0; for (Index1 = 0; Index1 < 10; Index1 += 1) { try { if ((Index1 & 0x1) == 1) { break;
} else { Counter += 1; }
} except (EXCEPTION_EXECUTE_HANDLER) { Counter += 40; }
Counter += 2; }
if (Counter != 3) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Break from a try body with an finally clause in a loop.
//
DbgPrint(" test38..."); Counter = 0; for (Index1 = 0; Index1 < 10; Index1 += 1) { try { if ((Index1 & 0x1) == 1) { break;
} else { Counter += 1; }
} finally { Counter += 2; }
Counter += 3; }
if (Counter != 8) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Break from doubly nested try body with an exception clause in a
// loop.
//
DbgPrint(" test39..."); Counter = 0; for (Index1 = 0; Index1 < 10; Index1 += 1) { try { try { if ((Index1 & 0x1) == 1) { break;
} else { Counter += 1; }
} except (EXCEPTION_EXECUTE_HANDLER) { Counter += 10; }
Counter += 2;
} except (EXCEPTION_EXECUTE_HANDLER) { Counter += 20; }
Counter += 3; }
if (Counter != 6) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Break from doubly nested try body with an finally clause in a loop.
//
DbgPrint(" test40..."); Counter = 0; for (Index1 = 0; Index1 < 10; Index1 += 1) { try { try { if ((Index1 & 0x1) == 1) { break;
} else { Counter += 1; }
} finally { Counter += 2; }
Counter += 3;
} finally { Counter += 4; }
Counter += 5; }
if (Counter != 21) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Break from a finally clause in a loop.
//
DbgPrint(" test41..."); Counter = 0; for (Index1 = 0; Index1 < 10; Index1 += 1) { try { if ((Index1 & 0x1) == 1) { Counter += 1; }
} finally { Counter += 2; break; }
Counter += 4; }
if (Counter != 2) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Break from a doubly nested finally clause in a loop.
//
DbgPrint(" test42..."); Counter = 0; for (Index1 = 0; Index1 < 10; Index1 += 1) { try { try { if ((Index1 & 0x1) == 1) { Counter += 1; }
} finally { Counter += 2; break; }
Counter += 4;
} finally { Counter += 5; }
Counter += 6; }
if (Counter != 7) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Break from a doubly nested finally clause in a loop.
//
DbgPrint(" test43..."); Counter = 0; for (Index1 = 0; Index1 < 10; Index1 += 1) { try { try { if ((Index1 & 0x1) == 1) { Counter += 1; }
} finally { Counter += 2; }
Counter += 4;
} finally { Counter += 5; break; }
Counter += 6; }
if (Counter != 11) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Break from a try body with an exception clause in a switch.
//
DbgPrint(" test44..."); Counter = 0; Index1 = 1; switch (Index2) { case BLUE: Counter += 100; break;
case RED: try { if ((Index1 & 0x1) == 1) { break;
} else { Counter += 1; }
} except (EXCEPTION_EXECUTE_HANDLER) { Counter += 40; }
Counter += 2; break; }
if (Counter != 0) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Break from a try body with an finally clause in a switch.
//
DbgPrint(" test45..."); Counter = 0; Index1 = 1; switch (Index2) { case BLUE: Counter += 100; break;
case RED: try { if ((Index1 & 0x1) == 1) { break;
} else { Counter += 1; }
} finally { Counter += 2; }
Counter += 3; }
if (Counter != 2) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Break from doubly nested try body with an exception clause in a
// switch.
//
DbgPrint(" test46..."); Counter = 0; Index1 = 1; switch (Index2) { case BLUE: Counter += 100; break;
case RED: try { try { if ((Index1 & 0x1) == 1) { break;
} else { Counter += 1; }
} except (EXCEPTION_EXECUTE_HANDLER) { Counter += 10; }
Counter += 2;
} except (EXCEPTION_EXECUTE_HANDLER) { Counter += 20; }
Counter += 3; }
if (Counter != 0) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Break from doubly nested try body with an finally clause in a switch.
//
DbgPrint(" test47..."); Counter = 0; Index1 = 1; switch (Index2) { case BLUE: Counter += 100; break;
case RED: try { try { if ((Index1 & 0x1) == 1) { break;
} else { Counter += 1; }
} finally { Counter += 2; }
Counter += 3;
} finally { Counter += 4; }
Counter += 5; }
if (Counter != 6) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Break from a finally clause in a switch.
//
DbgPrint(" test48..."); Counter = 0; Index1 = 1; switch (Index2) { case BLUE: Counter += 100; break;
case RED: try { if ((Index1 & 0x1) == 1) { Counter += 1; }
} finally { Counter += 2; break; }
Counter += 4; }
if (Counter != 3) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Break from a doubly nested finally clause in a switch.
//
DbgPrint(" test49..."); Counter = 0; Index1 = 1; switch (Index2) { case BLUE: Counter += 100; break;
case RED: try { try { if ((Index1 & 0x1) == 1) { Counter += 1; }
} finally { Counter += 2; break; }
Counter += 4;
} finally { Counter += 5; }
Counter += 6; }
if (Counter != 8) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Break from a doubly nested finally clause in a switch.
//
DbgPrint(" test50..."); Counter = 0; Index1 = 1; switch (Index2) { case BLUE: Counter += 100; break;
case RED: try { try { if ((Index1 & 0x1) == 1) { Counter += 1; }
} finally { Counter += 2; }
Counter += 4;
} finally { Counter += 5; break; }
Counter += 6; }
if (Counter != 12) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Leave from an if in a simple try/finally.
//
DbgPrint(" test51..."); Counter = 0; try { if (Echo(Counter) == Counter) { Counter += 3; leave;
} else { Counter += 100; }
} finally { if (abnormal_termination() == FALSE) { Counter += 5; } }
if (Counter != 8) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Leave from a loop in a simple try/finally.
//
DbgPrint(" test52..."); Counter = 0; try { for (Index1 = 0; Index1 < 10; Index1 += 1) { if (Echo(Index1) == Index1) { Counter += 3; leave; }
Counter += 100; }
} finally { if (abnormal_termination() == FALSE) { Counter += 5; } }
if (Counter != 8) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Leave from a switch in a simple try/finally.
//
DbgPrint(" test53..."); Counter = 0; try { switch (Index2) { case BLUE: break;
case RED: Counter += 3; leave; }
Counter += 100;
} finally { if (abnormal_termination() == FALSE) { Counter += 5; } }
if (Counter != 8) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Leave from an if in doubly nested try/finally followed by a leave
// from an if in the outer try/finally.
//
DbgPrint(" test54..."); Counter = 0; try { try { if (Echo(Counter) == Counter) { Counter += 3; leave;
} else { Counter += 100; }
} finally { if (abnormal_termination() == FALSE) { Counter += 5; } }
if (Echo(Counter) == Counter) { Counter += 3; leave;
} else { Counter += 100; }
} finally { if (abnormal_termination() == FALSE) { Counter += 5; } }
if (Counter != 16) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Leave from an if in doubly nested try/finally followed by a leave
// from the finally of the outer try/finally.
//
DbgPrint(" test55..."); Counter = 0; try { try { if (Echo(Counter) == Counter) { Counter += 3; leave;
} else { Counter += 100; }
} finally { if (abnormal_termination() == FALSE) { Counter += 5; leave; } }
Counter += 100;
} finally { if (abnormal_termination() == FALSE) { Counter += 5; } }
if (Counter != 13) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Try/finally within the except clause of a try/except that is always
// executed.
//
DbgPrint(" test56..."); Counter = 0; try { Counter += 1; RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
} except (Counter) { try { Counter += 3;
} finally { if (abnormal_termination() == FALSE) { Counter += 5; } } }
if (Counter != 9) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Try/finally within the finally clause of a try/finally.
//
DbgPrint(" test57..."); Counter = 0; try { Counter += 1;
} finally { if (abnormal_termination() == FALSE) { try { Counter += 3;
} finally { if (abnormal_termination() == FALSE) { Counter += 5; } } } }
if (Counter != 9) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Try/except within the finally clause of a try/finally.
//
DbgPrint(" test58..."); Counter = 0; try { Counter -= 1;
} finally { try { Counter += 2; RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
} except (Counter) { try { Counter += 3;
} finally { if (abnormal_termination() == FALSE) { Counter += 5; } } } }
if (Counter != 9) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Try/except within the except clause of a try/except that is always
// executed.
//
DbgPrint(" test59..."); Counter = 0; try { Counter += 1; RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
} except (Counter) { try { Counter += 3; RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
} except(Counter - 3) { Counter += 5; } }
if (Counter != 9) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Try with a Try which exits the scope with a goto
//
DbgPrint(" test60..."); Counter = 0; try { try { goto outside;
} except(1) { Counter += 1; }
outside: RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
} except(1) { Counter += 3; }
if (Counter != 3) { DbgPrint("failed, count = %d\n", Counter); } else { DbgPrint("succeeded\n"); }
//
// Try/except which gets an exception from a subfunction within
// a try/finally which has a try/except in the finally clause
//
DbgPrint(" test61..."); Counter = 0; try { Test61Part2 (&Counter); } except (EXCEPTION_EXECUTE_HANDLER) { Counter += 11; }
if (Counter != 24) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Try/except within a try/except where the outer try/except gets
// a floating overflow exception.
//
DbgPrint(" test62..."); _controlfp(_controlfp(0,0) & ~EM_OVERFLOW, _MCW_EM); Counter = 0; try { doubleresult = SquareDouble(1.7e300);
try { doubleresult = SquareDouble (1.0);
} except (EXCEPTION_EXECUTE_HANDLER) { Counter += 3; }
} except ((GetExceptionCode() == STATUS_FLOAT_OVERFLOW) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
Counter += 1; }
if (Counter != 1) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
_clearfp ();
//
// Try/except within a try/except where the outer try/except gets
// a floating overflow exception in a subfunction.
//
DbgPrint(" test63..."); Counter = 0; try { SquareDouble17E300((PVOID)&doubleresult); try { SquareDouble17E300((PVOID)&doubleresult);
} except (EXCEPTION_EXECUTE_HANDLER) { Counter += 3; }
} except ((GetExceptionCode() == STATUS_FLOAT_OVERFLOW) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
Counter += 1; }
if (Counter != 1) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
_clearfp ();
//
// Try/finally within a try/except where the finally body causes an
// exception that leads to a collided unwind during the exception
// dispatch.
//
DbgPrint(" test64..."); Counter = 0; try { Counter += 1; try { Counter += 1; FAULT; Counter += 20;
} finally { if (abnormal_termination() == FALSE) { Counter += 20;
} else { Counter += 1; FAULT; } }
} except (EXCEPTION_EXECUTE_HANDLER) { Counter += 10; } if (Counter != 13) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Try/finally within a try/finally within a try/except that leads to a
// collided unwind during the exception dispatch.
//
DbgPrint(" test65..."); Counter = 0; try { Counter += 1; try { Counter += 1; FAULT; Counter += 20;
} finally { if (abnormal_termination() == FALSE) { Counter += 20;
} else { try { Counter += 1; FAULT; Counter += 20; } finally { if (abnormal_termination() == FALSE) { Counter += 20;
} else { Counter += 1; } } }
FAULT; }
} except (EXCEPTION_EXECUTE_HANDLER) { Counter += 10; } if (Counter != 14) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// A call to a function with a try/finally that returns out of the try
// body.
//
DbgPrint(" test66..."); Counter = 0; if ((test66sub(&Counter) + 1) != Counter) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// A call to a function with a try finally that returnss out of the
// termination hander.
//
DbgPrint(" test67..."); Counter = 0; if (test67sub(&Counter) != Counter) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Emulate C++ exception handing and frame consolidation.
//
DbgPrint(" test68..."); Counter = 0; try { Counter += 1; ExceptionRecord.ExceptionCode = 0xbaadf00d; ExceptionRecord.ExceptionInformation[4] = (ULONG_PTR)&Catch; RtlRaiseException(&ExceptionRecord);
} except (Counter) { Counter += 1; }
if (Counter != 2) { DbgPrint("failed, count = %d\n", Counter);
} else { DbgPrint("succeeded\n"); }
//
// Announce end of exception test.
//
DbgBreakPoint(); DbgPrint("End of exception test\n"); return; }
VOID addtwo ( long First, long Second, long *Place )
{
RtlRaiseStatus(STATUS_INTEGER_OVERFLOW); *Place = First + Second; return; }
VOID bar1 ( IN NTSTATUS Status, IN PLONG Counter ) {
try { foo1(Status);
} finally { if (abnormal_termination() != FALSE) { *Counter = 99;
} else { *Counter = 100; } }
return; }
VOID bar2 ( IN PLONG BlackHole, IN PLONG BadAddress, IN PLONG Counter ) {
try { foo2(BlackHole, BadAddress);
} finally { if (abnormal_termination() != FALSE) { *Counter = 99;
} else { *Counter = 100; } }
return; }
ULONG64 Catch ( IN PEXCEPTION_RECORD ExceptionRecord )
{ UNREFERENCED_PARAMETER(ExceptionRecord);
return 0; }
VOID dojump ( IN jmp_buf JumpBuffer, IN PLONG Counter )
{
try { try { *Counter += 1; RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
} finally { *Counter += 1; }
} finally { *Counter += 1; longjmp(JumpBuffer, 1); } }
VOID eret( IN NTSTATUS Status, IN PLONG Counter )
{
try { try { foo1(Status);
} except (((NTSTATUS)GetExceptionCode() == Status) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { *Counter += 1; return; }
} finally { *Counter += 1; }
return; }
VOID except1 ( IN PLONG Counter )
{
try { *Counter += 5; RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
} except (except3(GetExceptionInformation(), Counter)) { *Counter += 7; }
*Counter += 9; return; }
ULONG except2 ( IN PEXCEPTION_POINTERS ExceptionPointers, IN PLONG Counter )
{
PEXCEPTION_RECORD ExceptionRecord;
ExceptionRecord = ExceptionPointers->ExceptionRecord; if ((ExceptionRecord->ExceptionCode == STATUS_UNSUCCESSFUL) && ((ExceptionRecord->ExceptionFlags & EXCEPTION_NESTED_CALL) == 0)) { *Counter += 11; return EXCEPTION_EXECUTE_HANDLER;
} else { *Counter += 13; return EXCEPTION_CONTINUE_SEARCH; } }
ULONG except3 ( IN PEXCEPTION_POINTERS ExceptionPointers, IN PLONG Counter )
{
PEXCEPTION_RECORD ExceptionRecord;
ExceptionRecord = ExceptionPointers->ExceptionRecord; if ((ExceptionRecord->ExceptionCode == STATUS_INTEGER_OVERFLOW) && ((ExceptionRecord->ExceptionFlags & EXCEPTION_NESTED_CALL) == 0)) { *Counter += 17; RtlRaiseStatus(STATUS_UNSUCCESSFUL);
} else if ((ExceptionRecord->ExceptionCode == STATUS_UNSUCCESSFUL) && ((ExceptionRecord->ExceptionFlags & EXCEPTION_NESTED_CALL) != 0)) { *Counter += 19; return EXCEPTION_CONTINUE_SEARCH; }
*Counter += 23; return EXCEPTION_EXECUTE_HANDLER; }
VOID foo1 ( IN NTSTATUS Status )
{
//
// Raise exception.
//
RtlRaiseStatus(Status); return; }
VOID foo2 ( IN PLONG BlackHole, IN PLONG BadAddress )
{
//
// Raise exception.
//
*BlackHole += *BadAddress; return; }
VOID fret ( IN PLONG Counter )
{
try { try { *Counter += 1;
} finally { *Counter += 1; return; } } finally { *Counter += 1; }
return; }
LONG Echo ( IN LONG Value )
{ return Value; }
VOID Test61Part2 ( IN OUT PLONG Counter ) {
try { *Counter -= 1; RtlRaiseStatus(STATUS_INTEGER_OVERFLOW);
} finally { *Counter += 2; *Counter += 5; *Counter += 7; } }
double SquareDouble ( IN double op ) { return op * op; }
VOID SquareDouble17E300 ( OUT PVOID output ) { double ans;
ans = SquareDouble (1.7e300); *(double *) output = ans; }
LONG test66sub ( IN PLONG Counter )
{
*Counter += 1; try { *Counter += 1; return(*Counter);
} finally { *Counter += 1; } }
LONG test67sub ( IN PLONG Counter )
{
*Counter += 1; try { *Counter += 1;
} finally { *Counter += 1; return(*Counter); } }
|