L0Debug Win: Always generate module create/destroy events

We have to always generate module create/destroy events to give
debugger a chance to insert bp, read/write debuggee memory  etc
even there is no debug data was generated. In this case ELF will not be
reported to debugger, just ISA GpuVA

Related-To: NEO-6723

Signed-off-by: Igor Venevtsev <igor.venevtsev@intel.com>
This commit is contained in:
Igor Venevtsev
2022-08-23 12:02:10 +00:00
committed by Compute-Runtime-Automation
parent aa59ee94b2
commit d40173e47a
6 changed files with 56 additions and 33 deletions

View File

@@ -1262,26 +1262,17 @@ void ModuleImp::notifyModuleCreate() {
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);
debuggerL0->notifyModuleCreate(const_cast<char *>(debugData.vIsa), debugData.vIsaSize, moduleLoadAddress);
UNRECOVERABLE_IF(!translationUnit->debugData);
debuggerL0->notifyModuleCreate(translationUnit->debugData.get(), static_cast<uint32_t>(debugDataSize), moduleLoadAddress);
} else {
for (auto &kernImmData : kernelImmDatas) {
if (kernImmData->getKernelInfo()->kernelDescriptor.external.debugData.get()) {
NEO::DebugData *notifyDebugData = kernImmData->getKernelInfo()->kernelDescriptor.external.debugData.get();
NEO::DebugData relocatedDebugData;
auto debugData = kernImmData->getKernelInfo()->kernelDescriptor.external.debugData.get();
auto relocatedDebugData = kernImmData->getKernelInfo()->kernelDescriptor.external.relocatedDebugData.get();
if (kernImmData->getKernelInfo()->kernelDescriptor.external.relocatedDebugData.get()) {
relocatedDebugData.genIsa = kernImmData->getKernelInfo()->kernelDescriptor.external.debugData->genIsa;
relocatedDebugData.genIsaSize = kernImmData->getKernelInfo()->kernelDescriptor.external.debugData->genIsaSize;
relocatedDebugData.vIsa = reinterpret_cast<char *>(kernImmData->getKernelInfo()->kernelDescriptor.external.relocatedDebugData.get());
relocatedDebugData.vIsaSize = kernImmData->getKernelInfo()->kernelDescriptor.external.debugData->vIsaSize;
notifyDebugData = &relocatedDebugData;
}
debuggerL0->notifyModuleCreate(const_cast<char *>(notifyDebugData->vIsa), notifyDebugData->vIsaSize, kernImmData->getIsaGraphicsAllocation()->getGpuAddress());
if (debugData) {
debuggerL0->notifyModuleCreate(relocatedDebugData ? reinterpret_cast<char *>(relocatedDebugData) : const_cast<char *>(debugData->vIsa), debugData->vIsaSize, kernImmData->getIsaGraphicsAllocation()->getGpuAddress());
} else {
debuggerL0->notifyModuleCreate(nullptr, 0, kernImmData->getIsaGraphicsAllocation()->getGpuAddress());
}
}
}
@@ -1298,12 +1289,10 @@ void ModuleImp::notifyModuleDestroy() {
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;

View File

@@ -515,7 +515,7 @@ HWTEST_F(ModuleWithDebuggerL0Test, GivenDebugDataWithoutRelocationsWhenInitializ
EXPECT_EQ(kernelInfo->kernelDescriptor.external.debugData->vIsa, getMockDebuggerL0Hw<FamilyType>()->lastReceivedElf);
}
HWTEST_F(ModuleWithDebuggerL0Test, GivenNoDebugDataWhenInitializingModuleThenDoNotRegisterElfAndDoNotNotifyModuleCreate) {
HWTEST_F(ModuleWithDebuggerL0Test, GivenNoDebugDataWhenInitializingModuleThenDoNotRegisterElfAndNotifyModuleCreate) {
NEO::MockCompilerEnableGuard mock(true);
auto cip = new NEO::MockCompilerInterfaceCaptureBuildOptions();
neoDevice->getExecutionEnvironment()->rootDeviceEnvironments[device->getRootDeviceIndex()]->compilerInterface.reset(cip);
@@ -546,7 +546,7 @@ HWTEST_F(ModuleWithDebuggerL0Test, GivenNoDebugDataWhenInitializingModuleThenDoN
EXPECT_EQ(0u, getMockDebuggerL0Hw<FamilyType>()->registerElfCount);
EXPECT_TRUE(moduleMock->initialize(&moduleDesc, neoDevice));
EXPECT_EQ(0u, getMockDebuggerL0Hw<FamilyType>()->registerElfCount);
EXPECT_EQ(0u, getMockDebuggerL0Hw<FamilyType>()->notifyModuleCreateCount);
EXPECT_EQ(1u, getMockDebuggerL0Hw<FamilyType>()->notifyModuleCreateCount);
}
using ModuleWithZebinAndL0DebuggerTest = Test<L0DebuggerHwFixture>;
@@ -703,7 +703,7 @@ HWTEST_F(ModuleWithDebuggerL0Test, GivenNonZebinBinaryWhenDestroyModuleThenModul
EXPECT_EQ(1u, getMockDebuggerL0Hw<FamilyType>()->notifyModuleDestroyCount);
}
HWTEST_F(ModuleWithDebuggerL0Test, GivenNoDebugDataWhenDestroyingModuleThenDoNotNotifyModuleDestroy) {
HWTEST_F(ModuleWithDebuggerL0Test, GivenNoDebugDataWhenDestroyingModuleThenNotifyModuleDestroy) {
NEO::MockCompilerEnableGuard mock(true);
auto cip = std::make_unique<NEO::MockCompilerInterfaceCaptureBuildOptions>();
neoDevice->getExecutionEnvironment()->rootDeviceEnvironments[device->getRootDeviceIndex()]->compilerInterface = std::move(cip);
@@ -734,7 +734,7 @@ HWTEST_F(ModuleWithDebuggerL0Test, GivenNoDebugDataWhenDestroyingModuleThenDoNot
EXPECT_TRUE(moduleMock->initialize(&moduleDesc, neoDevice));
moduleMock->destroy();
moduleMock.release();
EXPECT_EQ(0u, getMockDebuggerL0Hw<FamilyType>()->notifyModuleDestroyCount);
EXPECT_EQ(1u, getMockDebuggerL0Hw<FamilyType>()->notifyModuleDestroyCount);
}
HWTEST_F(ModuleWithZebinAndL0DebuggerTest, GivenModuleDebugHandleZeroWhenInitializingAndDestoryingModuleThenHandleIsNotPassedToDebugger) {

View File

@@ -177,8 +177,8 @@ TEST_F(L0DebuggerWindowsTest, givenDebuggerL0NotifyModuleDestroyCalledThenModule
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(0u, wddm->moduleCreateNotificationPassedParam.param.Modulesize);
EXPECT_EQ(0ull, wddm->moduleCreateNotificationPassedParam.param.hElfAddressPtr);
EXPECT_EQ(0x80000000, wddm->moduleCreateNotificationPassedParam.param.LoadAddress);
}

View File

@@ -303,11 +303,13 @@ ze_result_t DebugSessionWindows::readAllocationDebugData(uint32_t seqNo, uint64_
ze_result_t DebugSessionWindows::handleCreateDebugDataEvent(DBGUMD_READ_EVENT_CREATE_DEBUG_DATA_PARAMS &createDebugDataParams) {
PRINT_DEBUGGER_INFO_LOG("DBGUMD_READ_EVENT_CREATE_DEBUG_DATA_PARAMS: Type: %d BufferPtr: 0x%llX DataSize: 0x%lX\n", createDebugDataParams.DebugDataType, createDebugDataParams.DataBufferPtr, createDebugDataParams.DataSize);
if (createDebugDataParams.DebugDataType == ELF_BINARY) {
if (createDebugDataParams.DataBufferPtr && createDebugDataParams.DataSize) {
std::unique_lock<std::mutex> lock(asyncThreadMutex);
ElfRange elf;
ElfRange elf = {};
elf.startVA = createDebugDataParams.DataBufferPtr;
elf.endVA = elf.startVA + createDebugDataParams.DataSize;
allElfs.push_back(elf);
}
} else if (createDebugDataParams.DebugDataType == static_cast<uint32_t>(NEO::DebugDataType::CMD_QUEUE_CREATED)) {
zet_debug_event_t debugEvent = {};
debugEvent.type = ZET_DEBUG_EVENT_TYPE_PROCESS_ENTRY;

View File

@@ -504,6 +504,38 @@ TEST_F(DebugApiWindowsTest, givenDebugDataEventTypeWhenReadAndHandleEventCalledT
EXPECT_EQ(elf.endVA, 0xa008u);
}
TEST_F(DebugApiWindowsTest, givenDebugDataEventTypeAndNullDebugDataPtrWhenReadAndHandleEventCalledThenResultDebugDataIsNotSaved) {
zet_debug_config_t config = {};
config.pid = 0x1234;
auto session = std::make_unique<MockDebugSessionWindows>(config, device);
session->wddm = mockWddm;
mockWddm->numEvents = 1;
mockWddm->eventQueue[0].readEventType = DBGUMD_READ_EVENT_CREATE_DEBUG_DATA;
mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ReadCreateDebugDataParams.DebugDataType = ELF_BINARY;
mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ReadCreateDebugDataParams.DataBufferPtr = 0;
mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ReadCreateDebugDataParams.DataSize = 8;
EXPECT_EQ(ZE_RESULT_SUCCESS, session->readAndHandleEvent(100));
EXPECT_TRUE(session->allElfs.empty());
}
TEST_F(DebugApiWindowsTest, givenDebugDataEventTypeAndNullDebugDataSizeWhenReadAndHandleEventCalledThenResultDebugDataIsNotSaved) {
zet_debug_config_t config = {};
config.pid = 0x1234;
auto session = std::make_unique<MockDebugSessionWindows>(config, device);
session->wddm = mockWddm;
mockWddm->numEvents = 1;
mockWddm->eventQueue[0].readEventType = DBGUMD_READ_EVENT_CREATE_DEBUG_DATA;
mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ReadCreateDebugDataParams.DebugDataType = ELF_BINARY;
mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ReadCreateDebugDataParams.DataBufferPtr = 0xa000;
mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ReadCreateDebugDataParams.DataSize = 0;
EXPECT_EQ(ZE_RESULT_SUCCESS, session->readAndHandleEvent(100));
EXPECT_TRUE(session->allElfs.empty());
}
TEST(DebugSessionTest, GivenNullptrEventWhenReadingEventThenErrorNullptrReturned) {
zet_debug_config_t config = {};
config.pid = 0x1234;

View File

@@ -169,8 +169,8 @@ void DebuggerL0::notifyModuleDestroy(uint64_t moduleLoadAddress) {
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.Modulesize = 0;
escapeInfo.KmEuDbgUmdCreateModuleNotification.hElfAddressPtr = 0;
escapeInfo.KmEuDbgUmdCreateModuleNotification.LoadAddress = moduleLoadAddress;
auto wddm = device->getRootDeviceEnvironment().osInterface->getDriverModel()->as<NEO::Wddm>();