mirror of
https://github.com/intel/compute-runtime.git
synced 2025-12-24 12:23:05 +08:00
Debugger L0 Win: implement module destroy event
Related-To: NEO-6723 Signed-off-by: Igor Venevtsev <igor.venevtsev@intel.com>
This commit is contained in:
committed by
Compute-Runtime-Automation
parent
f17b46bc22
commit
4cb9ad5d55
@@ -569,6 +569,17 @@ bool ModuleImp::initialize(const ze_module_desc_t *desc, NEO::Device *neoDevice)
|
||||
kernelImmDatas.push_back(std::move(kernelImmData));
|
||||
}
|
||||
|
||||
auto refBin = ArrayRef<const uint8_t>::fromAny(translationUnit->unpackedDeviceBinary.get(), translationUnit->unpackedDeviceBinarySize);
|
||||
if (NEO::isDeviceBinaryFormat<NEO::DeviceBinaryFormat::Zebin>(refBin)) {
|
||||
isZebinBinary = true;
|
||||
}
|
||||
|
||||
StackVec<NEO::GraphicsAllocation *, 32> moduleAllocs = getModuleAllocations();
|
||||
if (!moduleAllocs.empty()) {
|
||||
auto minGpuAddressAlloc = std::min_element(moduleAllocs.begin(), moduleAllocs.end(), [](const auto &alloc1, const auto &alloc2) { return alloc1->getGpuAddress() < alloc2->getGpuAddress(); });
|
||||
moduleLoadAddress = (*minGpuAddressAlloc)->getGpuAddress();
|
||||
}
|
||||
|
||||
registerElfInDebuggerL0();
|
||||
this->maxGroupSize = static_cast<uint32_t>(this->translationUnit->device->getNEODevice()->getDeviceInfo().maxWorkGroupSize);
|
||||
|
||||
@@ -608,7 +619,7 @@ bool ModuleImp::initialize(const ze_module_desc_t *desc, NEO::Device *neoDevice)
|
||||
}
|
||||
|
||||
void ModuleImp::createDebugZebin() {
|
||||
auto refBin = ArrayRef<const uint8_t>(reinterpret_cast<const uint8_t *>(translationUnit->unpackedDeviceBinary.get()), translationUnit->unpackedDeviceBinarySize);
|
||||
auto refBin = ArrayRef<const uint8_t>::fromAny(translationUnit->unpackedDeviceBinary.get(), translationUnit->unpackedDeviceBinarySize);
|
||||
auto segments = getZebinSegments();
|
||||
auto debugZebin = NEO::Debug::createDebugZebin(refBin, segments);
|
||||
|
||||
@@ -619,8 +630,7 @@ void ModuleImp::createDebugZebin() {
|
||||
}
|
||||
|
||||
void ModuleImp::passDebugData() {
|
||||
auto refBin = ArrayRef<const uint8_t>(reinterpret_cast<const uint8_t *>(translationUnit->unpackedDeviceBinary.get()), translationUnit->unpackedDeviceBinarySize);
|
||||
if (NEO::isDeviceBinaryFormat<NEO::DeviceBinaryFormat::Zebin>(refBin)) {
|
||||
if (isZebinBinary) {
|
||||
createDebugZebin();
|
||||
if (device->getSourceLevelDebugger()) {
|
||||
NEO::DebugData debugData; // pass debug zebin in vIsa field
|
||||
@@ -757,8 +767,8 @@ ze_result_t ModuleImp::getDebugInfo(size_t *pDebugDataSize, uint8_t *pDebugData)
|
||||
if (translationUnit == nullptr) {
|
||||
return ZE_RESULT_ERROR_UNINITIALIZED;
|
||||
}
|
||||
auto refBin = ArrayRef<const uint8_t>(reinterpret_cast<const uint8_t *>(translationUnit->unpackedDeviceBinary.get()), translationUnit->unpackedDeviceBinarySize);
|
||||
if (nullptr == translationUnit->debugData.get() && NEO::isDeviceBinaryFormat<NEO::DeviceBinaryFormat::Zebin>(refBin)) {
|
||||
|
||||
if (nullptr == translationUnit->debugData.get() && isZebinBinary) {
|
||||
createDebugZebin();
|
||||
}
|
||||
if (pDebugData != nullptr) {
|
||||
@@ -1173,14 +1183,19 @@ bool ModuleImp::populateHostGlobalSymbolsMap(std::unordered_map<std::string, std
|
||||
}
|
||||
|
||||
ze_result_t ModuleImp::destroy() {
|
||||
notifyModuleDestroy();
|
||||
|
||||
auto tempHandle = debugModuleHandle;
|
||||
auto tempDevice = device;
|
||||
delete this;
|
||||
|
||||
if (tempDevice->getL0Debugger() && tempHandle != 0) {
|
||||
tempDevice->getL0Debugger()->removeZebinModule(tempHandle);
|
||||
}
|
||||
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
void ModuleImp::registerElfInDebuggerL0() {
|
||||
auto debuggerL0 = device->getL0Debugger();
|
||||
|
||||
@@ -1188,8 +1203,7 @@ void ModuleImp::registerElfInDebuggerL0() {
|
||||
return;
|
||||
}
|
||||
|
||||
auto refBin = ArrayRef<const uint8_t>(reinterpret_cast<const uint8_t *>(translationUnit->unpackedDeviceBinary.get()), translationUnit->unpackedDeviceBinarySize);
|
||||
if (NEO::isDeviceBinaryFormat<NEO::DeviceBinaryFormat::Zebin>(refBin)) {
|
||||
if (isZebinBinary) {
|
||||
size_t debugDataSize = 0;
|
||||
getDebugInfo(&debugDataSize, nullptr);
|
||||
|
||||
@@ -1238,19 +1252,14 @@ void ModuleImp::notifyModuleCreate() {
|
||||
return;
|
||||
}
|
||||
|
||||
auto refBin = ArrayRef<const uint8_t>(reinterpret_cast<const uint8_t *>(translationUnit->unpackedDeviceBinary.get()), translationUnit->unpackedDeviceBinarySize);
|
||||
if (NEO::isDeviceBinaryFormat<NEO::DeviceBinaryFormat::Zebin>(refBin)) {
|
||||
if (isZebinBinary) {
|
||||
size_t debugDataSize = 0;
|
||||
getDebugInfo(&debugDataSize, nullptr);
|
||||
|
||||
NEO::DebugData debugData; // pass debug zebin in vIsa field
|
||||
debugData.vIsa = reinterpret_cast<const char *>(translationUnit->debugData.get());
|
||||
debugData.vIsaSize = static_cast<uint32_t>(translationUnit->debugDataSize);
|
||||
|
||||
StackVec<NEO::GraphicsAllocation *, 32> segmentAllocs = getModuleAllocations();
|
||||
|
||||
auto minAddressGpuAlloc = std::min_element(segmentAllocs.begin(), segmentAllocs.end(), [](const auto &alloc1, const auto &alloc2) { return alloc1->getGpuAddress() < alloc2->getGpuAddress(); });
|
||||
debuggerL0->notifyModuleCreate(const_cast<char *>(debugData.vIsa), debugData.vIsaSize, (*minAddressGpuAlloc)->getGpuAddress());
|
||||
debuggerL0->notifyModuleCreate(const_cast<char *>(debugData.vIsa), debugData.vIsaSize, moduleLoadAddress);
|
||||
} else {
|
||||
for (auto &kernImmData : kernelImmDatas) {
|
||||
if (kernImmData->getKernelInfo()->kernelDescriptor.external.debugData.get()) {
|
||||
@@ -1271,6 +1280,24 @@ void ModuleImp::notifyModuleCreate() {
|
||||
}
|
||||
}
|
||||
|
||||
void ModuleImp::notifyModuleDestroy() {
|
||||
auto debuggerL0 = device->getL0Debugger();
|
||||
|
||||
if (!debuggerL0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isZebinBinary) {
|
||||
debuggerL0->notifyModuleDestroy(moduleLoadAddress);
|
||||
} else {
|
||||
for (auto &kernImmData : kernelImmDatas) {
|
||||
if (kernImmData->getKernelInfo()->kernelDescriptor.external.debugData.get()) {
|
||||
debuggerL0->notifyModuleDestroy(kernImmData->getIsaGraphicsAllocation()->getGpuAddress());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StackVec<NEO::GraphicsAllocation *, 32> ModuleImp::getModuleAllocations() {
|
||||
StackVec<NEO::GraphicsAllocation *, 32> allocs;
|
||||
for (auto &kernImmData : kernelImmDatas) {
|
||||
|
||||
@@ -142,6 +142,7 @@ struct ModuleImp : public Module {
|
||||
void createDebugZebin();
|
||||
void registerElfInDebuggerL0();
|
||||
void notifyModuleCreate();
|
||||
void notifyModuleDestroy();
|
||||
bool populateHostGlobalSymbolsMap(std::unordered_map<std::string, std::string> &devToHostNameMapping);
|
||||
StackVec<NEO::GraphicsAllocation *, 32> getModuleAllocations();
|
||||
|
||||
@@ -164,11 +165,13 @@ struct ModuleImp : public Module {
|
||||
bool debugEnabled = false;
|
||||
bool isFullyLinked = false;
|
||||
bool allocatePrivateMemoryPerDispatch = true;
|
||||
bool isZebinBinary = false;
|
||||
ModuleType type;
|
||||
NEO::Linker::UnresolvedExternals unresolvedExternalsInfo{};
|
||||
std::set<NEO::GraphicsAllocation *> importedSymbolAllocations{};
|
||||
uint32_t debugModuleHandle = 0;
|
||||
uint32_t profileFlags = 0;
|
||||
uint64_t moduleLoadAddress = std::numeric_limits<uint64_t>::max();
|
||||
|
||||
NEO::Linker::PatchableSegments isaSegmentsForPatching;
|
||||
std::vector<std::vector<char>> patchedIsaTempStorage;
|
||||
|
||||
@@ -340,10 +340,13 @@ struct ModuleWithZebinFixture : public DeviceFixture {
|
||||
struct MockModuleWithZebin : public L0::ModuleImp {
|
||||
using ModuleImp::getDebugInfo;
|
||||
using ModuleImp::getZebinSegments;
|
||||
using ModuleImp::isZebinBinary;
|
||||
using ModuleImp::kernelImmDatas;
|
||||
using ModuleImp::passDebugData;
|
||||
using ModuleImp::translationUnit;
|
||||
MockModuleWithZebin(L0::Device *device) : ModuleImp(device, nullptr, ModuleType::User) {}
|
||||
MockModuleWithZebin(L0::Device *device) : ModuleImp(device, nullptr, ModuleType::User) {
|
||||
isZebinBinary = true;
|
||||
}
|
||||
|
||||
void addSegments() {
|
||||
kernelImmDatas.push_back(std::make_unique<MockImmutableData>(device));
|
||||
|
||||
@@ -652,6 +652,89 @@ HWTEST_F(ModuleWithZebinAndL0DebuggerTest, GivenZebinWhenModuleIsInitializedAndD
|
||||
moduleMock.release();
|
||||
|
||||
EXPECT_EQ(6u, getMockDebuggerL0Hw<FamilyType>()->removedZebinModuleHandle);
|
||||
EXPECT_EQ(1u, getMockDebuggerL0Hw<FamilyType>()->notifyModuleDestroyCount);
|
||||
}
|
||||
|
||||
HWTEST_F(ModuleWithDebuggerL0Test, GivenNonZebinBinaryWhenDestroyModuleThenModuleDestroyNotified) {
|
||||
NEO::MockCompilerEnableGuard mock(true);
|
||||
auto cip = std::make_unique<NEO::MockCompilerInterfaceCaptureBuildOptions>();
|
||||
neoDevice->getExecutionEnvironment()->rootDeviceEnvironments[device->getRootDeviceIndex()]->compilerInterface = std::move(cip);
|
||||
|
||||
uint8_t binary[10] = {0};
|
||||
ze_module_desc_t moduleDesc = {};
|
||||
moduleDesc.format = ZE_MODULE_FORMAT_IL_SPIRV;
|
||||
moduleDesc.pInputModule = binary;
|
||||
moduleDesc.inputSize = 10;
|
||||
ModuleBuildLog *moduleBuildLog = nullptr;
|
||||
|
||||
std::unique_ptr<MockModule> moduleMock = std::make_unique<MockModule>(device, moduleBuildLog, ModuleType::User);
|
||||
moduleMock->translationUnit = std::make_unique<MockModuleTranslationUnit>(device);
|
||||
|
||||
uint32_t kernelHeap = 0;
|
||||
auto kernelInfo = new KernelInfo();
|
||||
kernelInfo->heapInfo.KernelHeapSize = 1;
|
||||
kernelInfo->heapInfo.pKernelHeap = &kernelHeap;
|
||||
|
||||
Mock<::L0::Kernel> kernelMock;
|
||||
kernelMock.module = moduleMock.get();
|
||||
kernelMock.immutableData.kernelInfo = kernelInfo;
|
||||
kernelInfo->kernelDescriptor.payloadMappings.implicitArgs.systemThreadSurfaceAddress.bindful = 0;
|
||||
|
||||
moduleMock->kernelImmData = &kernelMock.immutableData;
|
||||
moduleMock->translationUnit->programInfo.kernelInfos.push_back(kernelInfo);
|
||||
|
||||
kernelInfo->kernelDescriptor.external.debugData = std::make_unique<NEO::DebugData>();
|
||||
|
||||
std::vector<uint8_t> data;
|
||||
data.resize(4);
|
||||
NEO::Elf::ElfEncoder<> elfEncoder;
|
||||
elfEncoder.getElfFileHeader().type = NEO::Elf::SHT_PROGBITS;
|
||||
elfEncoder.appendSection(NEO::Elf::SHT_PROGBITS, NEO::Elf::SectionsNamesZebin::textPrefix, data);
|
||||
auto elfBinary = elfEncoder.encode();
|
||||
|
||||
kernelInfo->kernelDescriptor.external.debugData->vIsaSize = static_cast<uint32_t>(elfBinary.size());
|
||||
kernelInfo->kernelDescriptor.external.debugData->vIsa = reinterpret_cast<char *>(elfBinary.data());
|
||||
kernelInfo->kernelDescriptor.external.debugData->genIsa = nullptr;
|
||||
kernelInfo->kernelDescriptor.external.debugData->genIsaSize = 0;
|
||||
|
||||
EXPECT_TRUE(moduleMock->initialize(&moduleDesc, neoDevice));
|
||||
moduleMock->destroy();
|
||||
moduleMock.release();
|
||||
EXPECT_EQ(1u, getMockDebuggerL0Hw<FamilyType>()->notifyModuleDestroyCount);
|
||||
}
|
||||
|
||||
HWTEST_F(ModuleWithDebuggerL0Test, GivenNoDebugDataWhenDestroyingModuleThenDoNotNotifyModuleDestroy) {
|
||||
NEO::MockCompilerEnableGuard mock(true);
|
||||
auto cip = std::make_unique<NEO::MockCompilerInterfaceCaptureBuildOptions>();
|
||||
neoDevice->getExecutionEnvironment()->rootDeviceEnvironments[device->getRootDeviceIndex()]->compilerInterface = std::move(cip);
|
||||
|
||||
uint8_t binary[10] = {0};
|
||||
ze_module_desc_t moduleDesc = {};
|
||||
moduleDesc.format = ZE_MODULE_FORMAT_IL_SPIRV;
|
||||
moduleDesc.pInputModule = binary;
|
||||
moduleDesc.inputSize = 10;
|
||||
ModuleBuildLog *moduleBuildLog = nullptr;
|
||||
|
||||
std::unique_ptr<MockModule> moduleMock = std::make_unique<MockModule>(device, moduleBuildLog, ModuleType::User);
|
||||
moduleMock->translationUnit = std::make_unique<MockModuleTranslationUnit>(device);
|
||||
|
||||
uint32_t kernelHeap = 0;
|
||||
auto kernelInfo = new KernelInfo();
|
||||
kernelInfo->heapInfo.KernelHeapSize = 1;
|
||||
kernelInfo->heapInfo.pKernelHeap = &kernelHeap;
|
||||
|
||||
Mock<::L0::Kernel> kernelMock;
|
||||
kernelMock.module = moduleMock.get();
|
||||
kernelMock.immutableData.kernelInfo = kernelInfo;
|
||||
kernelInfo->kernelDescriptor.payloadMappings.implicitArgs.systemThreadSurfaceAddress.bindful = 0;
|
||||
|
||||
moduleMock->kernelImmData = &kernelMock.immutableData;
|
||||
moduleMock->translationUnit->programInfo.kernelInfos.push_back(kernelInfo);
|
||||
|
||||
EXPECT_TRUE(moduleMock->initialize(&moduleDesc, neoDevice));
|
||||
moduleMock->destroy();
|
||||
moduleMock.release();
|
||||
EXPECT_EQ(0u, getMockDebuggerL0Hw<FamilyType>()->notifyModuleDestroyCount);
|
||||
}
|
||||
|
||||
HWTEST_F(ModuleWithZebinAndL0DebuggerTest, GivenModuleDebugHandleZeroWhenInitializingAndDestoryingModuleThenHandleIsNotPassedToDebugger) {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "shared/test/common/mocks/windows/mock_wddm_eudebug.h"
|
||||
#include "shared/test/common/os_interface/windows/mock_wddm_memory_manager.h"
|
||||
#include "shared/test/common/test_macros/hw_test.h"
|
||||
#include "shared/test/unit_test/helpers/gtest_helpers.h"
|
||||
|
||||
#include "level_zero/core/source/device/device.h"
|
||||
#include "level_zero/core/test/unit_tests/mocks/mock_cmdqueue.h"
|
||||
@@ -108,7 +109,7 @@ HWTEST_F(L0DebuggerWindowsTest, givenDebuggingEnabledAndCommandQueuesAreCreatedA
|
||||
TEST_F(L0DebuggerWindowsTest, givenAllocateGraphicsMemoryWhenAllocationRegistrationIsRequiredThenAllocationIsRegistered) {
|
||||
auto memoryManager = executionEnvironment->memoryManager.get();
|
||||
|
||||
EXPECT_GE(wddm->registerAllocationTypeCalled, 3u); // At least 1xSBA + 1xMODULE_DEBUG + 1xSTATE_SAVE_AREA during DebuggerL0 init
|
||||
EXPECT_LE(3u, wddm->registerAllocationTypeCalled); // At least 1xSBA + 1xMODULE_DEBUG + 1xSTATE_SAVE_AREA during DebuggerL0 init
|
||||
uint32_t registerAllocationTypeCalled = wddm->registerAllocationTypeCalled;
|
||||
for (auto allocationType : {AllocationType::DEBUG_CONTEXT_SAVE_AREA,
|
||||
AllocationType::DEBUG_SBA_TRACKING_BUFFER,
|
||||
@@ -129,7 +130,7 @@ TEST_F(L0DebuggerWindowsTest, givenAllocateGraphicsMemoryWhenAllocationRegistrat
|
||||
TEST_F(L0DebuggerWindowsTest, givenAllocateGraphicsMemoryWhenAllocationRegistrationIsNotRequiredThenAllocationIsNotRegistered) {
|
||||
auto memoryManager = executionEnvironment->memoryManager.get();
|
||||
|
||||
EXPECT_GE(wddm->registerAllocationTypeCalled, 3u); // At least 1xSBA + 1xMODULE_DEBUG + 1xSTATE_SAVE_AREA during DebuggerL0 init
|
||||
EXPECT_LE(3u, wddm->registerAllocationTypeCalled); // At least 1xSBA + 1xMODULE_DEBUG + 1xSTATE_SAVE_AREA during DebuggerL0 init
|
||||
uint32_t registerAllocationTypeCalled = wddm->registerAllocationTypeCalled;
|
||||
auto wddmAlloc = static_cast<WddmAllocation *>(memoryManager->allocateGraphicsMemoryWithProperties(MockAllocationProperties{0u, MemoryConstants::pageSize, AllocationType::BUFFER}));
|
||||
EXPECT_EQ(registerAllocationTypeCalled, wddm->registerAllocationTypeCalled);
|
||||
@@ -140,34 +141,58 @@ TEST_F(L0DebuggerWindowsTest, givenDebuggerL0NotifyModuleCreateCalledAndCreateDe
|
||||
wddm->createDebugDataPassedParam.ntStatus = STATUS_UNSUCCESSFUL;
|
||||
auto debugger = static_cast<DebuggerL0 *>(neoDevice->getDebugger());
|
||||
debugger->notifyModuleCreate((void *)0x12345678, 0x1000, 0x80000000);
|
||||
EXPECT_EQ(wddm->createDebugDataCalled, 1u);
|
||||
EXPECT_EQ(wddm->createDebugDataPassedParam.param.hElfAddressPtr, 0xDEADDEADu);
|
||||
EXPECT_EQ(wddm->moduleCreateNotifyCalled, 0);
|
||||
EXPECT_EQ(1u, wddm->createDebugDataCalled);
|
||||
EXPECT_EQ(0xDEADDEADu, wddm->createDebugDataPassedParam.param.hElfAddressPtr);
|
||||
EXPECT_EQ(0, wddm->moduleCreateNotifyCalled);
|
||||
}
|
||||
|
||||
TEST_F(L0DebuggerWindowsTest, givenDebuggerL0NotifyModuleCreateCalledAndModuleCreateNotifyEscapeIsFailedThenModuleIsNotRegistered) {
|
||||
wddm->moduleCreateNotificationPassedParam.ntStatus = STATUS_UNSUCCESSFUL;
|
||||
auto debugger = static_cast<DebuggerL0 *>(neoDevice->getDebugger());
|
||||
debugger->notifyModuleCreate((void *)0x12345678, 0x1000, 0x80000000);
|
||||
EXPECT_EQ(wddm->createDebugDataCalled, 1u);
|
||||
EXPECT_EQ(wddm->createDebugDataPassedParam.param.hElfAddressPtr, 0x12345678u);
|
||||
EXPECT_EQ(wddm->moduleCreateNotifyCalled, 1u);
|
||||
EXPECT_EQ(wddm->moduleCreateNotificationPassedParam.param.hElfAddressPtr, 0xDEADDEADu);
|
||||
EXPECT_EQ(1u, wddm->createDebugDataCalled);
|
||||
EXPECT_EQ(0x12345678u, wddm->createDebugDataPassedParam.param.hElfAddressPtr);
|
||||
EXPECT_EQ(1u, wddm->moduleCreateNotifyCalled);
|
||||
EXPECT_EQ(0xDEADDEADu, wddm->moduleCreateNotificationPassedParam.param.hElfAddressPtr);
|
||||
}
|
||||
|
||||
TEST_F(L0DebuggerWindowsTest, givenDebuggerL0NotifyModuleCreateCalledThenCreateDebugDataAndModuleCreateNotifyEscapesAreCalled) {
|
||||
auto debugger = static_cast<DebuggerL0 *>(neoDevice->getDebugger());
|
||||
debugger->notifyModuleCreate((void *)0x12345678, 0x1000, 0x80000000);
|
||||
EXPECT_EQ(wddm->createDebugDataCalled, 1u);
|
||||
EXPECT_EQ(wddm->createDebugDataPassedParam.param.DebugDataType, ELF_BINARY);
|
||||
EXPECT_EQ(wddm->createDebugDataPassedParam.param.DataSize, 0x1000);
|
||||
EXPECT_EQ(wddm->createDebugDataPassedParam.param.hElfAddressPtr, 0x12345678u);
|
||||
EXPECT_EQ(1u, wddm->createDebugDataCalled);
|
||||
EXPECT_EQ(ELF_BINARY, wddm->createDebugDataPassedParam.param.DebugDataType);
|
||||
EXPECT_EQ(0x1000, wddm->createDebugDataPassedParam.param.DataSize);
|
||||
EXPECT_EQ(0x12345678u, wddm->createDebugDataPassedParam.param.hElfAddressPtr);
|
||||
|
||||
EXPECT_EQ(wddm->moduleCreateNotifyCalled, 1u);
|
||||
EXPECT_EQ(1u, wddm->moduleCreateNotifyCalled);
|
||||
EXPECT_TRUE(wddm->moduleCreateNotificationPassedParam.param.IsCreate);
|
||||
EXPECT_EQ(wddm->moduleCreateNotificationPassedParam.param.Modulesize, 0x1000);
|
||||
EXPECT_EQ(wddm->moduleCreateNotificationPassedParam.param.hElfAddressPtr, 0x12345678u);
|
||||
EXPECT_EQ(wddm->moduleCreateNotificationPassedParam.param.LoadAddress, 0x80000000);
|
||||
EXPECT_EQ(0x1000, wddm->moduleCreateNotificationPassedParam.param.Modulesize);
|
||||
EXPECT_EQ(0x12345678u, wddm->moduleCreateNotificationPassedParam.param.hElfAddressPtr);
|
||||
EXPECT_EQ(0x80000000, wddm->moduleCreateNotificationPassedParam.param.LoadAddress);
|
||||
}
|
||||
|
||||
TEST_F(L0DebuggerWindowsTest, givenDebuggerL0NotifyModuleDestroyCalledThenModuleDestroyNotifyEscapeIsCalled) {
|
||||
auto debugger = static_cast<DebuggerL0 *>(neoDevice->getDebugger());
|
||||
debugger->notifyModuleDestroy(0x80000000);
|
||||
|
||||
EXPECT_EQ(1u, wddm->moduleCreateNotifyCalled);
|
||||
EXPECT_FALSE(wddm->moduleCreateNotificationPassedParam.param.IsCreate);
|
||||
EXPECT_EQ(0x1000, wddm->moduleCreateNotificationPassedParam.param.Modulesize);
|
||||
EXPECT_EQ(std::numeric_limits<uint64_t>::max(), wddm->moduleCreateNotificationPassedParam.param.hElfAddressPtr);
|
||||
EXPECT_EQ(0x80000000, wddm->moduleCreateNotificationPassedParam.param.LoadAddress);
|
||||
}
|
||||
|
||||
TEST_F(L0DebuggerWindowsTest, givenDebuggerL0NotifyModuleDestroyCalledAndModuleDestroyNotifyEscapeIsFailedThenErrorMessageIsPrinted) {
|
||||
DebugManagerStateRestore restorer;
|
||||
NEO::DebugManager.flags.DebuggerLogBitmask.set(255);
|
||||
|
||||
testing::internal::CaptureStderr();
|
||||
wddm->moduleCreateNotificationPassedParam.ntStatus = STATUS_UNSUCCESSFUL;
|
||||
auto debugger = static_cast<DebuggerL0 *>(neoDevice->getDebugger());
|
||||
debugger->notifyModuleDestroy(0x80000000);
|
||||
|
||||
EXPECT_EQ(1u, wddm->moduleCreateNotifyCalled);
|
||||
EXPECT_TRUE(hasSubstr(testing::internal::GetCapturedStderr(), std::string("KM_ESCAPE_EUDBG_UMD_MODULE_DESTROY_NOTIFY: Failed - Status:")));
|
||||
}
|
||||
|
||||
} // namespace ult
|
||||
|
||||
@@ -201,6 +201,8 @@ ze_result_t DebugSessionWindows::handleModuleCreateEvent(uint32_t seqNo, DBGUMD_
|
||||
} else {
|
||||
auto it = std::find_if(allModules.begin(), allModules.end(), [&](auto &m) { return m.gpuAddress == moduleCreateParams.LoadAddress; });
|
||||
if (it != allModules.end()) {
|
||||
moduleCreateParams.hElfAddressPtr = it->cpuAddress;
|
||||
moduleCreateParams.ElfModulesize = it->size;
|
||||
allModules.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -662,8 +662,8 @@ TEST_F(DebugApiWindowsTest, givenModuleDestroyNotificationeEventTypeWhenReadAndH
|
||||
mockWddm->eventQueue[0].readEventType = DBGUMD_READ_EVENT_MODULE_CREATE_NOTIFICATION;
|
||||
mockWddm->eventQueue[0].seqNo = 123u;
|
||||
mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ModuleCreateEventParams.IsModuleCreate = false;
|
||||
mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ModuleCreateEventParams.hElfAddressPtr = 0x12345678;
|
||||
mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ModuleCreateEventParams.ElfModulesize = 0x1000;
|
||||
mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ModuleCreateEventParams.hElfAddressPtr = 0xDEADDEAD;
|
||||
mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ModuleCreateEventParams.ElfModulesize = 1;
|
||||
mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ModuleCreateEventParams.LoadAddress = 0x80000000;
|
||||
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, session->readAndHandleEvent(100));
|
||||
|
||||
@@ -96,6 +96,7 @@ class DebuggerL0 : public NEO::Debugger, NEO::NonCopyableOrMovableClass {
|
||||
MOCKABLE_VIRTUAL void notifyCommandQueueDestroyed(NEO::Device *device);
|
||||
MOCKABLE_VIRTUAL void notifyModuleLoadAllocations(const StackVec<NEO::GraphicsAllocation *, 32> &allocs);
|
||||
MOCKABLE_VIRTUAL void notifyModuleCreate(void *module, uint32_t moduleSize, uint64_t moduleLoadAddress);
|
||||
MOCKABLE_VIRTUAL void notifyModuleDestroy(uint64_t moduleLoadAddress);
|
||||
MOCKABLE_VIRTUAL void registerAllocationType(GraphicsAllocation *allocation);
|
||||
void initSbaTrackingMode();
|
||||
|
||||
|
||||
@@ -64,6 +64,8 @@ bool DebuggerL0::removeZebinModule(uint32_t moduleHandle) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void DebuggerL0::notifyModuleDestroy(uint64_t moduleLoadAddress) {}
|
||||
|
||||
void DebuggerL0::notifyCommandQueueCreated(NEO::Device *device) {
|
||||
if (this->device->getRootDeviceEnvironment().osInterface.get() != nullptr) {
|
||||
std::unique_lock<std::mutex> commandQueueCountLock(debuggerL0Mutex);
|
||||
|
||||
@@ -74,8 +74,7 @@ void DebuggerL0::registerAllocationType(GraphicsAllocation *allocation) {
|
||||
allocationDebugDataInfo.DataSize = sizeof(registrationData);
|
||||
allocationDebugDataInfo.DataPointer = reinterpret_cast<uint64_t>(®istrationData);
|
||||
|
||||
KM_ESCAPE_INFO escapeInfo;
|
||||
memset(&escapeInfo, 0, sizeof(escapeInfo));
|
||||
KM_ESCAPE_INFO escapeInfo = {0};
|
||||
escapeInfo.Header.EscapeCode = GFX_ESCAPE_KMD;
|
||||
escapeInfo.Header.Size = sizeof(escapeInfo) - sizeof(escapeInfo.Header);
|
||||
escapeInfo.EscapeOperation = KM_ESCAPE_EUDBG_UMD_REGISTER_ALLOCATION_TYPE;
|
||||
@@ -111,8 +110,7 @@ void DebuggerL0::notifyModuleCreate(void *module, uint32_t moduleSize, uint64_t
|
||||
}
|
||||
|
||||
// Register ELF
|
||||
KM_ESCAPE_INFO escapeInfo;
|
||||
memset(&escapeInfo, 0, sizeof(escapeInfo));
|
||||
KM_ESCAPE_INFO escapeInfo = {0};
|
||||
escapeInfo.Header.EscapeCode = GFX_ESCAPE_KMD;
|
||||
escapeInfo.Header.Size = sizeof(escapeInfo) - sizeof(escapeInfo.Header);
|
||||
escapeInfo.EscapeOperation = KM_ESCAPE_EUDBG_UMD_CREATE_DEBUG_DATA;
|
||||
@@ -142,7 +140,7 @@ void DebuggerL0::notifyModuleCreate(void *module, uint32_t moduleSize, uint64_t
|
||||
PRINT_DEBUGGER_INFO_LOG("KM_ESCAPE_EUDBG_UMD_CREATE_DEBUG_DATA - Success\n");
|
||||
|
||||
// Fire MODULE_CREATE event
|
||||
memset(&escapeInfo, 0, sizeof(escapeInfo));
|
||||
escapeInfo = {0};
|
||||
escapeInfo.Header.EscapeCode = GFX_ESCAPE_KMD;
|
||||
escapeInfo.Header.Size = sizeof(escapeInfo) - sizeof(escapeInfo.Header);
|
||||
escapeInfo.EscapeOperation = KM_ESCAPE_EUDBG_UMD_MODULE_CREATE_NOTIFY;
|
||||
@@ -151,8 +149,6 @@ void DebuggerL0::notifyModuleCreate(void *module, uint32_t moduleSize, uint64_t
|
||||
escapeInfo.KmEuDbgUmdCreateModuleNotification.hElfAddressPtr = reinterpret_cast<uint64_t>(module);
|
||||
escapeInfo.KmEuDbgUmdCreateModuleNotification.LoadAddress = moduleLoadAddress;
|
||||
|
||||
PRINT_DEBUGGER_INFO_LOG("Sending KM_ESCAPE_EUDBG_UMD_MODULE_CREATE_NOTIFY...\n");
|
||||
|
||||
status = wddm->escape(escapeCommand);
|
||||
|
||||
if (STATUS_SUCCESS != status) {
|
||||
@@ -163,6 +159,42 @@ void DebuggerL0::notifyModuleCreate(void *module, uint32_t moduleSize, uint64_t
|
||||
PRINT_DEBUGGER_INFO_LOG("KM_ESCAPE_EUDBG_UMD_MODULE_CREATE_NOTIFY - Success\n");
|
||||
}
|
||||
|
||||
void DebuggerL0::notifyModuleDestroy(uint64_t moduleLoadAddress) {
|
||||
if (device->getRootDeviceEnvironment().osInterface == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
KM_ESCAPE_INFO escapeInfo = {0};
|
||||
escapeInfo.Header.EscapeCode = GFX_ESCAPE_KMD;
|
||||
escapeInfo.Header.Size = sizeof(escapeInfo) - sizeof(escapeInfo.Header);
|
||||
escapeInfo.EscapeOperation = KM_ESCAPE_EUDBG_UMD_MODULE_CREATE_NOTIFY;
|
||||
escapeInfo.KmEuDbgUmdCreateModuleNotification.IsCreate = false;
|
||||
escapeInfo.KmEuDbgUmdCreateModuleNotification.Modulesize = 0x1000;
|
||||
escapeInfo.KmEuDbgUmdCreateModuleNotification.hElfAddressPtr = uint64_t(-1);
|
||||
escapeInfo.KmEuDbgUmdCreateModuleNotification.LoadAddress = moduleLoadAddress;
|
||||
|
||||
auto wddm = device->getRootDeviceEnvironment().osInterface->getDriverModel()->as<NEO::Wddm>();
|
||||
|
||||
D3DKMT_ESCAPE escapeCommand = {0};
|
||||
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;
|
||||
|
||||
auto status = wddm->escape(escapeCommand);
|
||||
|
||||
if (STATUS_SUCCESS != status) {
|
||||
PRINT_DEBUGGER_ERROR_LOG("KM_ESCAPE_EUDBG_UMD_MODULE_DESTROY_NOTIFY: Failed - Status: 0x%llX\n", status);
|
||||
return;
|
||||
}
|
||||
|
||||
PRINT_DEBUGGER_INFO_LOG("KM_ESCAPE_EUDBG_UMD_MODULE_DESTROY_NOTIFY - Success\n");
|
||||
}
|
||||
|
||||
bool DebuggerL0::removeZebinModule(uint32_t moduleHandle) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -101,6 +101,11 @@ class MockDebuggerL0Hw : public NEO::DebuggerL0Hw<GfxFamily> {
|
||||
NEO::DebuggerL0Hw<GfxFamily>::notifyModuleCreate(module, moduleSize, moduleLoadAddress);
|
||||
}
|
||||
|
||||
void notifyModuleDestroy(uint64_t moduleLoadAddress) override {
|
||||
notifyModuleDestroyCount++;
|
||||
NEO::DebuggerL0Hw<GfxFamily>::notifyModuleDestroy(moduleLoadAddress);
|
||||
}
|
||||
|
||||
uint32_t captureStateBaseAddressCount = 0;
|
||||
uint32_t programSbaTrackingCommandsCount = 0;
|
||||
uint32_t getSbaTrackingCommandsSizeCount = 0;
|
||||
@@ -109,6 +114,7 @@ class MockDebuggerL0Hw : public NEO::DebuggerL0Hw<GfxFamily> {
|
||||
uint32_t commandQueueDestroyedCount = 0;
|
||||
uint32_t registerAllocationTypeCount = 0;
|
||||
uint32_t notifyModuleCreateCount = 0;
|
||||
uint32_t notifyModuleDestroyCount = 0;
|
||||
const char *lastReceivedElf = nullptr;
|
||||
|
||||
uint32_t segmentCountWithAttachedModuleHandle = 0;
|
||||
|
||||
Reference in New Issue
Block a user