summaryrefslogtreecommitdiff
path: root/src/pal/tests/palsuite/exception_handling/PAL_EXCEPT_FILTER/test2/pal_except_filter.cpp
blob: ccf53fb0ba20c537ebf92857c5d8f97ddaf5f306 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

/*=====================================================================
**
** Source:  pal_except_filter.c (test 2)
**
** Purpose: Tests the PAL implementation of the PAL_EXCEPT_FILTER. An 
**          exception is forced and the filter returns
**          EXCEPTION_CONTINUE_EXECUTION to allow execution to continue.
**
**
**===================================================================*/


#include <palsuite.h>

char* p;   /* pointer to be abused */

BOOL bFilter = FALSE;
BOOL bTry = FALSE;
BOOL bTry2 = FALSE;
BOOL bContinued = FALSE;
const int nValidator = 12321;

LONG ExitFilter(EXCEPTION_POINTERS* ep, LPVOID pnTestInt)
{
    int nTestInt = *(int *)pnTestInt;
    void *Temp;
    
    /* let the main know we've hit the filter function */
    bFilter = TRUE;

    if (!bTry)
    {
        Fail("PAL_EXCEPT_FILTER: ERROR -> Something weird is going on."
            " The filter was hit without PAL_TRY being hit.\n");
    }

    /* was the correct value passed? */
    if (nValidator != nTestInt)
    {
        Fail("PAL_EXCEPT_FILTER: ERROR -> Parameter passed to filter function"
            " should have been \"%d\" but was \"%d\".\n",
            nValidator,
            nTestInt);
    }

    /* Are we dealing with the exception we expected? */
    if (EXCEPTION_ACCESS_VIOLATION != ep->ExceptionRecord->ExceptionCode)
    {
        Fail("PAL_EXCEPT_FILTER: ERROR -> Unexpected Exception"
            " should have been \"%x\" but was \"%x\".\n",
            EXCEPTION_ACCESS_VIOLATION,
            ep->ExceptionRecord->ExceptionCode);
    }

    /* attempt to correct the problem by commiting the page at address 'p'  */
    Temp= VirtualAlloc(p, 1, MEM_COMMIT, PAGE_READWRITE);	
    if (!Temp) 
    { 
        Fail("EXCEPTION_CONTINUE_EXECUTION: last error = %u - probably "
             "out of memory. Unable to continue, not proof of exception "
             "failure\n",
             GetLastError());
    }
    /*  The memory that 'p' points to is now valid */

    return EXCEPTION_CONTINUE_EXECUTION;
}


int __cdecl main(int argc, char *argv[])
{
    BOOL bExcept = FALSE;

    if (0 != PAL_Initialize(argc, argv))
    {
        return FAIL;
    }


    /*
    ** test to make sure we get into the exception block
    */
    
    PAL_TRY 
    {
        if (bExcept)
        {
            Fail("PAL_EXCEPT_FILTER: ERROR -> Something weird is going on."
                " PAL_EXCEPT_FILTER was hit before PAL_TRY.\n");
        }
        bTry = TRUE;    /* indicate we hit the PAL_TRY block */

        /* reserve an address chunk for p to point to */
        p = (char*) VirtualAlloc(0, 1, MEM_RESERVE, PAGE_READONLY);
        if (!p) 
        {
            Fail("EXCEPTION_CONTINUE_EXECUTION: test setup via "
                 "VirtualAlloc failed.\n");
        }

        *p = 13;        /* causes an access violation exception */

        bTry2 = TRUE;

 
    }
    PAL_EXCEPT_FILTER(ExitFilter, (LPVOID)&nValidator)
    {
        bExcept = TRUE; /* indicate we hit the PAL_EXCEPT_FILTER block */
        Fail("PAL_EXCEPT_FILTER: ERROR -> in handler despite filter's "
            "continue choice\n");
    }
    PAL_ENDTRY;

    if (!bTry)
    {
        Trace("PAL_EXCEPT_FILTER: ERROR -> It appears the code in the PAL_TRY"
            " block was not executed.\n");
    }

    if (bExcept)
    {
        Trace("PAL_EXCEPT_FILTER: ERROR -> It appears the code in the "
            "PAL_EXCEPT_FILTER block was executed.\n");
    }

    if (!bFilter)
    {
        Trace("PAL_EXCEPT_FILTER: ERROR -> It appears the code in the filter"
            " function was not executed.\n");
    }


    if (!bTry2)
    {
        Trace("PAL_EXCEPT_FILTER: ERROR -> It appears the code in the PAL_TRY"
            " block after the exception causing statements was not executed.\n");
    }

    /* did we hit all the code blocks? */
    if(!bTry || bExcept || !bFilter)
    {
        Fail("");
    }


    PAL_Terminate();  
    return PASS;

}