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:
Igor Venevtsev
2022-07-26 10:48:22 +00:00
committed by Compute-Runtime-Automation
parent f17b46bc22
commit 4cb9ad5d55
11 changed files with 225 additions and 41 deletions

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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));

View File

@@ -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) {

View File

@@ -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

View File

@@ -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);
}
}

View File

@@ -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));

View File

@@ -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();

View File

@@ -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);

View File

@@ -74,8 +74,7 @@ void DebuggerL0::registerAllocationType(GraphicsAllocation *allocation) {
allocationDebugDataInfo.DataSize = sizeof(registrationData);
allocationDebugDataInfo.DataPointer = reinterpret_cast<uint64_t>(&registrationData);
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;
}

View File

@@ -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;