source: trunk/testapp/exceptions/seh/except.c@ 21476

Last change on this file since 21476 was 21476, checked in by dmik, 15 years ago

testapp: Improved SEH/except test case.

  • Property svn:executable set to *
File size: 3.6 KB
Line 
1#include <stdio.h>
2#include <windows.h>
3#include <excpt.h>
4
5#ifndef _MSC_VER
6
7#include <odinlx.h>
8
9int _main();
10int _argc;
11char **_argv;
12
13int WIN32API WinMain(HANDLE hInstance,
14 HANDLE hPrevInstance,
15 LPSTR lpCmdLine,
16 int nCmdShow)
17{
18 return _main(_argc, _argv);
19}
20
21int main(int argc, char **argv)
22{
23 _argc = argc;
24 _argv = argv;
25 EnableSEH();
26 RegisterLxExe(WinMain, NULL);
27}
28
29#else
30#define _main main
31#endif
32
33int testCode = 0;
34
35int tries = 3;
36
37int exc_filter(DWORD code, DWORD filtercode, PEXCEPTION_POINTERS pPtrs)
38{
39 PEXCEPTION_RECORD pRec = pPtrs->ExceptionRecord;
40
41 printf("Filter: code %08lx, filtercode %08lx\n", code, filtercode);
42 printf("ExceptionCode %p\n", pRec->ExceptionCode);
43 printf("ExceptionAddress %p\n", pRec->ExceptionAddress);
44 printf("NumberParameters %d\n", pRec->NumberParameters);
45
46 if (code == filtercode)
47 {
48 if (testCode == 4 && tries)
49 {
50 --tries;
51 return EXCEPTION_CONTINUE_EXECUTION;
52 }
53
54 return EXCEPTION_EXECUTE_HANDLER;
55 }
56
57 return EXCEPTION_CONTINUE_SEARCH;
58}
59
60void throw_EXCEPTION_INT_DIVIDE_BY_ZERO()
61{
62 printf("Throwing EXCEPTION_INT_DIVIDE_BY_ZERO...\n");
63 int x = 0;
64 volatile int y = 4 / x;
65}
66
67void throw_EXCEPTION_ACCESS_VIOLATION()
68{
69 printf("Throwing EXCEPTION_ACCESS_VIOLATION...\n");
70 volatile int *x = 0;
71 *x = 0;
72}
73
74int _main(int argc, char **argv)
75{
76 testCode = argc > 1 ? atoi(argv[1]) : 0;
77
78 switch (testCode)
79 {
80 case 1:
81 printf("Target: Throw EXCEPTION_ACCESS_VIOLATION from inner __try\n"
82 "and catch it in inner __except.\n\n");
83 break;
84 case 2:
85 printf("Target: Throw EXCEPTION_INT_DIVIDE_BY_ZERO from inner __try\n"
86 "and catch it in outer __except.\n\n");
87 break;
88 case 3:
89 printf("Target: Throw EXCEPTION_INT_DIVIDE_BY_ZERO from outer __try\n"
90 "and catch it in outer __except.\n\n");
91 break;
92 case 4:
93 printf("Target: Throw EXCEPTION_INT_DIVIDE_BY_ZERO from outer __try,\n"
94 "fix it in the handler and continue execution.\n\n");
95 break;
96 default:
97 printf("Invalid test code %d\n", testCode);
98 return 1;
99 }
100
101 __try
102 {
103 if (testCode == 3 || testCode == 4)
104 {
105 throw_EXCEPTION_INT_DIVIDE_BY_ZERO();
106
107 printf("FAILED: No outer exception!\n");
108 return 1;
109 }
110
111 __try
112 {
113 if (testCode == 1)
114 throw_EXCEPTION_ACCESS_VIOLATION();
115 else if (testCode == 2)
116 throw_EXCEPTION_INT_DIVIDE_BY_ZERO();
117
118 printf("FAILED: No inner exception!\n");
119 return 1;
120 }
121 __except(exc_filter(GetExceptionCode(),
122 EXCEPTION_ACCESS_VIOLATION,
123 exception_info()))
124 {
125 // handle exception
126 printf("Inner exception handled.\n");
127 }
128 }
129 __except(exc_filter(GetExceptionCode(),
130 EXCEPTION_INT_DIVIDE_BY_ZERO,
131 exception_info()))
132 {
133 if (testCode == 4 && tries)
134 {
135 printf("FAILED: Outer exception (tries = %d)!\n", tries);
136 return 1;
137 }
138
139 // handle exception
140 printf("Outer exception handled.\n");
141 }
142
143 printf("Return.\n");
144
145 return 0;
146}
Note: See TracBrowser for help on using the repository browser.