I'm trying to write a test that checks for data overruns using VirtualAlloc and VirtualProtect and I think I may have found a bug. Here is the problem:
DWORD dwPageSize; BYTE * twoPages, temp; DWORD flOldProtect; twoPages = VirtualAlloc(NULL, 2 * dwPageSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); res = VirtualProtect(twoPages + dwPageSize, dwPageSize, PAGE_NOACCESS, &flOldProtect); temp = twoPages[dwPageSize + 1]; // should cause exception but doesn't in wine twoPages[dwPageSize + 1] = 0; // does cause exception
I would like to write a test to check the exception handling but I don't know how to do a __try and __except in C.
Any ideas?
Here is an answer to my own question.
How will this cross compile?
Robert Reif wrote:
I'm trying to write a test that checks for data overruns using VirtualAlloc and VirtualProtect and I think I may have found a bug. Here is the problem:
DWORD dwPageSize; BYTE * twoPages, temp; DWORD flOldProtect; twoPages = VirtualAlloc(NULL, 2 * dwPageSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); res = VirtualProtect(twoPages + dwPageSize, dwPageSize, PAGE_NOACCESS, &flOldProtect); temp = twoPages[dwPageSize + 1]; // should cause exception but doesn't in wine twoPages[dwPageSize + 1] = 0; // does cause exception
I would like to write a test to check the exception handling but I don't know how to do a __try and __except in C.
Any ideas?
Index: dlls/kernel/tests/virtual.c =================================================================== RCS file: /home/wine/wine/dlls/kernel/tests/virtual.c,v retrieving revision 1.2 diff -u -r1.2 virtual.c --- dlls/kernel/tests/virtual.c 10 Feb 2004 20:07:56 -0000 1.2 +++ dlls/kernel/tests/virtual.c 16 May 2004 01:28:00 -0000 @@ -24,6 +24,54 @@ #include "winbase.h" #include "winerror.h" #include "wine/test.h" +#include "excpt.h" +#include "wine/exception.h" + +static WINE_EXCEPTION_FILTER(page_fault) +{ + if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION || + GetExceptionCode() == EXCEPTION_PRIV_INSTRUCTION) + return EXCEPTION_EXECUTE_HANDLER; + return EXCEPTION_CONTINUE_SEARCH; +} + +static void test_VirtualProtect() +{ + DWORD dwPageSize; + BYTE * twoPages, temp; + DWORD old_prot; + SYSTEM_INFO sSysInfo; + BOOL res; + + GetSystemInfo(&sSysInfo); + dwPageSize = sSysInfo.dwPageSize; + + twoPages = VirtualAlloc(0, 2 * dwPageSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); + ok(twoPages!=NULL,"Failed to allocate two pages\n"); + if (twoPages==NULL) + return; + + res = VirtualProtect(twoPages + dwPageSize, dwPageSize, PAGE_NOACCESS, &old_prot); + ok(res,"Failed to set protection for second page\n"); + if (!res) + return; + + __TRY { + temp = twoPages[dwPageSize]; + ok(FALSE,"didn't get fault reading from page with PAGE_NOACCESS\n"); + } __EXCEPT(page_fault) { + ok(TRUE,"got fault\n"); + } __ENDTRY + + __TRY { + twoPages[dwPageSize] = 0; + ok(FALSE,"didn't get fault writing to page with PAGE_NOACCESS\n"); + } __EXCEPT(page_fault) { + ok(TRUE,"got fault\n"); + } __ENDTRY + + ok(VirtualFree(twoPages, 0, MEM_RELEASE), "VirtualFree failed\n"); +}
static void test_VirtualAlloc(void) { @@ -110,4 +158,5 @@ START_TEST(virtual) { test_VirtualAlloc(); + test_VirtualProtect(); }
Robert Reif reif@earthlink.net writes:
I'm trying to write a test that checks for data overruns using VirtualAlloc and VirtualProtect and I think I may have found a bug. Here is the problem:
DWORD dwPageSize; BYTE * twoPages, temp; DWORD flOldProtect; twoPages = VirtualAlloc(NULL, 2 * dwPageSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); res = VirtualProtect(twoPages + dwPageSize, dwPageSize, PAGE_NOACCESS, &flOldProtect); temp = twoPages[dwPageSize + 1]; // should cause exception but doesn't in wine twoPages[dwPageSize + 1] = 0; // does cause exception
Most likely the read access was optimized out. Try doing the access through a volatile pointer.