mirror of
https://github.com/intel/compute-runtime.git
synced 2025-09-15 13:01:45 +08:00
L0 Debugger Windows - implement debugger attach/detach
Related-To: NEO-6718 Signed-off-by: Igor Venevtsev <igor.venevtsev@intel.com>
This commit is contained in:

committed by
Compute-Runtime-Automation

parent
b2021498e2
commit
8c165a6f41
@ -7,6 +7,7 @@
|
|||||||
set(L0_SRCS_DLL_WINDOWS
|
set(L0_SRCS_DLL_WINDOWS
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
|
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/debugger_l0_windows.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/debugger_l0_windows.cpp
|
||||||
|
${NEO_SOURCE_DIR}/level_zero/tools/source/debug/windows/debug_session_windows_helper.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set_property(GLOBAL PROPERTY L0_SRCS_DLL_WINDOWS ${L0_SRCS_DLL_WINDOWS})
|
set_property(GLOBAL PROPERTY L0_SRCS_DLL_WINDOWS ${L0_SRCS_DLL_WINDOWS})
|
||||||
|
@ -8,6 +8,7 @@ if(WIN32)
|
|||||||
target_sources(${L0_STATIC_LIB_NAME}
|
target_sources(${L0_STATIC_LIB_NAME}
|
||||||
PRIVATE
|
PRIVATE
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/debug_session.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/debug_session.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/debug_session.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
|
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
@ -5,14 +5,154 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "level_zero/tools/source/debug/debug_session.h"
|
#include "level_zero/tools/source/debug/windows/debug_session.h"
|
||||||
|
|
||||||
#include "level_zero/core/source/device/device.h"
|
|
||||||
|
|
||||||
namespace L0 {
|
namespace L0 {
|
||||||
|
|
||||||
|
DebugSession *createDebugSessionHelper(const zet_debug_config_t &config, Device *device, int debugFd);
|
||||||
|
|
||||||
DebugSession *DebugSession::create(const zet_debug_config_t &config, Device *device, ze_result_t &result) {
|
DebugSession *DebugSession::create(const zet_debug_config_t &config, Device *device, ze_result_t &result) {
|
||||||
result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
if (!device->getOsInterface().isDebugAttachAvailable()) {
|
||||||
return nullptr;
|
result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto debugSession = createDebugSessionHelper(config, device, 0);
|
||||||
|
result = debugSession->initialize();
|
||||||
|
if (result != ZE_RESULT_SUCCESS) {
|
||||||
|
debugSession->closeConnection();
|
||||||
|
delete debugSession;
|
||||||
|
debugSession = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return debugSession;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ze_result_t DebugSessionWindows::initialize() {
|
||||||
|
wddm = connectedDevice->getOsInterface().getDriverModel()->as<NEO::Wddm>();
|
||||||
|
UNRECOVERABLE_IF(wddm == nullptr);
|
||||||
|
|
||||||
|
KM_ESCAPE_INFO escapeInfo = {0};
|
||||||
|
escapeInfo.KmEuDbgL0EscapeInfo.EscapeActionType = DBGUMD_ACTION_ATTACH_DEBUGGER;
|
||||||
|
escapeInfo.KmEuDbgL0EscapeInfo.AttachDebuggerParams.hAdapter = wddm->getAdapter();
|
||||||
|
escapeInfo.KmEuDbgL0EscapeInfo.AttachDebuggerParams.ProcessId = processId;
|
||||||
|
|
||||||
|
auto status = runEscape(escapeInfo);
|
||||||
|
if (STATUS_SUCCESS != status) {
|
||||||
|
PRINT_DEBUGGER_ERROR_LOG("DBGUMD_ACTION_ATTACH_DEBUGGER: Failed - ProcessId: %d Status: %d EscapeReturnStatus: %d\n", processId, status, escapeInfo.KmEuDbgL0EscapeInfo.EscapeReturnStatus);
|
||||||
|
return DebugSessionWindows::translateEscapeReturnStatusToZeResult(escapeInfo.KmEuDbgL0EscapeInfo.EscapeReturnStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
debugHandle = escapeInfo.KmEuDbgL0EscapeInfo.AttachDebuggerParams.hDebugHandle;
|
||||||
|
PRINT_DEBUGGER_INFO_LOG("DBGUMD_ACTION_ATTACH_DEBUGGER: SUCCESS - ProcessId: %d DebugHandle: 0x%ullx\n", processId, debugHandle);
|
||||||
|
return ZE_RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DebugSessionWindows::closeConnection() {
|
||||||
|
if (debugHandle == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
KM_ESCAPE_INFO escapeInfo = {0};
|
||||||
|
escapeInfo.KmEuDbgL0EscapeInfo.EscapeActionType = DBGUMD_ACTION_DETACH_DEBUGGER;
|
||||||
|
escapeInfo.KmEuDbgL0EscapeInfo.DetachDebuggerParams.ProcessID = processId;
|
||||||
|
|
||||||
|
auto status = runEscape(escapeInfo);
|
||||||
|
if (STATUS_SUCCESS != status) {
|
||||||
|
PRINT_DEBUGGER_ERROR_LOG("DBGUMD_ACTION_DETACH_DEBUGGER: Failed - ProcessId: %d Status: %d\n", processId, status);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRINT_DEBUGGER_INFO_LOG("DBGUMD_ACTION_DETACH_DEBUGGER: SUCCESS\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS DebugSessionWindows::runEscape(KM_ESCAPE_INFO &escapeInfo) {
|
||||||
|
D3DKMT_ESCAPE escapeCommand = {0};
|
||||||
|
|
||||||
|
escapeInfo.Header.EscapeCode = GFX_ESCAPE_KMD;
|
||||||
|
escapeInfo.EscapeOperation = KM_ESCAPE_EUDBG_L0_DBGUMD_HANDLER;
|
||||||
|
escapeInfo.KmEuDbgL0EscapeInfo.hDebugHandle = debugHandle;
|
||||||
|
|
||||||
|
escapeCommand.Flags.HardwareAccess = 0;
|
||||||
|
escapeCommand.Flags.Reserved = 0;
|
||||||
|
escapeCommand.hAdapter = wddm->getAdapter();
|
||||||
|
escapeCommand.hContext = (D3DKMT_HANDLE)0;
|
||||||
|
escapeCommand.hDevice = wddm->getDeviceHandle();
|
||||||
|
escapeCommand.pPrivateDriverData = &escapeInfo;
|
||||||
|
escapeCommand.PrivateDriverDataSize = sizeof(escapeInfo);
|
||||||
|
escapeCommand.Type = D3DKMT_ESCAPE_DRIVERPRIVATE;
|
||||||
|
|
||||||
|
return wddm->escape(escapeCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
ze_result_t DebugSessionWindows::translateEscapeReturnStatusToZeResult(uint32_t escapeReturnStatus) {
|
||||||
|
switch (escapeReturnStatus) {
|
||||||
|
case KmHeadersWA::DBGUMD_RETURN_ESCAPE_SUCCESS:
|
||||||
|
return ZE_RESULT_SUCCESS;
|
||||||
|
case KmHeadersWA::DBGUMD_RETURN_DEBUGGER_ATTACH_DEVICE_BUSY:
|
||||||
|
case KmHeadersWA::DBGUMD_RETURN_READ_EVENT_TIMEOUT_EXPIRED:
|
||||||
|
return ZE_RESULT_ERROR_NOT_AVAILABLE;
|
||||||
|
case KmHeadersWA::DBGUMD_RETURN_INVALID_ARGS:
|
||||||
|
case KmHeadersWA::DBGUMD_RETURN_NOT_VALID_PROCESS:
|
||||||
|
return ZE_RESULT_ERROR_INVALID_ARGUMENT;
|
||||||
|
case KmHeadersWA::DBGUMD_RETURN_PERMISSION_DENIED:
|
||||||
|
return ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS;
|
||||||
|
case KmHeadersWA::DBGUMD_RETURN_EU_DEBUG_NOT_SUPPORTED:
|
||||||
|
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||||
|
default:
|
||||||
|
return ZE_RESULT_ERROR_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ze_result_t DebugSessionWindows::readEvent(uint64_t timeout, zet_debug_event_t *event) {
|
||||||
|
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ze_result_t DebugSessionWindows::readMemory(ze_device_thread_t thread, const zet_debug_memory_space_desc_t *desc, size_t size, void *buffer) {
|
||||||
|
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ze_result_t DebugSessionWindows::writeMemory(ze_device_thread_t thread, const zet_debug_memory_space_desc_t *desc, size_t size, const void *buffer) {
|
||||||
|
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ze_result_t DebugSessionWindows::acknowledgeEvent(const zet_debug_event_t *event) {
|
||||||
|
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ze_result_t DebugSessionWindows::resumeImp(std::vector<ze_device_thread_t> threads, uint32_t deviceIndex) {
|
||||||
|
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ze_result_t DebugSessionWindows::interruptImp(uint32_t deviceIndex) {
|
||||||
|
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ze_result_t DebugSessionWindows::readGpuMemory(uint64_t memoryHandle, char *output, size_t size, uint64_t gpuVa) {
|
||||||
|
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ze_result_t DebugSessionWindows::writeGpuMemory(uint64_t memoryHandle, const char *input, size_t size, uint64_t gpuVa) {
|
||||||
|
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugSessionWindows::enqueueApiEvent(zet_debug_event_t &debugEvent) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DebugSessionWindows::readSystemRoutineIdent(EuThread *thread, uint64_t vmHandle, SIP::sr_ident &srMagic) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DebugSessionWindows::readModuleDebugArea() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugSessionWindows::startAsyncThread() {
|
||||||
|
}
|
||||||
|
|
||||||
|
ze_result_t DebugSessionWindows::readSbaBuffer(EuThread::ThreadId, SbaTrackedAddresses &sbaBuffer) {
|
||||||
|
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace L0
|
} // namespace L0
|
||||||
|
73
level_zero/tools/source/debug/windows/debug_session.h
Normal file
73
level_zero/tools/source/debug/windows/debug_session.h
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2022 Intel Corporation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "shared/source/os_interface/windows/wddm/wddm.h"
|
||||||
|
|
||||||
|
#include "level_zero/core/source/device/device.h"
|
||||||
|
#include "level_zero/tools/source/debug/debug_session.h"
|
||||||
|
#include "level_zero/tools/source/debug/debug_session_imp.h"
|
||||||
|
|
||||||
|
#include "KmEscape.h"
|
||||||
|
|
||||||
|
namespace L0 {
|
||||||
|
|
||||||
|
namespace KmHeadersWA {
|
||||||
|
typedef enum __EUDBG_L0DBGUMD_ESCAPE_RETURN_TYPE {
|
||||||
|
DBGUMD_RETURN_ESCAPE_SUCCESS = 0, /* Default return type */
|
||||||
|
DBGUMD_RETURN_DEBUGGER_ATTACH_DEVICE_BUSY = 1,
|
||||||
|
DBGUMD_RETURN_READ_EVENT_TIMEOUT_EXPIRED = 2,
|
||||||
|
DBGUMD_RETURN_INVALID_ARGS = 3,
|
||||||
|
DBGUMD_RETURN_PERMISSION_DENIED = 4,
|
||||||
|
DBGUMD_RETURN_NOT_VALID_PROCESS = 5,
|
||||||
|
DBGUMD_RETURN_EU_DEBUG_NOT_SUPPORTED = 6,
|
||||||
|
DBGUMD_RETURN_KMD_DEBUG_ERROR = 7,
|
||||||
|
DBGUMD_RETURN_INVALID_SESSION_INFO = 8,
|
||||||
|
DBGUMD_RETURN_INVALID_EVENT_SEQ_NO = 9,
|
||||||
|
|
||||||
|
DBGUMD_RETURN_TYPE_MAX,
|
||||||
|
|
||||||
|
DBGUMD_RETURN_NOT_IMPLEMENTED = -1
|
||||||
|
} EUDBG_L0DBGUMD_ESCAPE_RETURN_TYPE;
|
||||||
|
} // namespace KmHeadersWA
|
||||||
|
|
||||||
|
struct DebugSessionWindows : DebugSessionImp {
|
||||||
|
DebugSessionWindows(const zet_debug_config_t &config, Device *device) : DebugSessionImp(config, device), processId(config.pid) {}
|
||||||
|
|
||||||
|
ze_result_t initialize() override;
|
||||||
|
bool closeConnection() override;
|
||||||
|
|
||||||
|
ze_result_t readEvent(uint64_t timeout, zet_debug_event_t *event) override;
|
||||||
|
ze_result_t readMemory(ze_device_thread_t thread, const zet_debug_memory_space_desc_t *desc, size_t size, void *buffer) override;
|
||||||
|
ze_result_t writeMemory(ze_device_thread_t thread, const zet_debug_memory_space_desc_t *desc, size_t size, const void *buffer) override;
|
||||||
|
ze_result_t acknowledgeEvent(const zet_debug_event_t *event) override;
|
||||||
|
|
||||||
|
static ze_result_t translateEscapeReturnStatusToZeResult(uint32_t escapeErrorStatus);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ze_result_t resumeImp(std::vector<ze_device_thread_t> threads, uint32_t deviceIndex) override;
|
||||||
|
ze_result_t interruptImp(uint32_t deviceIndex) override;
|
||||||
|
|
||||||
|
ze_result_t readGpuMemory(uint64_t memoryHandle, char *output, size_t size, uint64_t gpuVa) override;
|
||||||
|
ze_result_t writeGpuMemory(uint64_t memoryHandle, const char *input, size_t size, uint64_t gpuVa) override;
|
||||||
|
|
||||||
|
ze_result_t readSbaBuffer(EuThread::ThreadId, SbaTrackedAddresses &sbaBuffer) override;
|
||||||
|
|
||||||
|
void enqueueApiEvent(zet_debug_event_t &debugEvent) override;
|
||||||
|
bool readSystemRoutineIdent(EuThread *thread, uint64_t vmHandle, SIP::sr_ident &srMagic) override;
|
||||||
|
bool readModuleDebugArea() override;
|
||||||
|
void startAsyncThread() override;
|
||||||
|
|
||||||
|
NTSTATUS runEscape(KM_ESCAPE_INFO &escapeInfo);
|
||||||
|
|
||||||
|
NEO::Wddm *wddm = nullptr;
|
||||||
|
uint32_t processId = 0;
|
||||||
|
uint64_t debugHandle = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace L0
|
@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2022 Intel Corporation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "level_zero/tools/source/debug/windows/debug_session.h"
|
||||||
|
#include <level_zero/ze_api.h>
|
||||||
|
namespace L0 {
|
||||||
|
|
||||||
|
DebugSession *createDebugSessionHelper(const zet_debug_config_t &config, Device *device, int debugFd) {
|
||||||
|
return new DebugSessionWindows(config, device);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace L0
|
@ -5,47 +5,141 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "shared/test/common/mocks/windows/mock_wddm_eudebug.h"
|
||||||
#include "shared/test/common/test_macros/test.h"
|
#include "shared/test/common/test_macros/test.h"
|
||||||
|
|
||||||
#include "level_zero/core/test/unit_tests/fixtures/device_fixture.h"
|
#include "level_zero/core/test/unit_tests/fixtures/device_fixture.h"
|
||||||
|
#include "level_zero/tools/source/debug/windows/debug_session.h"
|
||||||
|
|
||||||
namespace L0 {
|
namespace L0 {
|
||||||
namespace ult {
|
namespace ult {
|
||||||
|
|
||||||
|
struct MockDebugSessionWindows : DebugSessionWindows {
|
||||||
|
using DebugSessionWindows::debugHandle;
|
||||||
|
using DebugSessionWindows::initialize;
|
||||||
|
using DebugSessionWindows::processId;
|
||||||
|
|
||||||
|
MockDebugSessionWindows(const zet_debug_config_t &config, L0::Device *device) : DebugSessionWindows(config, device) {}
|
||||||
|
|
||||||
|
ze_result_t initialize() override {
|
||||||
|
if (resultInitialize != ZE_RESULT_FORCE_UINT32) {
|
||||||
|
return resultInitialize;
|
||||||
|
}
|
||||||
|
return DebugSessionWindows::initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
ze_result_t resultInitialize = ZE_RESULT_FORCE_UINT32;
|
||||||
|
};
|
||||||
|
|
||||||
struct DebugApiWindowsFixture : public DeviceFixture {
|
struct DebugApiWindowsFixture : public DeviceFixture {
|
||||||
void SetUp() {
|
void SetUp() {
|
||||||
DeviceFixture::SetUp();
|
DeviceFixture::SetUp();
|
||||||
|
mockWddm = new WddmEuDebugInterfaceMock(*neoDevice->executionEnvironment->rootDeviceEnvironments[0]);
|
||||||
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(new NEO::OSInterface);
|
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(new NEO::OSInterface);
|
||||||
|
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::unique_ptr<DriverModel>(mockWddm));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TearDown() {
|
void TearDown() {
|
||||||
DeviceFixture::TearDown();
|
DeviceFixture::TearDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WddmEuDebugInterfaceMock *mockWddm = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
using DebugApiWinTest = Test<DebugApiWindowsFixture>;
|
using DebugApiWindowsTest = Test<DebugApiWindowsFixture>;
|
||||||
|
|
||||||
TEST_F(DebugApiWinTest, givenDeviceWhenGettingDebugPropertiesThanNoFlagIsSet) {
|
TEST_F(DebugApiWindowsTest, givenDebugAttachIsNotAvailableWhenGetDebugPropertiesCalledThenNoFlagIsReturned) {
|
||||||
zet_device_debug_properties_t debugProperties = {};
|
zet_device_debug_properties_t debugProperties = {};
|
||||||
debugProperties.flags = ZET_DEVICE_DEBUG_PROPERTY_FLAG_FORCE_UINT32;
|
debugProperties.flags = ZET_DEVICE_DEBUG_PROPERTY_FLAG_FORCE_UINT32;
|
||||||
|
|
||||||
|
mockWddm->debugAttachAvailable = false;
|
||||||
auto result = zetDeviceGetDebugProperties(device->toHandle(), &debugProperties);
|
auto result = zetDeviceGetDebugProperties(device->toHandle(), &debugProperties);
|
||||||
|
|
||||||
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
|
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
|
||||||
EXPECT_EQ(0u, debugProperties.flags);
|
EXPECT_EQ(0u, debugProperties.flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(DebugApiWinTest, givenDeviceWhenCallingDebugAttachThenErrorIsReturned) {
|
using isDebugSupportedProduct = IsWithinProducts<IGFX_DG1, IGFX_PVC>;
|
||||||
|
HWTEST2_F(DebugApiWindowsTest, givenDebugAttachAvailableWhenGetDebugPropertiesCalledThenCorrectFlagIsReturned, isDebugSupportedProduct) {
|
||||||
|
zet_device_debug_properties_t debugProperties = {};
|
||||||
|
debugProperties.flags = ZET_DEVICE_DEBUG_PROPERTY_FLAG_FORCE_UINT32;
|
||||||
|
|
||||||
|
auto result = zetDeviceGetDebugProperties(device->toHandle(), &debugProperties);
|
||||||
|
|
||||||
|
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
|
||||||
|
EXPECT_EQ(ZET_DEVICE_DEBUG_PROPERTY_FLAG_ATTACH, debugProperties.flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DebugApiWindowsTest, givenDebugAttachIsNotAvailableWhenDebugSessionCreatedThenNullptrAndResultUnsupportedFeatureAreReturned) {
|
||||||
zet_debug_config_t config = {};
|
zet_debug_config_t config = {};
|
||||||
config.pid = 0x1234;
|
config.pid = 0x1234;
|
||||||
zet_debug_session_handle_t debugSession = nullptr;
|
zet_debug_session_handle_t debugSession = nullptr;
|
||||||
|
|
||||||
|
mockWddm->debugAttachAvailable = false;
|
||||||
auto result = zetDebugAttach(device->toHandle(), &config, &debugSession);
|
auto result = zetDebugAttach(device->toHandle(), &config, &debugSession);
|
||||||
|
|
||||||
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, result);
|
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, result);
|
||||||
EXPECT_EQ(nullptr, debugSession);
|
EXPECT_EQ(nullptr, debugSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(DebugApiWindowsTest, givenDebugAttachAvailableAndInitializationFailedWhenDebugSessionCreatedThenNullptrAndErrorStatusAreReturned) {
|
||||||
|
zet_debug_config_t config = {};
|
||||||
|
config.pid = 0x0; // debugSession->initialize() will fail
|
||||||
|
|
||||||
|
zet_debug_session_handle_t debugSession = nullptr;
|
||||||
|
auto result = zetDebugAttach(device->toHandle(), &config, &debugSession);
|
||||||
|
|
||||||
|
EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, result);
|
||||||
|
EXPECT_EQ(nullptr, debugSession);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DebugApiWindowsTest, givenDebugSessionInitializeCalledThenAttachDebuggerEscapeIsInvoked) {
|
||||||
|
zet_debug_config_t config = {};
|
||||||
|
config.pid = 0x1234;
|
||||||
|
|
||||||
|
auto session = std::make_unique<MockDebugSessionWindows>(config, device);
|
||||||
|
auto result = session->initialize();
|
||||||
|
|
||||||
|
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
|
||||||
|
EXPECT_EQ(1, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_ATTACH_DEBUGGER]);
|
||||||
|
EXPECT_EQ(session->processId, config.pid);
|
||||||
|
EXPECT_EQ(session->debugHandle, mockWddm->debugHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DebugApiWindowsTest, givenDebugSessionCloseConnectionCalledWithoutInitializationThenFalseIsReturned) {
|
||||||
|
zet_debug_config_t config = {};
|
||||||
|
config.pid = 0x1234;
|
||||||
|
|
||||||
|
auto session = std::make_unique<MockDebugSessionWindows>(config, device);
|
||||||
|
EXPECT_FALSE(session->closeConnection());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DebugApiWindowsTest, givenDebugSessionInitializedAndCloseConnectionCalledThenDebuggerDetachEscapeIsInvoked) {
|
||||||
|
zet_debug_config_t config = {};
|
||||||
|
config.pid = 0x1234;
|
||||||
|
|
||||||
|
auto session = std::make_unique<MockDebugSessionWindows>(config, device);
|
||||||
|
auto result = session->initialize();
|
||||||
|
|
||||||
|
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
|
||||||
|
EXPECT_EQ(1, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_ATTACH_DEBUGGER]);
|
||||||
|
EXPECT_EQ(session->processId, config.pid);
|
||||||
|
EXPECT_EQ(session->debugHandle, mockWddm->debugHandle);
|
||||||
|
|
||||||
|
EXPECT_TRUE(session->closeConnection());
|
||||||
|
EXPECT_EQ(1, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_DETACH_DEBUGGER]);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(DebugSessionWindowsTest, whenTranslateEscapeErrorStatusCalledThenCorrectZeResultReturned) {
|
||||||
|
EXPECT_EQ(ZE_RESULT_SUCCESS, DebugSessionWindows::translateEscapeReturnStatusToZeResult(KmHeadersWA::DBGUMD_RETURN_ESCAPE_SUCCESS));
|
||||||
|
EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, DebugSessionWindows::translateEscapeReturnStatusToZeResult(KmHeadersWA::DBGUMD_RETURN_DEBUGGER_ATTACH_DEVICE_BUSY));
|
||||||
|
EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, DebugSessionWindows::translateEscapeReturnStatusToZeResult(KmHeadersWA::DBGUMD_RETURN_READ_EVENT_TIMEOUT_EXPIRED));
|
||||||
|
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, DebugSessionWindows::translateEscapeReturnStatusToZeResult(KmHeadersWA::DBGUMD_RETURN_INVALID_ARGS));
|
||||||
|
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, DebugSessionWindows::translateEscapeReturnStatusToZeResult(KmHeadersWA::DBGUMD_RETURN_NOT_VALID_PROCESS));
|
||||||
|
EXPECT_EQ(ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS, DebugSessionWindows::translateEscapeReturnStatusToZeResult(KmHeadersWA::DBGUMD_RETURN_PERMISSION_DENIED));
|
||||||
|
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, DebugSessionWindows::translateEscapeReturnStatusToZeResult(KmHeadersWA::DBGUMD_RETURN_EU_DEBUG_NOT_SUPPORTED));
|
||||||
|
EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, DebugSessionWindows::translateEscapeReturnStatusToZeResult(KmHeadersWA::DBGUMD_RETURN_TYPE_MAX));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ult
|
} // namespace ult
|
||||||
} // namespace L0
|
} // namespace L0
|
||||||
|
@ -101,7 +101,7 @@ class Wddm : public DriverModel {
|
|||||||
MOCKABLE_VIRTUAL bool submit(uint64_t commandBuffer, size_t size, void *commandHeader, WddmSubmitArguments &submitArguments);
|
MOCKABLE_VIRTUAL bool submit(uint64_t commandBuffer, size_t size, void *commandHeader, WddmSubmitArguments &submitArguments);
|
||||||
MOCKABLE_VIRTUAL bool waitFromCpu(uint64_t lastFenceValue, const MonitoredFence &monitoredFence);
|
MOCKABLE_VIRTUAL bool waitFromCpu(uint64_t lastFenceValue, const MonitoredFence &monitoredFence);
|
||||||
|
|
||||||
NTSTATUS escape(D3DKMT_ESCAPE &escapeCommand);
|
MOCKABLE_VIRTUAL NTSTATUS escape(D3DKMT_ESCAPE &escapeCommand);
|
||||||
MOCKABLE_VIRTUAL VOID *registerTrimCallback(PFND3DKMT_TRIMNOTIFICATIONCALLBACK callback, WddmResidencyController &residencyController);
|
MOCKABLE_VIRTUAL VOID *registerTrimCallback(PFND3DKMT_TRIMNOTIFICATIONCALLBACK callback, WddmResidencyController &residencyController);
|
||||||
void unregisterTrimCallback(PFND3DKMT_TRIMNOTIFICATIONCALLBACK callback, VOID *trimCallbackHandle);
|
void unregisterTrimCallback(PFND3DKMT_TRIMNOTIFICATIONCALLBACK callback, VOID *trimCallbackHandle);
|
||||||
MOCKABLE_VIRTUAL void releaseReservedAddress(void *reservedAddress);
|
MOCKABLE_VIRTUAL void releaseReservedAddress(void *reservedAddress);
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
#include "shared/test/common/mocks/mock_wddm.h"
|
#include "shared/test/common/mocks/mock_wddm.h"
|
||||||
|
|
||||||
|
#include "KmEscape.h"
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace NEO {
|
namespace NEO {
|
||||||
@ -15,7 +17,33 @@ struct WddmEuDebugInterfaceMock : public WddmMock {
|
|||||||
WddmEuDebugInterfaceMock(RootDeviceEnvironment &rootDeviceEnvironment) : WddmMock(rootDeviceEnvironment) {}
|
WddmEuDebugInterfaceMock(RootDeviceEnvironment &rootDeviceEnvironment) : WddmMock(rootDeviceEnvironment) {}
|
||||||
|
|
||||||
bool isDebugAttachAvailable() override {
|
bool isDebugAttachAvailable() override {
|
||||||
return true;
|
return debugAttachAvailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS escape(D3DKMT_ESCAPE &escapeCommand) override {
|
||||||
|
auto pEscapeInfo = static_cast<KM_ESCAPE_INFO *>(escapeCommand.pPrivateDriverData);
|
||||||
|
if (pEscapeInfo->EscapeOperation != KM_ESCAPE_EUDBG_L0_DBGUMD_HANDLER) {
|
||||||
|
return escapeStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
++dbgUmdEscapeActionCalled[pEscapeInfo->KmEuDbgL0EscapeInfo.EscapeActionType];
|
||||||
|
|
||||||
|
switch (pEscapeInfo->KmEuDbgL0EscapeInfo.EscapeActionType) {
|
||||||
|
case DBGUMD_ACTION_ATTACH_DEBUGGER: {
|
||||||
|
pEscapeInfo->KmEuDbgL0EscapeInfo.EscapeReturnStatus = DBGUMD_ACTION_ESCAPE_SUCCESS;
|
||||||
|
pEscapeInfo->KmEuDbgL0EscapeInfo.AttachDebuggerParams.hDebugHandle = debugHandle;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DBGUMD_ACTION_DETACH_DEBUGGER:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return escapeStatus;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool debugAttachAvailable = true;
|
||||||
|
NTSTATUS escapeStatus = STATUS_SUCCESS;
|
||||||
|
uint64_t debugHandle = 0x0DEB0DEB;
|
||||||
|
uint32_t dbgUmdEscapeActionCalled[DBGUMD_ACTION_MAX] = {0};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace NEO
|
} // namespace NEO
|
@ -75,6 +75,11 @@ TEST_F(WddmTests, whenCheckedIfResourcesCleanupCanBeSkippedThenReturnsFalse) {
|
|||||||
EXPECT_TRUE(wddm->isDriverAvaliable());
|
EXPECT_TRUE(wddm->isDriverAvaliable());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(WddmTests, whenCheckedIfDebugAttachAvailableThenReturnsFalse) {
|
||||||
|
init();
|
||||||
|
EXPECT_FALSE(wddm->isDebugAttachAvailable());
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(WddmTests, whenCreatingContextWithPowerHintSuccessIsReturned) {
|
TEST_F(WddmTests, whenCreatingContextWithPowerHintSuccessIsReturned) {
|
||||||
init();
|
init();
|
||||||
auto newContext = osContext.get();
|
auto newContext = osContext.get();
|
||||||
|
Reference in New Issue
Block a user