Skip to content

Commit d4571d6

Browse files
Improve Windows page fault handler.
- Re-throw exception if not access violation exception. - If pointer is not within known pointers also re-throw. Change-Id: I01461f550994e32c9e8757b0344e70f2195612fb Signed-off-by: Mrozek, Michal <[email protected]>
1 parent 093bc4d commit d4571d6

File tree

3 files changed

+33
-5
lines changed

3 files changed

+33
-5
lines changed

core/page_fault_manager/windows/cpu_page_fault_manager_windows.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,14 @@ std::function<LONG(struct _EXCEPTION_POINTERS *exceptionInfo)> PageFaultManagerW
1818

1919
PageFaultManagerWindows::PageFaultManagerWindows() {
2020
pageFaultHandler = [&](struct _EXCEPTION_POINTERS *exceptionInfo) {
21-
if (exceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION && !this->verifyPageFault(reinterpret_cast<void *>(exceptionInfo->ExceptionRecord->ExceptionInformation[1]))) {
22-
return EXCEPTION_CONTINUE_SEARCH;
21+
if (exceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) {
22+
if (this->verifyPageFault(reinterpret_cast<void *>(exceptionInfo->ExceptionRecord->ExceptionInformation[1]))) {
23+
//this is our fault that we serviced, continue app execution
24+
return EXCEPTION_CONTINUE_EXECUTION;
25+
}
2326
}
24-
return EXCEPTION_CONTINUE_EXECUTION;
27+
//not our exception
28+
return EXCEPTION_CONTINUE_SEARCH;
2529
};
2630

2731
previousHandler = AddVectoredExceptionHandler(1, pageFaultHandlerWrapper);

core/unit_tests/page_fault_manager/mock_cpu_page_fault_manager.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,10 @@ class MockPageFaultManagerHandlerInvoke : public T {
6969
if (allowCPUMemoryAccessOnPageFault) {
7070
this->allowCPUMemoryAccess(ptr, size);
7171
}
72-
return true;
72+
return returnStatus;
7373
}
7474

75+
bool returnStatus = true;
7576
bool allowCPUMemoryAccessOnPageFault = false;
7677
bool handlerInvoked = false;
7778
size_t size = 65536;

core/unit_tests/page_fault_manager/windows/cpu_page_fault_manager_windows_tests.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,37 @@
1414
using namespace NEO;
1515
using MockPageFaultManagerWindows = MockPageFaultManagerHandlerInvoke<PageFaultManagerWindows>;
1616

17+
bool raiseException(NTSTATUS type) {
18+
__try {
19+
RaiseException(type, 0, 0, NULL);
20+
} __except (EXCEPTION_EXECUTE_HANDLER) {
21+
return true;
22+
}
23+
return false;
24+
}
25+
1726
TEST(PageFaultManagerWindowsTest, whenPageFaultIsRaisedThenHandlerIsInvoked) {
1827
auto pageFaultManager = std::make_unique<MockPageFaultManagerWindows>();
1928
EXPECT_FALSE(pageFaultManager->handlerInvoked);
29+
EXPECT_FALSE(raiseException(EXCEPTION_ACCESS_VIOLATION));
30+
EXPECT_TRUE(pageFaultManager->handlerInvoked);
31+
}
2032

21-
RaiseException(EXCEPTION_ACCESS_VIOLATION, 0, 0, NULL);
33+
TEST(PageFaultManagerWindowsTest, whenExceptionAccessViolationIsRaisedButPointerIsNotKnownThenExceptionIsRethrown) {
34+
auto pageFaultManager = std::make_unique<MockPageFaultManagerWindows>();
35+
EXPECT_FALSE(pageFaultManager->handlerInvoked);
36+
pageFaultManager->returnStatus = false;
37+
EXPECT_TRUE(raiseException(EXCEPTION_ACCESS_VIOLATION));
2238
EXPECT_TRUE(pageFaultManager->handlerInvoked);
2339
}
2440

41+
TEST(PageFaultManagerWindowsTest, whenExceptionOtherThanAccessViolationIsRaisedThenExceptionIsRethrownAndHandlerIsNotInvoked) {
42+
auto pageFaultManager = std::make_unique<MockPageFaultManagerWindows>();
43+
EXPECT_FALSE(pageFaultManager->handlerInvoked);
44+
EXPECT_TRUE(raiseException(EXCEPTION_DATATYPE_MISALIGNMENT));
45+
EXPECT_FALSE(pageFaultManager->handlerInvoked);
46+
}
47+
2548
TEST(PageFaultManagerWindowsTest, givenProtectedMemoryWhenTryingToAccessThenPageFaultIsRaisedAndMemoryIsAccessibleAfterHandling) {
2649
auto pageFaultManager = std::make_unique<MockPageFaultManagerWindows>();
2750
pageFaultManager->allowCPUMemoryAccessOnPageFault = true;

0 commit comments

Comments
 (0)