diff --git a/level_zero/tools/source/debug/windows/debug_session.cpp b/level_zero/tools/source/debug/windows/debug_session.cpp index e823d924ac..d79a6eaa2b 100644 --- a/level_zero/tools/source/debug/windows/debug_session.cpp +++ b/level_zero/tools/source/debug/windows/debug_session.cpp @@ -377,7 +377,19 @@ ze_result_t DebugSessionWindows::translateEscapeReturnStatusToZeResult(uint32_t } ze_result_t DebugSessionWindows::readElfSpace(const zet_debug_memory_space_desc_t *desc, size_t size, void *buffer) { - return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + + KM_ESCAPE_INFO escapeInfo = {0}; + escapeInfo.KmEuDbgL0EscapeInfo.EscapeActionType = DBGUMD_ACTION_READ_UMD_MEMORY; + escapeInfo.KmEuDbgL0EscapeInfo.ReadUmdMemoryParams.hElfHandle = desc->address; + escapeInfo.KmEuDbgL0EscapeInfo.ReadUmdMemoryParams.BufferSize = static_cast(size); + escapeInfo.KmEuDbgL0EscapeInfo.ReadUmdMemoryParams.BufferPtr = reinterpret_cast(buffer); + + auto status = runEscape(escapeInfo); + if (STATUS_SUCCESS != status || DBGUMD_RETURN_ESCAPE_SUCCESS != escapeInfo.KmEuDbgL0EscapeInfo.EscapeReturnStatus) { + PRINT_DEBUGGER_ERROR_LOG("DBGUMD_ACTION_READ_UMD_MEMORY: Failed - ProcessId: %d Status: %d EscapeReturnStatus: %d\n", processId, status, escapeInfo.KmEuDbgL0EscapeInfo.EscapeReturnStatus); + return DebugSessionWindows::translateEscapeReturnStatusToZeResult(escapeInfo.KmEuDbgL0EscapeInfo.EscapeReturnStatus); + } + return ZE_RESULT_SUCCESS; } bool DebugSessionWindows::isVAElf(const zet_debug_memory_space_desc_t *desc, size_t size) { diff --git a/level_zero/tools/test/unit_tests/sources/debug/windows/test_debug_api_windows.cpp b/level_zero/tools/test/unit_tests/sources/debug/windows/test_debug_api_windows.cpp index 356ff5195f..ac12fdf526 100644 --- a/level_zero/tools/test/unit_tests/sources/debug/windows/test_debug_api_windows.cpp +++ b/level_zero/tools/test/unit_tests/sources/debug/windows/test_debug_api_windows.cpp @@ -1097,7 +1097,7 @@ TEST_F(DebugApiWindowsTest, WhenCallingReadMemoryForSingleThreadThenMemoryIsRead EXPECT_EQ(ZE_RESULT_SUCCESS, retVal); } -TEST_F(DebugApiWindowsTest, WhenCallingReadMemoryForElfThenUnsupportedFeatureIsReturned) { +TEST_F(DebugApiWindowsTest, WhenCallingReadMemoryForElfThenElfisRead) { auto session = std::make_unique(zet_debug_config_t{0x1234}, device); ASSERT_NE(nullptr, session); session->wddm = mockWddm; @@ -1114,7 +1114,7 @@ TEST_F(DebugApiWindowsTest, WhenCallingReadMemoryForElfThenUnsupportedFeatureIsR MockDebugSessionWindows::ElfRange elf = {elfVaStart, elfVaEnd}; session->allElfs.push_back(elf); char output[bufferSize] = {0}; - + mockWddm->elfData = elfData; ze_device_thread_t thread; thread.slice = UINT32_MAX; thread.subslice = UINT32_MAX; @@ -1123,9 +1123,18 @@ TEST_F(DebugApiWindowsTest, WhenCallingReadMemoryForElfThenUnsupportedFeatureIsR zet_debug_memory_space_desc_t desc; desc.address = elfVaStart; desc.type = ZET_DEBUG_MEMORY_SPACE_TYPE_DEFAULT; + + mockWddm->escapeReturnStatus = DBGUMD_RETURN_INVALID_ARGS; auto retVal = session->readMemory(thread, &desc, bufferSize, output); + ASSERT_EQ(1u, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_READ_UMD_MEMORY]); + ASSERT_NE(ZE_RESULT_SUCCESS, retVal); + + mockWddm->escapeReturnStatus = DBGUMD_RETURN_ESCAPE_SUCCESS; + retVal = session->readMemory(thread, &desc, bufferSize, output); ASSERT_EQ(0u, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_READ_GFX_MEMORY]); - EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, retVal); + ASSERT_EQ(2u, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_READ_UMD_MEMORY]); + ASSERT_EQ(ZE_RESULT_SUCCESS, retVal); + EXPECT_EQ(memcmp(output, elfData, bufferSize), 0); desc.address = elfVaEnd - 1; retVal = session->readMemory(thread, &desc, bufferSize, output); diff --git a/shared/test/common/mocks/windows/mock_wddm_eudebug.h b/shared/test/common/mocks/windows/mock_wddm_eudebug.h index fb3986b7ef..2e5b680813 100644 --- a/shared/test/common/mocks/windows/mock_wddm_eudebug.h +++ b/shared/test/common/mocks/windows/mock_wddm_eudebug.h @@ -115,11 +115,19 @@ struct WddmEuDebugInterfaceMock : public WddmMock { acknowledgeEventPassedParam = pEscapeInfo->KmEuDbgL0EscapeInfo.AckEventParams; break; } + case DBGUMD_ACTION_READ_UMD_MEMORY: { + if (elfData != nullptr && escapeReturnStatus == DBGUMD_RETURN_ESCAPE_SUCCESS) { + memcpy(reinterpret_cast(pEscapeInfo->KmEuDbgL0EscapeInfo.ReadUmdMemoryParams.BufferPtr), elfData, pEscapeInfo->KmEuDbgL0EscapeInfo.ReadUmdMemoryParams.BufferSize); + } + pEscapeInfo->KmEuDbgL0EscapeInfo.EscapeReturnStatus = escapeReturnStatus; + break; + } } return ntStatus; }; + void *elfData = nullptr; uint32_t numEvents = 0; uint32_t curEvent = 0; struct {