source: trunk/testapp/exceptions/GuardPages/main.cpp@ 22145

Last change on this file since 22145 was 21999, checked in by dmik, 13 years ago

kernel32: Make SEH work in OS/2 context.

See #82 for details.

  • Property svn:eol-style set to native
File size: 6.2 KB
Line 
1#ifdef __WIN32OS2__
2#define INCL_DOSPROCESS
3#define INCL_DOSEXCEPTIONS
4#define INCL_ERRORS
5#define INCL_DOSSEMAPHORES
6#include <os2wrap2.h>
7#endif
8
9#include <windows.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <tchar.h>
13
14#ifdef __WIN32OS2__
15#include <odinlx.h>
16#include <excpt.h>
17#endif
18
19#ifdef __WIN32OS2__
20
21void os2_PrintMemLayout (os2_PVOID pAddr)
22{
23 os2_APIRET arc;
24 os2_ULONG sz, flags;
25 os2_PVOID pBase, pCur;
26
27 printf ("Layout of memory region containing %x:\n", pAddr);
28
29 // find the base address
30 sz = 0x1000;
31 pBase = (os2_PVOID)(((os2_ULONG) pAddr) & ~0xFFF);
32
33 do
34 {
35 arc = DosQueryMem (pBase, &sz, &flags);
36 if (arc)
37 {
38 printf ("DosQueryMem(%x) failed with %d\n", pBase, arc);
39 return;
40 }
41 if (flags & os2_PAG_BASE)
42 {
43 break;
44 }
45
46 pBase = (os2_PVOID) ((os2_ULONG) pBase - 0x1000);
47 }
48 while (1);
49
50 pCur = pBase;
51 do
52 {
53 sz = ~0;
54 arc = DosQueryMem (pCur, &sz, &flags);
55 if (arc)
56 {
57 printf ("DosQueryMem(%x) failed with %d\n", pCur, arc);
58 return;
59 }
60 if (pCur != pBase && (flags & (os2_PAG_BASE | os2_PAG_FREE)))
61 {
62 break;
63 }
64
65 printf (" %08X-%08X (%08X): Flags %08X\n",
66 pCur, (ULONG) pCur + sz - 1, sz, flags);
67
68 pCur = (os2_PVOID) ((os2_ULONG) pCur + sz);
69 }
70 while (1);
71}
72
73#endif
74
75SYSTEM_INFO sSysInfo;
76
77void PrintMemLayout (LPVOID pAddr)
78{
79 MEMORY_BASIC_INFORMATION sMemInfo;
80 if (VirtualQuery (pAddr, &sMemInfo, sizeof (sMemInfo)))
81 {
82 printf ("Layout of memory region containing %x:\n", pAddr);
83
84 LPVOID pBase = sMemInfo.AllocationBase;
85 DWORD dwSize = 0;
86
87 LPVOID pStart = pBase;
88 do
89 {
90 if (VirtualQuery (pStart, &sMemInfo, sizeof (sMemInfo)))
91 {
92 if (sMemInfo.AllocationBase != pBase)
93 break;
94 printf (" %08X-%08X (%08X): Protect %08X, State %08X, Type %08X\n",
95 sMemInfo.BaseAddress, (DWORD)sMemInfo.BaseAddress + sMemInfo.RegionSize - 1,
96 sMemInfo.RegionSize, sMemInfo.Protect, sMemInfo.State, sMemInfo.Type);
97 pStart = (LPVOID)((DWORD)sMemInfo.BaseAddress + sMemInfo.RegionSize);
98 dwSize += sMemInfo.RegionSize;
99 }
100 else
101 {
102 printf ("VirtualQuery(%x) failed with %d\n", pStart, GetLastError());
103 return;
104 }
105 }
106 while (1);
107 }
108 else
109 {
110 printf ("VirtualQuery(%x) failed with %d\n", pAddr, GetLastError());
111 }
112}
113
114void Alloc4KOnStack(int nTimes)
115{
116 char buf[4096 - 12];
117 printf ("buf %08X\n", &buf);
118 if (--nTimes)
119 Alloc4KOnStack (nTimes);
120}
121
122DWORD ExceptionFilter (DWORD ExceptionCode)
123{
124 printf ("Exception %08X\n", ExceptionCode);
125
126 if (ExceptionCode == EXCEPTION_STACK_OVERFLOW)
127 return EXCEPTION_EXECUTE_HANDLER;
128 if (ExceptionCode == EXCEPTION_GUARD_PAGE)
129 return EXCEPTION_EXECUTE_HANDLER;
130 return EXCEPTION_CONTINUE_SEARCH;
131}
132
133DWORD WINAPI ThreadProc (LPVOID lpParameter)
134{
135 DWORD dwStackSize = (DWORD) lpParameter;
136
137#ifdef _MSC_VER
138 DWORD dwStackTop = __readfsdword (0x04);
139 DWORD dwStackBottom = __readfsdword (0x08);
140#else
141 DWORD dwStackTop;
142 DWORD dwStackBottom;
143 __asm__ ("movl %%fs:0x04, %0" : "=r" (dwStackTop));
144 __asm__ ("movl %%fs:0x08, %0" : "=r" (dwStackBottom));
145#endif
146
147 printf ("Thread: dwStackTop %x, dwStackBottom %x\n", dwStackTop, dwStackBottom);
148
149 ///////////////////////////////////////////////////
150
151#if 1
152
153 printf ("\nTEST 1 (STACK)\n");
154
155 DWORD dwStackBase = dwStackTop - dwStackSize;
156 DWORD dwYellowZoneSize = sSysInfo.dwPageSize * 3;
157
158 if (VirtualAlloc ((LPVOID) dwStackBase, dwYellowZoneSize,
159 MEM_COMMIT, PAGE_READWRITE))
160 {
161 DWORD dwOldFlags;
162 if (!VirtualProtect ((LPVOID) dwStackBase, dwYellowZoneSize,
163 PAGE_READWRITE | PAGE_GUARD, &dwOldFlags))
164 {
165 printf ("VirtualProtect(%x) failed with %d\n", dwStackBase,
166 GetLastError());
167 }
168 }
169 else
170 {
171 printf ("VirtualAlloc(%x) failed with %d\n", dwStackBase,
172 GetLastError());
173 }
174
175 PrintMemLayout (&dwStackTop);
176
177 {
178 __try
179 {
180 //Alloc4KOnStack (15);
181
182 printf ("Writing to %08X...\n", dwStackBase + sSysInfo.dwPageSize * 3 - 4);
183 *((LPDWORD)(dwStackBase + sSysInfo.dwPageSize * 3 - 4)) = 0;
184 }
185 __except (ExceptionFilter (GetExceptionCode()))
186 {
187 }
188 }
189
190 PrintMemLayout (&dwStackTop);
191
192#endif
193
194 ///////////////////////////////////////////////////
195
196#if 1
197
198 printf ("\nTEST 2 (PAGE_GUARD)\n");
199
200 LPVOID pNonStack = VirtualAlloc (NULL, sSysInfo.dwPageSize,
201 MEM_COMMIT, PAGE_READWRITE | PAGE_GUARD);
202 if (!pNonStack)
203 {
204 printf ("VirtualAlloc(0) failed with %d\n", GetLastError());
205 return 0;
206 }
207
208 PrintMemLayout (pNonStack);
209 os2_PrintMemLayout (pNonStack);
210
211 {
212 __try
213 {
214 *((LPDWORD)(pNonStack)) = 0;
215 }
216 __except (ExceptionFilter (GetExceptionCode()))
217 {
218 }
219 }
220
221 PrintMemLayout (pNonStack);
222 os2_PrintMemLayout (pNonStack);
223
224 VirtualFree (pNonStack, 0, MEM_RELEASE);
225
226#endif
227
228 return 0;
229}
230
231int main()
232{
233#ifdef __WIN32OS2__
234#ifdef ODIN_FORCE_WIN32_TIB
235 ForceWin32TIB();
236#endif
237#endif
238
239 //setbuf (stdout, NULL);
240
241 GetSystemInfo (&sSysInfo);
242
243 printf ("This computer has page size %d.\n", sSysInfo.dwPageSize);
244
245 DWORD dwStackSize = 64 * 1024;
246
247 HANDLE hThread = CreateThread (NULL, dwStackSize, ThreadProc, (LPVOID) dwStackSize,
248 STACK_SIZE_PARAM_IS_A_RESERVATION,
249 NULL);
250 if (hThread == NULL)
251 {
252 printf ("CreateThread failed with %d\n", GetLastError());
253 //getc (stdin);
254 return 1;
255 }
256
257 printf ("Waiting for thread...\n");
258 DWORD rc = WaitForSingleObject (hThread, INFINITE);
259 printf ("Wait returned %d\n", rc);
260
261 //getc (stdin);
262 return 0;
263}
Note: See TracBrowser for help on using the repository browser.