mirror of
https://github.com/intel/compute-runtime.git
synced 2026-01-07 21:27:04 +08:00
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 <michal.mrozek@intel.com>
This commit is contained in:
committed by
sys_ocldev
parent
093bc4da9c
commit
d4571d685a
@@ -18,10 +18,14 @@ std::function<LONG(struct _EXCEPTION_POINTERS *exceptionInfo)> PageFaultManagerW
|
|||||||
|
|
||||||
PageFaultManagerWindows::PageFaultManagerWindows() {
|
PageFaultManagerWindows::PageFaultManagerWindows() {
|
||||||
pageFaultHandler = [&](struct _EXCEPTION_POINTERS *exceptionInfo) {
|
pageFaultHandler = [&](struct _EXCEPTION_POINTERS *exceptionInfo) {
|
||||||
if (exceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION && !this->verifyPageFault(reinterpret_cast<void *>(exceptionInfo->ExceptionRecord->ExceptionInformation[1]))) {
|
if (exceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) {
|
||||||
return EXCEPTION_CONTINUE_SEARCH;
|
if (this->verifyPageFault(reinterpret_cast<void *>(exceptionInfo->ExceptionRecord->ExceptionInformation[1]))) {
|
||||||
|
//this is our fault that we serviced, continue app execution
|
||||||
|
return EXCEPTION_CONTINUE_EXECUTION;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return EXCEPTION_CONTINUE_EXECUTION;
|
//not our exception
|
||||||
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
};
|
};
|
||||||
|
|
||||||
previousHandler = AddVectoredExceptionHandler(1, pageFaultHandlerWrapper);
|
previousHandler = AddVectoredExceptionHandler(1, pageFaultHandlerWrapper);
|
||||||
|
|||||||
@@ -69,9 +69,10 @@ class MockPageFaultManagerHandlerInvoke : public T {
|
|||||||
if (allowCPUMemoryAccessOnPageFault) {
|
if (allowCPUMemoryAccessOnPageFault) {
|
||||||
this->allowCPUMemoryAccess(ptr, size);
|
this->allowCPUMemoryAccess(ptr, size);
|
||||||
}
|
}
|
||||||
return true;
|
return returnStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool returnStatus = true;
|
||||||
bool allowCPUMemoryAccessOnPageFault = false;
|
bool allowCPUMemoryAccessOnPageFault = false;
|
||||||
bool handlerInvoked = false;
|
bool handlerInvoked = false;
|
||||||
size_t size = 65536;
|
size_t size = 65536;
|
||||||
|
|||||||
@@ -14,14 +14,37 @@
|
|||||||
using namespace NEO;
|
using namespace NEO;
|
||||||
using MockPageFaultManagerWindows = MockPageFaultManagerHandlerInvoke<PageFaultManagerWindows>;
|
using MockPageFaultManagerWindows = MockPageFaultManagerHandlerInvoke<PageFaultManagerWindows>;
|
||||||
|
|
||||||
|
bool raiseException(NTSTATUS type) {
|
||||||
|
__try {
|
||||||
|
RaiseException(type, 0, 0, NULL);
|
||||||
|
} __except (EXCEPTION_EXECUTE_HANDLER) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
TEST(PageFaultManagerWindowsTest, whenPageFaultIsRaisedThenHandlerIsInvoked) {
|
TEST(PageFaultManagerWindowsTest, whenPageFaultIsRaisedThenHandlerIsInvoked) {
|
||||||
auto pageFaultManager = std::make_unique<MockPageFaultManagerWindows>();
|
auto pageFaultManager = std::make_unique<MockPageFaultManagerWindows>();
|
||||||
EXPECT_FALSE(pageFaultManager->handlerInvoked);
|
EXPECT_FALSE(pageFaultManager->handlerInvoked);
|
||||||
|
EXPECT_FALSE(raiseException(EXCEPTION_ACCESS_VIOLATION));
|
||||||
RaiseException(EXCEPTION_ACCESS_VIOLATION, 0, 0, NULL);
|
|
||||||
EXPECT_TRUE(pageFaultManager->handlerInvoked);
|
EXPECT_TRUE(pageFaultManager->handlerInvoked);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(PageFaultManagerWindowsTest, whenExceptionAccessViolationIsRaisedButPointerIsNotKnownThenExceptionIsRethrown) {
|
||||||
|
auto pageFaultManager = std::make_unique<MockPageFaultManagerWindows>();
|
||||||
|
EXPECT_FALSE(pageFaultManager->handlerInvoked);
|
||||||
|
pageFaultManager->returnStatus = false;
|
||||||
|
EXPECT_TRUE(raiseException(EXCEPTION_ACCESS_VIOLATION));
|
||||||
|
EXPECT_TRUE(pageFaultManager->handlerInvoked);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(PageFaultManagerWindowsTest, whenExceptionOtherThanAccessViolationIsRaisedThenExceptionIsRethrownAndHandlerIsNotInvoked) {
|
||||||
|
auto pageFaultManager = std::make_unique<MockPageFaultManagerWindows>();
|
||||||
|
EXPECT_FALSE(pageFaultManager->handlerInvoked);
|
||||||
|
EXPECT_TRUE(raiseException(EXCEPTION_DATATYPE_MISALIGNMENT));
|
||||||
|
EXPECT_FALSE(pageFaultManager->handlerInvoked);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(PageFaultManagerWindowsTest, givenProtectedMemoryWhenTryingToAccessThenPageFaultIsRaisedAndMemoryIsAccessibleAfterHandling) {
|
TEST(PageFaultManagerWindowsTest, givenProtectedMemoryWhenTryingToAccessThenPageFaultIsRaisedAndMemoryIsAccessibleAfterHandling) {
|
||||||
auto pageFaultManager = std::make_unique<MockPageFaultManagerWindows>();
|
auto pageFaultManager = std::make_unique<MockPageFaultManagerWindows>();
|
||||||
pageFaultManager->allowCPUMemoryAccessOnPageFault = true;
|
pageFaultManager->allowCPUMemoryAccessOnPageFault = true;
|
||||||
|
|||||||
Reference in New Issue
Block a user