feature: capture multiple cpu pagefault handler

Recorded multiple page fault handlers by using vector in
cpu_page_fault_manager_linux.

Added a static handlerIndex in order to track the depth of
handler logic to call appropriate previous handlers.

Related-To: NEO-11563
Signed-off-by: Young Jin Yoon <young.jin.yoon@intel.com>
This commit is contained in:
Young Jin Yoon
2024-07-17 19:10:37 +00:00
committed by Compute-Runtime-Automation
parent f005574f3e
commit b1f73355ac
9 changed files with 328 additions and 37 deletions

View File

@@ -253,6 +253,8 @@ TEST_F(PageFaultManagerTest, givenUnifiedMemoryAllocWhenMoveToGpuDomainThenTrans
}
TEST_F(PageFaultManagerTest, givenUnifiedMemoryAllocWhenMoveToGpuDomainTwiceThenCheckFaultHandlerFromPageFaultManagerReturnsTrue) {
DebugManagerStateRestore restorer;
debugManager.flags.RegisterPageFaultHandlerOnMigration.set(true);
void *cmdQ = reinterpret_cast<void *>(0xFFFF);
void *alloc1 = reinterpret_cast<void *>(0x1);
void *alloc2 = reinterpret_cast<void *>(0x2);
@@ -262,7 +264,7 @@ TEST_F(PageFaultManagerTest, givenUnifiedMemoryAllocWhenMoveToGpuDomainTwiceThen
EXPECT_EQ(pageFaultManager->memoryData.size(), 2u);
EXPECT_EQ(pageFaultManager->transferToCpuCalled, 0);
EXPECT_FALSE(pageFaultManager->checkFaultHandlerFromPageFaultManager());
pageFaultManager->isFaultHandlerFromPageFaultManager = false;
pageFaultManager->moveAllocationToGpuDomain(alloc1);
EXPECT_EQ(pageFaultManager->allowMemoryAccessCalled, 0);
@@ -274,7 +276,9 @@ TEST_F(PageFaultManagerTest, givenUnifiedMemoryAllocWhenMoveToGpuDomainTwiceThen
EXPECT_EQ(pageFaultManager->protectedSize, 10u);
EXPECT_EQ(pageFaultManager->transferToGpuAddress, alloc1);
EXPECT_TRUE(pageFaultManager->checkFaultHandlerFromPageFaultManager());
EXPECT_FALSE(pageFaultManager->checkFaultHandlerFromPageFaultManager());
pageFaultManager->isFaultHandlerFromPageFaultManager = true;
pageFaultManager->moveAllocationToGpuDomain(alloc2);
EXPECT_EQ(pageFaultManager->allowMemoryAccessCalled, 0);
@@ -289,6 +293,44 @@ TEST_F(PageFaultManagerTest, givenUnifiedMemoryAllocWhenMoveToGpuDomainTwiceThen
EXPECT_TRUE(pageFaultManager->checkFaultHandlerFromPageFaultManager());
}
TEST_F(PageFaultManagerTest, givenUnifiedMemoryAllocWhenMoveToGpuDomainTwiceThenRegisterFaultHandlerIsCalledTwice) {
DebugManagerStateRestore restorer;
debugManager.flags.RegisterPageFaultHandlerOnMigration.set(true);
void *cmdQ = reinterpret_cast<void *>(0xFFFF);
void *alloc1 = reinterpret_cast<void *>(0x1);
void *alloc2 = reinterpret_cast<void *>(0x2);
pageFaultManager->insertAllocation(alloc1, 10u, unifiedMemoryManager.get(), cmdQ, {});
pageFaultManager->insertAllocation(alloc2, 20u, unifiedMemoryManager.get(), cmdQ, {});
EXPECT_EQ(pageFaultManager->memoryData.size(), 2u);
EXPECT_EQ(pageFaultManager->transferToCpuCalled, 0);
pageFaultManager->isFaultHandlerFromPageFaultManager = false;
pageFaultManager->moveAllocationToGpuDomain(alloc1);
EXPECT_EQ(pageFaultManager->allowMemoryAccessCalled, 0);
EXPECT_EQ(pageFaultManager->protectMemoryCalled, 1);
EXPECT_EQ(pageFaultManager->transferToCpuCalled, 0);
EXPECT_EQ(pageFaultManager->transferToGpuCalled, 1);
EXPECT_EQ(pageFaultManager->registerFaultHandlerCalled, 1);
EXPECT_EQ(pageFaultManager->protectedMemoryAccessAddress, alloc1);
EXPECT_EQ(pageFaultManager->protectedSize, 10u);
EXPECT_EQ(pageFaultManager->transferToGpuAddress, alloc1);
EXPECT_FALSE(pageFaultManager->checkFaultHandlerFromPageFaultManager());
pageFaultManager->moveAllocationToGpuDomain(alloc2);
EXPECT_EQ(pageFaultManager->allowMemoryAccessCalled, 0);
EXPECT_EQ(pageFaultManager->protectMemoryCalled, 2);
EXPECT_EQ(pageFaultManager->transferToCpuCalled, 0);
EXPECT_EQ(pageFaultManager->transferToGpuCalled, 2);
EXPECT_EQ(pageFaultManager->registerFaultHandlerCalled, 2);
EXPECT_EQ(pageFaultManager->protectedMemoryAccessAddress, alloc2);
EXPECT_EQ(pageFaultManager->protectedSize, 20u);
EXPECT_EQ(pageFaultManager->transferToGpuAddress, alloc2);
EXPECT_FALSE(pageFaultManager->checkFaultHandlerFromPageFaultManager());
}
TEST_F(PageFaultManagerTest, givenRegisterPageFaultHandlerOnMigrationDisabledWhenMoveToGpuDomainThenDoNotRegisterHandler) {
DebugManagerStateRestore restorer;
debugManager.flags.RegisterPageFaultHandlerOnMigration.set(false);
@@ -397,14 +439,17 @@ TEST_F(PageFaultManagerTest, whenMovingToGpuDomainUntrackedAllocThenNothingIsCal
TEST_F(PageFaultManagerTest, givenHandlerRegisteredAndUntrackedPageFaultAddressWhenVerifyingThenFalseIsReturned) {
void *alloc1 = reinterpret_cast<void *>(0x1);
void *alloc2 = reinterpret_cast<void *>(0x100);
void *alloc3 = reinterpret_cast<void *>(0x10000);
void *alloc2 = reinterpret_cast<void *>(0x10);
void *alloc3 = reinterpret_cast<void *>(0x100);
void *alloc4 = reinterpret_cast<void *>(0x1000);
pageFaultManager->insertAllocation(alloc1, 10, unifiedMemoryManager.get(), nullptr, {});
pageFaultManager->insertAllocation(alloc2, 20, unifiedMemoryManager.get(), nullptr, {});
pageFaultManager->insertAllocation(alloc2, 10, unifiedMemoryManager.get(), nullptr, {});
pageFaultManager->insertAllocation(alloc3, 20, unifiedMemoryManager.get(), nullptr, {});
EXPECT_EQ(pageFaultManager->memoryData.size(), 2u);
auto retVal = pageFaultManager->verifyPageFault(alloc3);
auto retVal = pageFaultManager->verifyAndHandlePageFault(alloc1, true);
EXPECT_FALSE(retVal);
retVal = pageFaultManager->verifyAndHandlePageFault(alloc4, true);
EXPECT_FALSE(retVal);
}
@@ -417,7 +462,13 @@ TEST_F(PageFaultManagerTest, givenTrackedPageFaultAddressWhenVerifyingThenProper
EXPECT_EQ(pageFaultManager->transferToCpuCalled, 0);
EXPECT_EQ(pageFaultManager->memoryData.size(), 2u);
pageFaultManager->verifyPageFault(alloc1);
pageFaultManager->verifyAndHandlePageFault(alloc1, false);
EXPECT_EQ(pageFaultManager->allowMemoryAccessCalled, 0);
EXPECT_EQ(pageFaultManager->protectMemoryCalled, 0);
EXPECT_EQ(pageFaultManager->transferToCpuCalled, 0);
EXPECT_EQ(pageFaultManager->transferToGpuCalled, 0);
pageFaultManager->verifyAndHandlePageFault(alloc1, true);
EXPECT_EQ(pageFaultManager->allowMemoryAccessCalled, 1);
EXPECT_EQ(pageFaultManager->protectMemoryCalled, 0);
EXPECT_EQ(pageFaultManager->transferToCpuCalled, 0);
@@ -438,7 +489,7 @@ TEST_F(PageFaultManagerTest, givenInitialPlacementCpuWhenVerifyingPagefaultThenF
EXPECT_EQ(unifiedMemoryManager->nonGpuDomainAllocs.size(), 1u);
EXPECT_EQ(unifiedMemoryManager->nonGpuDomainAllocs[0], alloc);
pageFaultManager->verifyPageFault(alloc);
pageFaultManager->verifyAndHandlePageFault(alloc, true);
EXPECT_EQ(pageFaultManager->allowMemoryAccessCalled, 1);
EXPECT_EQ(pageFaultManager->protectMemoryCalled, 0);
EXPECT_EQ(pageFaultManager->transferToCpuCalled, 0);
@@ -464,13 +515,13 @@ TEST_F(PageFaultManagerTest, givenAllocsMovedToGpuDomainWhenVerifyingPageFaultTh
pageFaultManager->moveAllocationsWithinUMAllocsManagerToGpuDomain(unifiedMemoryManager.get());
EXPECT_EQ(unifiedMemoryManager->nonGpuDomainAllocs.size(), 0u);
pageFaultManager->verifyPageFault(alloc2);
pageFaultManager->verifyAndHandlePageFault(alloc2, true);
EXPECT_EQ(unifiedMemoryManager->nonGpuDomainAllocs.size(), 1u);
EXPECT_EQ(unifiedMemoryManager->nonGpuDomainAllocs[0], alloc2);
pageFaultManager->gpuDomainHandler = &MockPageFaultManager::unprotectAndTransferMemory;
pageFaultManager->verifyPageFault(alloc1);
pageFaultManager->verifyAndHandlePageFault(alloc1, true);
EXPECT_EQ(unifiedMemoryManager->nonGpuDomainAllocs.size(), 2u);
EXPECT_EQ(unifiedMemoryManager->nonGpuDomainAllocs[1], alloc1);
}
@@ -489,13 +540,13 @@ TEST_F(PageFaultManagerTest, givenAllocsFromCpuDomainWhenVerifyingPageFaultThenD
EXPECT_EQ(unifiedMemoryManager->nonGpuDomainAllocs.size(), 0u);
pageFaultManager->memoryData.at(alloc2).domain = PageFaultManager::AllocationDomain::none;
pageFaultManager->verifyPageFault(alloc2);
pageFaultManager->verifyAndHandlePageFault(alloc2, true);
EXPECT_EQ(pageFaultManager->memoryData.at(alloc2).domain, PageFaultManager::AllocationDomain::cpu);
EXPECT_EQ(unifiedMemoryManager->nonGpuDomainAllocs.size(), 0u);
pageFaultManager->gpuDomainHandler = &MockPageFaultManager::unprotectAndTransferMemory;
pageFaultManager->memoryData.at(alloc1).domain = PageFaultManager::AllocationDomain::none;
pageFaultManager->verifyPageFault(alloc1);
pageFaultManager->verifyAndHandlePageFault(alloc1, true);
EXPECT_EQ(pageFaultManager->memoryData.at(alloc1).domain, PageFaultManager::AllocationDomain::cpu);
EXPECT_EQ(unifiedMemoryManager->nonGpuDomainAllocs.size(), 0u);
}
@@ -514,7 +565,7 @@ TEST_F(PageFaultManagerTest, givenTbxWhenVerifyingPagefaultThenVerifyPagefaultUn
EXPECT_EQ(pageFaultManager->protectMemoryCalled, 1);
EXPECT_EQ(pageFaultManager->transferToGpuCalled, 0);
pageFaultManager->verifyPageFault(alloc);
pageFaultManager->verifyAndHandlePageFault(alloc, true);
EXPECT_EQ(pageFaultManager->allowMemoryAccessCalled, 1);
EXPECT_EQ(pageFaultManager->transferToCpuCalled, 1);
EXPECT_EQ(pageFaultManager->allowedMemoryAccessAddress, alloc);
@@ -541,7 +592,7 @@ TEST_F(PageFaultManagerTest, whenVerifyingPagefaultWithPrintUsmSharedMigrationDe
EXPECT_EQ(pageFaultManager->protectedMemoryAccessAddress, alloc);
EXPECT_EQ(pageFaultManager->protectedSize, 10u);
pageFaultManager->verifyPageFault(alloc);
pageFaultManager->verifyAndHandlePageFault(alloc, true);
std::string output = testing::internal::GetCapturedStdout(); // stop capturing
@@ -580,7 +631,7 @@ TEST_F(PageFaultManagerTest, givenTbxWhenVerifyingPagefaultWithPrintUsmSharedMig
EXPECT_EQ(pageFaultManager->protectedMemoryAccessAddress, alloc);
EXPECT_EQ(pageFaultManager->protectedSize, 10u);
pageFaultManager->verifyPageFault(alloc);
pageFaultManager->verifyAndHandlePageFault(alloc, true);
std::string output = testing::internal::GetCapturedStdout(); // stop capturing
@@ -614,7 +665,7 @@ TEST_F(PageFaultManagerTest, givenTbxAndInitialPlacementGpuWhenVerifyingPagefaul
EXPECT_EQ(pageFaultManager->protectedSize, 10u);
EXPECT_EQ(pageFaultManager->memoryData.size(), 1u);
pageFaultManager->verifyPageFault(alloc);
pageFaultManager->verifyAndHandlePageFault(alloc, true);
EXPECT_EQ(pageFaultManager->allowMemoryAccessCalled, 1);
EXPECT_EQ(pageFaultManager->transferToGpuCalled, 0);
@@ -670,7 +721,7 @@ TEST_F(PageFaultManagerTest, givenAllocationMovedToGpuDomainWhenVerifyingPagefau
EXPECT_EQ(pageFaultManager->transferToGpuCalled, 0);
EXPECT_EQ(unifiedMemoryManager->nonGpuDomainAllocs.size(), 0u);
pageFaultManager->verifyPageFault(alloc);
pageFaultManager->verifyAndHandlePageFault(alloc, true);
EXPECT_EQ(pageFaultManager->allowMemoryAccessCalled, 1);
EXPECT_EQ(pageFaultManager->transferToCpuCalled, 1);
EXPECT_EQ(pageFaultManager->transferToGpuCalled, 0);
@@ -682,6 +733,35 @@ TEST_F(PageFaultManagerTest, givenAllocationMovedToGpuDomainWhenVerifyingPagefau
EXPECT_EQ(unifiedMemoryManager->nonGpuDomainAllocs[0], alloc);
}
TEST_F(PageFaultManagerTest, givenAllocationMovedToGpuDomainWhenVerifyingPagefaultWithHandlePageFaultFalseThenAllocationIsNotMovedToCpuDomain) {
void *cmdQ = reinterpret_cast<void *>(0xFFFF);
void *alloc = reinterpret_cast<void *>(0x1);
memoryProperties.allocFlags.usmInitialPlacementGpu = 1;
pageFaultManager->insertAllocation(alloc, 10, unifiedMemoryManager.get(), cmdQ, memoryProperties);
EXPECT_EQ(pageFaultManager->transferToCpuCalled, 0);
EXPECT_EQ(pageFaultManager->memoryData.size(), 1u);
EXPECT_EQ(pageFaultManager->protectMemoryCalled, 1);
EXPECT_EQ(pageFaultManager->protectedMemoryAccessAddress, alloc);
EXPECT_EQ(pageFaultManager->protectedSize, 10u);
EXPECT_EQ(unifiedMemoryManager->nonGpuDomainAllocs.size(), 1u);
EXPECT_EQ(unifiedMemoryManager->nonGpuDomainAllocs[0], alloc);
pageFaultManager->moveAllocationToGpuDomain(alloc);
EXPECT_EQ(pageFaultManager->allowMemoryAccessCalled, 0);
EXPECT_EQ(pageFaultManager->protectMemoryCalled, 1);
EXPECT_EQ(pageFaultManager->transferToCpuCalled, 0);
EXPECT_EQ(pageFaultManager->transferToGpuCalled, 0);
EXPECT_EQ(unifiedMemoryManager->nonGpuDomainAllocs.size(), 0u);
pageFaultManager->verifyAndHandlePageFault(alloc, false);
EXPECT_EQ(pageFaultManager->allowMemoryAccessCalled, 0);
EXPECT_EQ(pageFaultManager->protectMemoryCalled, 1);
EXPECT_EQ(pageFaultManager->transferToCpuCalled, 0);
EXPECT_EQ(pageFaultManager->transferToGpuCalled, 0);
EXPECT_EQ(unifiedMemoryManager->nonGpuDomainAllocs.size(), 0u);
}
TEST_F(PageFaultManagerTest, givenUnifiedMemoryAllocWhenSetAubWritableIsCalledThenAllocIsAubWritable) {
REQUIRE_SVM_OR_SKIP(executionEnvironment.rootDeviceEnvironments[0]->getHardwareInfo());
@@ -727,7 +807,7 @@ TEST_F(PageFaultManagerTest, givenUnifiedMemoryAllocWhenMigratedBetweenCpuAndGpu
EXPECT_EQ(pageFaultManager->protectedMemoryAccessAddress, ptr);
EXPECT_EQ(pageFaultManager->protectedSize, 10u);
pageFaultManager->verifyPageFault(ptr);
pageFaultManager->verifyAndHandlePageFault(ptr, true);
EXPECT_EQ(pageFaultManager->transferToCpuCalled, 1);
EXPECT_EQ(pageFaultManager->allowMemoryAccessCalled, 1);
EXPECT_EQ(pageFaultManager->setCpuAllocEvictableCalled, 2);

View File

@@ -125,10 +125,14 @@ class MockFailPageFaultManager : public PageFaultManagerLinux {
using PageFaultManagerLinux::checkFaultHandlerFromPageFaultManager;
using PageFaultManagerLinux::PageFaultManagerLinux;
using PageFaultManagerLinux::previousHandlerRestored;
using PageFaultManagerLinux::previousPageFaultHandlers;
using PageFaultManagerLinux::registerFaultHandler;
bool verifyPageFault(void *ptr) override {
bool verifyAndHandlePageFault(void *ptr, bool handlePageFault) override {
verifyCalled = true;
if (handlePageFault) {
numPageFaultHandled++;
}
return false;
}
@@ -136,22 +140,38 @@ class MockFailPageFaultManager : public PageFaultManagerLinux {
mockCalled = true;
}
static void mockPageFaultHandler2(int signal, siginfo_t *info, void *context) {
mockCalled2 = true;
pageFaultHandlerWrapper(signal, info, context);
}
static void mockPageFaultSimpleHandler(int signal) {
simpleMockCalled = true;
}
static void mockPageFaultSimpleHandler2(int signal) {
simpleMockCalled2 = true;
}
~MockFailPageFaultManager() override {
mockCalled = false;
mockCalled2 = false;
simpleMockCalled = false;
simpleMockCalled2 = false;
}
static bool mockCalled;
static bool mockCalled2;
static bool simpleMockCalled;
static bool simpleMockCalled2;
bool verifyCalled = false;
int numPageFaultHandled = 0;
};
bool MockFailPageFaultManager::mockCalled = false;
bool MockFailPageFaultManager::mockCalled2 = false;
bool MockFailPageFaultManager::simpleMockCalled = false;
bool MockFailPageFaultManager::simpleMockCalled2 = false;
TEST_F(PageFaultManagerLinuxTest, givenPageFaultThatNEOShouldNotHandleAndSigInfoFlagSetThenSaSigactionIsCalled) {
struct sigaction previousHandler = {};
@@ -184,6 +204,7 @@ TEST_F(PageFaultManagerLinuxTest, givenPageFaultThatNEOShouldNotHandleThenSaHand
auto mockPageFaultManager = std::make_unique<MockFailPageFaultManager>();
EXPECT_FALSE(MockFailPageFaultManager::mockCalled);
EXPECT_FALSE(MockFailPageFaultManager::simpleMockCalled);
EXPECT_EQ(1ul, mockPageFaultManager->previousPageFaultHandlers.size());
std::raise(SIGSEGV);
EXPECT_TRUE(mockPageFaultManager->verifyCalled);
@@ -243,3 +264,170 @@ TEST_F(PageFaultManagerLinuxTest, givenDefaultSaHandlerWhenOverwritingNewHandler
mockPageFaultManager.reset();
sigaction(SIGSEGV, &originalHandler, nullptr);
}
TEST_F(PageFaultManagerLinuxTest, givenPageFaultThatNEOShouldNotHandleWhenRegisterSimpleHandlerTwiceThenSimpleHandlerIsRegisteredOnce) {
struct sigaction previousHandler = {};
struct sigaction previousHandler2 = {};
struct sigaction mockHandler = {};
struct sigaction mockHandler2 = {};
mockHandler.sa_handler = MockFailPageFaultManager::mockPageFaultSimpleHandler;
auto retVal = sigaction(SIGSEGV, &mockHandler, &previousHandler);
EXPECT_EQ(retVal, 0);
auto mockPageFaultManager = std::make_unique<MockFailPageFaultManager>();
EXPECT_FALSE(MockFailPageFaultManager::mockCalled);
EXPECT_FALSE(MockFailPageFaultManager::simpleMockCalled);
EXPECT_EQ(1ul, mockPageFaultManager->previousPageFaultHandlers.size());
std::raise(SIGSEGV);
EXPECT_TRUE(mockPageFaultManager->verifyCalled);
EXPECT_EQ(1, mockPageFaultManager->numPageFaultHandled);
EXPECT_FALSE(MockFailPageFaultManager::mockCalled);
EXPECT_TRUE(MockFailPageFaultManager::simpleMockCalled);
MockFailPageFaultManager::simpleMockCalled = false;
mockHandler2.sa_handler = MockFailPageFaultManager::mockPageFaultSimpleHandler;
retVal = sigaction(SIGSEGV, &mockHandler2, &previousHandler2);
EXPECT_EQ(retVal, 0);
mockPageFaultManager->registerFaultHandler();
std::raise(SIGSEGV);
EXPECT_TRUE(mockPageFaultManager->verifyCalled);
EXPECT_EQ(2, mockPageFaultManager->numPageFaultHandled);
EXPECT_FALSE(MockFailPageFaultManager::mockCalled);
EXPECT_TRUE(MockFailPageFaultManager::simpleMockCalled);
EXPECT_EQ(1ul, mockPageFaultManager->previousPageFaultHandlers.size());
mockPageFaultManager.reset();
sigaction(SIGSEGV, &previousHandler, nullptr);
}
TEST_F(PageFaultManagerLinuxTest, givenPageFaultThatNEOShouldNotHandleWhenRegisterTwoSimpleHandlersThenBothHandlersAreRegistered) {
struct sigaction previousHandler = {};
struct sigaction previousHandler2 = {};
struct sigaction mockHandler = {};
struct sigaction mockHandler2 = {};
mockHandler.sa_handler = MockFailPageFaultManager::mockPageFaultSimpleHandler;
auto retVal = sigaction(SIGSEGV, &mockHandler, &previousHandler);
EXPECT_EQ(retVal, 0);
auto mockPageFaultManager = std::make_unique<MockFailPageFaultManager>();
EXPECT_FALSE(MockFailPageFaultManager::mockCalled);
EXPECT_FALSE(MockFailPageFaultManager::mockCalled2);
EXPECT_FALSE(MockFailPageFaultManager::simpleMockCalled);
EXPECT_FALSE(MockFailPageFaultManager::simpleMockCalled2);
EXPECT_EQ(1ul, mockPageFaultManager->previousPageFaultHandlers.size());
std::raise(SIGSEGV);
EXPECT_TRUE(mockPageFaultManager->verifyCalled);
EXPECT_FALSE(MockFailPageFaultManager::mockCalled);
EXPECT_FALSE(MockFailPageFaultManager::mockCalled2);
EXPECT_TRUE(MockFailPageFaultManager::simpleMockCalled);
EXPECT_FALSE(MockFailPageFaultManager::simpleMockCalled2);
MockFailPageFaultManager::simpleMockCalled = false;
mockHandler2.sa_handler = MockFailPageFaultManager::mockPageFaultSimpleHandler2;
retVal = sigaction(SIGSEGV, &mockHandler2, &previousHandler2);
EXPECT_EQ(retVal, 0);
mockPageFaultManager->registerFaultHandler();
std::raise(SIGSEGV);
EXPECT_TRUE(mockPageFaultManager->verifyCalled);
EXPECT_FALSE(MockFailPageFaultManager::mockCalled);
EXPECT_FALSE(MockFailPageFaultManager::mockCalled2);
EXPECT_FALSE(MockFailPageFaultManager::simpleMockCalled);
EXPECT_TRUE(MockFailPageFaultManager::simpleMockCalled2);
EXPECT_EQ(2ul, mockPageFaultManager->previousPageFaultHandlers.size());
mockPageFaultManager.reset();
sigaction(SIGSEGV, &previousHandler, nullptr);
}
TEST_F(PageFaultManagerLinuxTest, givenPageFaultThatNEOShouldNotHandleWhenRegisterTwoHandlersThenBothHandlersAreRegistered) {
struct sigaction previousHandler = {};
struct sigaction previousHandler2 = {};
struct sigaction mockHandler = {};
struct sigaction mockHandler2 = {};
mockHandler.sa_flags = SA_SIGINFO;
mockHandler.sa_sigaction = MockFailPageFaultManager::mockPageFaultHandler;
auto retVal = sigaction(SIGSEGV, &mockHandler, &previousHandler);
EXPECT_EQ(retVal, 0);
auto mockPageFaultManager = std::make_unique<MockFailPageFaultManager>();
EXPECT_FALSE(MockFailPageFaultManager::mockCalled);
EXPECT_FALSE(MockFailPageFaultManager::mockCalled2);
EXPECT_FALSE(MockFailPageFaultManager::simpleMockCalled);
EXPECT_FALSE(MockFailPageFaultManager::simpleMockCalled2);
EXPECT_EQ(1ul, mockPageFaultManager->previousPageFaultHandlers.size());
std::raise(SIGSEGV);
EXPECT_TRUE(mockPageFaultManager->verifyCalled);
EXPECT_TRUE(MockFailPageFaultManager::mockCalled);
EXPECT_FALSE(MockFailPageFaultManager::mockCalled2);
EXPECT_FALSE(MockFailPageFaultManager::simpleMockCalled);
EXPECT_FALSE(MockFailPageFaultManager::simpleMockCalled2);
MockFailPageFaultManager::mockCalled = false;
mockHandler2.sa_flags = SA_SIGINFO;
mockHandler2.sa_sigaction = MockFailPageFaultManager::mockPageFaultHandler2;
retVal = sigaction(SIGSEGV, &mockHandler2, &previousHandler2);
EXPECT_EQ(retVal, 0);
mockPageFaultManager->registerFaultHandler();
std::raise(SIGSEGV);
EXPECT_TRUE(mockPageFaultManager->verifyCalled);
EXPECT_TRUE(MockFailPageFaultManager::mockCalled);
EXPECT_TRUE(MockFailPageFaultManager::mockCalled2);
EXPECT_FALSE(MockFailPageFaultManager::simpleMockCalled);
EXPECT_FALSE(MockFailPageFaultManager::simpleMockCalled2);
EXPECT_EQ(2ul, mockPageFaultManager->previousPageFaultHandlers.size());
mockPageFaultManager.reset();
sigaction(SIGSEGV, &previousHandler, nullptr);
}
TEST_F(PageFaultManagerLinuxTest, givenPageFaultThatNEOShouldNotHandleWhenRegisterSimpleAndRegularHandlersThenBothHandlersAreRegistered) {
struct sigaction previousHandler = {};
struct sigaction previousHandler2 = {};
struct sigaction mockHandler = {};
struct sigaction mockHandler2 = {};
mockHandler.sa_handler = MockFailPageFaultManager::mockPageFaultSimpleHandler;
auto retVal = sigaction(SIGSEGV, &mockHandler, &previousHandler);
EXPECT_EQ(retVal, 0);
auto mockPageFaultManager = std::make_unique<MockFailPageFaultManager>();
EXPECT_FALSE(MockFailPageFaultManager::mockCalled);
EXPECT_FALSE(MockFailPageFaultManager::mockCalled2);
EXPECT_FALSE(MockFailPageFaultManager::simpleMockCalled);
EXPECT_FALSE(MockFailPageFaultManager::simpleMockCalled2);
EXPECT_EQ(1ul, mockPageFaultManager->previousPageFaultHandlers.size());
std::raise(SIGSEGV);
EXPECT_TRUE(mockPageFaultManager->verifyCalled);
EXPECT_FALSE(MockFailPageFaultManager::mockCalled);
EXPECT_FALSE(MockFailPageFaultManager::mockCalled2);
EXPECT_TRUE(MockFailPageFaultManager::simpleMockCalled);
EXPECT_FALSE(MockFailPageFaultManager::simpleMockCalled2);
MockFailPageFaultManager::simpleMockCalled = false;
mockHandler2.sa_flags = SA_SIGINFO;
mockHandler2.sa_sigaction = MockFailPageFaultManager::mockPageFaultHandler2;
retVal = sigaction(SIGSEGV, &mockHandler2, &previousHandler2);
EXPECT_EQ(retVal, 0);
mockPageFaultManager->registerFaultHandler();
std::raise(SIGSEGV);
EXPECT_TRUE(mockPageFaultManager->verifyCalled);
EXPECT_FALSE(MockFailPageFaultManager::mockCalled);
EXPECT_TRUE(MockFailPageFaultManager::mockCalled2);
EXPECT_TRUE(MockFailPageFaultManager::simpleMockCalled);
EXPECT_FALSE(MockFailPageFaultManager::simpleMockCalled2);
EXPECT_EQ(2ul, mockPageFaultManager->previousPageFaultHandlers.size());
mockPageFaultManager.reset();
sigaction(SIGSEGV, &previousHandler, nullptr);
}

View File

@@ -76,7 +76,7 @@ class MockFailPageFaultManager : public PageFaultManagerWindows {
using PageFaultManagerWindows::checkFaultHandlerFromPageFaultManager;
using PageFaultManagerWindows::PageFaultManagerWindows;
bool verifyPageFault(void *ptr) override {
bool verifyAndHandlePageFault(void *ptr, bool handlePageFault) override {
verifyCalled = true;
return false;
}