Skip to content

Commit 7ccde3f

Browse files
bmyatesCompute-Runtime-Automation
authored andcommitted
L0 Win Debug - read StateSave and moduleDebug header
Related-to: NEO-7162 Signed-off-by: Yates, Brandon <[email protected]>
1 parent b225c63 commit 7ccde3f

File tree

7 files changed

+236
-14
lines changed

7 files changed

+236
-14
lines changed

level_zero/tools/source/debug/debug_session_imp.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,18 @@ void DebugSessionImp::generateEventsForStoppedThreads(const std::vector<EuThread
717717
}
718718
}
719719

720+
void DebugSessionImp::validateAndSetStateSaveAreaHeader(const std::vector<char> &data) {
721+
auto pStateSaveArea = reinterpret_cast<const SIP::StateSaveAreaHeader *>(data.data());
722+
if (0 == strcmp(pStateSaveArea->versionHeader.magic, "tssarea")) {
723+
size_t size = pStateSaveArea->versionHeader.size * 8u;
724+
DEBUG_BREAK_IF(size != sizeof(SIP::StateSaveAreaHeader));
725+
stateSaveAreaHeader.assign(data.begin(), data.begin() + size);
726+
PRINT_DEBUGGER_INFO_LOG("Context State Save Area : version == %d.%d.%d\n", (int)pStateSaveArea->versionHeader.version.major, (int)pStateSaveArea->versionHeader.version.minor, (int)pStateSaveArea->versionHeader.version.patch);
727+
} else {
728+
PRINT_DEBUGGER_ERROR_LOG("Setting Context State Save Area: failed to match magic numbers\n", "");
729+
}
730+
}
731+
720732
const SIP::StateSaveAreaHeader *DebugSessionImp::getStateSaveAreaHeader() {
721733
if (stateSaveAreaHeader.empty()) {
722734
readStateSaveAreaHeader();

level_zero/tools/source/debug/debug_session_imp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ struct DebugSessionImp : DebugSession {
6969
MOCKABLE_VIRTUAL void generateEventsForPendingInterrupts();
7070

7171
const SIP::StateSaveAreaHeader *getStateSaveAreaHeader();
72+
void validateAndSetStateSaveAreaHeader(const std::vector<char> &data);
7273
virtual void readStateSaveAreaHeader(){};
7374

7475
virtual uint64_t getContextStateSaveAreaGpuVa(uint64_t memoryHandle) {

level_zero/tools/source/debug/linux/prelim/debug_session.cpp

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -647,14 +647,7 @@ void DebugSessionLinux::readStateSaveAreaHeader() {
647647
if (retVal != 0) {
648648
PRINT_DEBUGGER_ERROR_LOG("Reading Context State Save Area failed, error = %d\n", retVal);
649649
} else {
650-
auto pStateSaveArea = reinterpret_cast<const SIP::StateSaveAreaHeader *>(data.data());
651-
if (0 == strcmp(pStateSaveArea->versionHeader.magic, "tssarea")) {
652-
size_t size = pStateSaveArea->versionHeader.size * 8u;
653-
DEBUG_BREAK_IF(size != sizeof(SIP::StateSaveAreaHeader));
654-
stateSaveAreaHeader.assign(data.begin(), data.begin() + size);
655-
656-
PRINT_DEBUGGER_INFO_LOG("Context State Save Area : version == %d.%d.%d\n", (int)pStateSaveArea->versionHeader.version.major, (int)pStateSaveArea->versionHeader.version.minor, (int)pStateSaveArea->versionHeader.version.patch);
657-
}
650+
validateAndSetStateSaveAreaHeader(data);
658651
}
659652
}
660653
}

level_zero/tools/source/debug/windows/debug_session.cpp

Lines changed: 64 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
#include "shared/source/helpers/register_offsets.h"
1111

12+
#include "common/StateSaveAreaHeader.h"
13+
1214
namespace L0 {
1315

1416
DebugSession *createDebugSessionHelper(const zet_debug_config_t &config, Device *device, int debugFd);
@@ -60,11 +62,13 @@ ze_result_t DebugSessionWindows::initialize() {
6062
PRINT_DEBUGGER_INFO_LOG("DBGUMD_ACTION_ATTACH_DEBUGGER: SUCCESS - ProcessId: %d DebugHandle: 0x%llx\n", processId, debugHandle);
6163

6264
auto result = ZE_RESULT_SUCCESS;
65+
6366
do {
6467
result = readAndHandleEvent(100);
6568
} while (result == ZE_RESULT_SUCCESS && !moduleDebugAreaCaptured);
6669

6770
if (moduleDebugAreaCaptured) {
71+
readModuleDebugArea();
6872
return ZE_RESULT_SUCCESS;
6973
}
7074

@@ -203,7 +207,13 @@ ze_result_t DebugSessionWindows::handleAllocationDataEvent(uint32_t seqNo, DBGUM
203207
}
204208

205209
if (allocationDebugData->DataType == MODULE_HEAP_DEBUG_AREA) {
210+
DEBUG_BREAK_IF(moduleDebugAreaCaptured && (registrationData.gpuVirtualAddress != this->debugAreaVA));
206211
moduleDebugAreaCaptured = true;
212+
this->debugAreaVA = registrationData.gpuVirtualAddress;
213+
} else if (allocationDebugData->DataType == SIP_CONTEXT_SAVE_AREA) {
214+
DEBUG_BREAK_IF(stateSaveAreaCaptured && (registrationData.gpuVirtualAddress != this->stateSaveAreaVA.load()));
215+
stateSaveAreaVA.store(registrationData.gpuVirtualAddress);
216+
stateSaveAreaCaptured = true;
207217
}
208218
PRINT_DEBUGGER_INFO_LOG("DBGUMD_ACTION_READ_ALLOCATION_DATA - Success - gpuVA=0x%llX Size=0x%X\n", registrationData.gpuVirtualAddress, registrationData.size);
209219
}
@@ -454,10 +464,6 @@ bool DebugSessionWindows::readSystemRoutineIdent(EuThread *thread, uint64_t vmHa
454464
return false;
455465
}
456466

457-
bool DebugSessionWindows::readModuleDebugArea() {
458-
return false;
459-
}
460-
461467
ze_result_t DebugSessionWindows::readSbaBuffer(EuThread::ThreadId threadId, NEO::SbaTrackedAddresses &sbaBuffer) {
462468
uint64_t gpuVa = 0;
463469
getSbaBufferGpuVa(gpuVa);
@@ -493,4 +499,58 @@ void DebugSessionWindows::getSbaBufferGpuVa(uint64_t &gpuVa) {
493499
return;
494500
}
495501

502+
bool DebugSessionWindows::readModuleDebugArea() {
503+
504+
uint64_t memoryHandle = 0;
505+
uint64_t gpuVa = this->debugAreaVA;
506+
if (!moduleDebugAreaCaptured || allContexts.empty()) {
507+
return false;
508+
}
509+
memoryHandle = *allContexts.begin();
510+
511+
memset(this->debugArea.magic, 0, sizeof(this->debugArea.magic));
512+
auto retVal = readGpuMemory(memoryHandle, reinterpret_cast<char *>(&this->debugArea), sizeof(this->debugArea), gpuVa);
513+
514+
if (retVal != ZE_RESULT_SUCCESS) {
515+
PRINT_DEBUGGER_ERROR_LOG("Reading Module Debug Area failed, error = %d\n", retVal);
516+
return false;
517+
}
518+
519+
if (strncmp(this->debugArea.magic, "dbgarea", sizeof(NEO::DebugAreaHeader::magic)) != 0) {
520+
PRINT_DEBUGGER_ERROR_LOG("Module Debug Area failed to match magic numbers\n");
521+
return false;
522+
}
523+
PRINT_DEBUGGER_INFO_LOG("Reading Module Debug Area Passed");
524+
return true;
525+
}
526+
527+
void DebugSessionWindows::readStateSaveAreaHeader() {
528+
529+
uint64_t memoryHandle = 0;
530+
uint64_t gpuVa = 0;
531+
if (!stateSaveAreaCaptured) {
532+
return;
533+
}
534+
gpuVa = this->stateSaveAreaVA.load();
535+
536+
{
537+
std::unique_lock<std::mutex> lock(asyncThreadMutex);
538+
if (allContexts.empty()) {
539+
return;
540+
}
541+
memoryHandle = *allContexts.begin();
542+
}
543+
544+
auto headerSize = sizeof(SIP::StateSaveAreaHeader);
545+
std::vector<char> data(headerSize);
546+
auto retVal = readGpuMemory(memoryHandle, data.data(), headerSize, gpuVa);
547+
548+
if (retVal != ZE_RESULT_SUCCESS) {
549+
PRINT_DEBUGGER_ERROR_LOG("Reading Context State Save Area failed, error = %d\n", retVal);
550+
return;
551+
}
552+
553+
validateAndSetStateSaveAreaHeader(data);
554+
}
555+
496556
} // namespace L0

level_zero/tools/source/debug/windows/debug_session.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "KmEscape.h"
1818

19+
#include <atomic>
1920
#include <unordered_set>
2021

2122
namespace L0 {
@@ -45,6 +46,7 @@ struct DebugSessionWindows : DebugSessionImp {
4546
ze_result_t readElfSpace(const zet_debug_memory_space_desc_t *desc, size_t size, void *buffer);
4647

4748
ze_result_t readSbaBuffer(EuThread::ThreadId, NEO::SbaTrackedAddresses &sbaBuffer) override;
49+
void readStateSaveAreaHeader() override;
4850

4951
MOCKABLE_VIRTUAL ze_result_t readAndHandleEvent(uint64_t timeoutMs);
5052
ze_result_t handleModuleCreateEvent(DBGUMD_READ_EVENT_MODULE_CREATE_EVENT_PARAMS &moduleCreateParams);
@@ -65,7 +67,6 @@ struct DebugSessionWindows : DebugSessionImp {
6567
ThreadHelper asyncThread;
6668
std::mutex asyncThreadMutex;
6769
MOCKABLE_VIRTUAL void getSbaBufferGpuVa(uint64_t &gpuVa);
68-
6970
MOCKABLE_VIRTUAL NTSTATUS runEscape(KM_ESCAPE_INFO &escapeInfo);
7071

7172
bool moduleDebugAreaCaptured = false;
@@ -79,6 +80,11 @@ struct DebugSessionWindows : DebugSessionImp {
7980
uint64_t endVA;
8081
};
8182

83+
uint64_t debugAreaVA;
84+
NEO::DebugAreaHeader debugArea;
85+
std::atomic<uint64_t> stateSaveAreaVA{0};
86+
bool stateSaveAreaCaptured = false;
87+
8288
std::unordered_set<uint64_t> allContexts;
8389
std::vector<ElfRange> allElfs;
8490
};

level_zero/tools/test/unit_tests/sources/debug/windows/test_debug_api_windows.cpp

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,17 @@
55
*
66
*/
77

8+
#include "shared/source/built_ins/sip.h"
89
#include "shared/source/os_interface/windows/wddm_allocation.h"
10+
#include "shared/test/common/mocks/mock_sip.h"
911
#include "shared/test/common/mocks/windows/mock_wddm_eudebug.h"
1012
#include "shared/test/common/test_macros/hw_test.h"
1113

1214
#include "level_zero/core/test/unit_tests/fixtures/device_fixture.h"
1315
#include "level_zero/tools/source/debug/windows/debug_session.h"
1416

17+
#include "common/StateSaveAreaHeader.h"
18+
1519
namespace L0 {
1620
namespace ult {
1721

@@ -20,6 +24,8 @@ struct MockDebugSessionWindows : DebugSessionWindows {
2024
using DebugSessionWindows::allElfs;
2125
using DebugSessionWindows::asyncThread;
2226
using DebugSessionWindows::closeAsyncThread;
27+
using DebugSessionWindows::debugArea;
28+
using DebugSessionWindows::debugAreaVA;
2329
using DebugSessionWindows::debugHandle;
2430
using DebugSessionWindows::ElfRange;
2531
using DebugSessionWindows::getSbaBufferGpuVa;
@@ -30,11 +36,16 @@ struct MockDebugSessionWindows : DebugSessionWindows {
3036
using DebugSessionWindows::readAllocationDebugData;
3137
using DebugSessionWindows::readAndHandleEvent;
3238
using DebugSessionWindows::readGpuMemory;
39+
using DebugSessionWindows::readModuleDebugArea;
3340
using DebugSessionWindows::readSbaBuffer;
41+
using DebugSessionWindows::readStateSaveAreaHeader;
3442
using DebugSessionWindows::runEscape;
3543
using DebugSessionWindows::startAsyncThread;
44+
using DebugSessionWindows::stateSaveAreaCaptured;
45+
using DebugSessionWindows::stateSaveAreaVA;
3646
using DebugSessionWindows::wddm;
3747
using DebugSessionWindows::writeGpuMemory;
48+
using L0::DebugSessionImp::getStateSaveAreaHeader;
3849
using L0::DebugSessionImp::isValidGpuAddress;
3950

4051
MockDebugSessionWindows(const zet_debug_config_t &config, L0::Device *device) : DebugSessionWindows(config, device) {}
@@ -336,6 +347,7 @@ TEST_F(DebugApiWindowsTest, givenDebugSessionInitializeCalledAndEventQueueIsNotA
336347

337348
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
338349
EXPECT_TRUE(session->moduleDebugAreaCaptured);
350+
EXPECT_EQ(session->debugAreaVA, 0x12345678U);
339351
EXPECT_EQ(1u, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_ATTACH_DEBUGGER]);
340352
EXPECT_EQ(3u, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_READ_EVENT]);
341353
EXPECT_EQ(1u, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_READ_ALLOCATION_DATA]);
@@ -470,6 +482,27 @@ TEST_F(DebugApiWindowsTest, givenDebugDataEventTypeWhenReadAndHandleEventCalledT
470482
EXPECT_EQ(elf.endVA, 0xa008u);
471483
}
472484

485+
TEST_F(DebugApiWindowsTest, givenAllocationEventTypeForStateSaveWhenReadAndHandleEventCalledThenStateSaveIsCaptured) {
486+
zet_debug_config_t config = {};
487+
config.pid = 0x1234;
488+
auto session = std::make_unique<MockDebugSessionWindows>(config, device);
489+
session->wddm = mockWddm;
490+
491+
mockWddm->numEvents = 1;
492+
mockWddm->eventQueue[0].readEventType = DBGUMD_READ_EVENT_ALLOCATION_DATA_INFO;
493+
mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ReadAdditionalAllocDataParams.NumOfDebugData = 1;
494+
GFX_ALLOCATION_DEBUG_DATA_INFO *allocDebugDataInfo = reinterpret_cast<GFX_ALLOCATION_DEBUG_DATA_INFO *>(&mockWddm->eventQueue[0].eventParamsBuffer.eventParamsBuffer.ReadAdditionalAllocDataParams.DebugDataBufferPtr);
495+
allocDebugDataInfo->DataType = SIP_CONTEXT_SAVE_AREA;
496+
497+
WddmAllocation::RegistrationData registrationData = {0x12345678, 0x1000};
498+
mockWddm->readAllocationDataOutParams.outData = &registrationData;
499+
mockWddm->readAllocationDataOutParams.outDataSize = sizeof(registrationData);
500+
501+
EXPECT_EQ(ZE_RESULT_SUCCESS, session->readAndHandleEvent(100));
502+
EXPECT_EQ(session->stateSaveAreaVA.load(), 0x12345678u);
503+
EXPECT_TRUE(session->stateSaveAreaCaptured);
504+
}
505+
473506
TEST_F(DebugApiWindowsTest, givenContextCreateEventTypeWhenReadAndHandleEventCalledThenAllContextsIsSetCorrectly) {
474507
zet_debug_config_t config = {};
475508
config.pid = 0x1234;
@@ -927,5 +960,117 @@ TEST_F(DebugApiWindowsTest, WhenCallingReadMemoryForExpectedFailureCasesThenErro
927960
EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, retVal);
928961
}
929962

963+
TEST_F(DebugApiWindowsTest, GivenModuleDebugAreaVaWhenReadingModuleDebugAreaThenGpuMemoryIsRead) {
964+
auto session = std::make_unique<MockDebugSessionWindows>(zet_debug_config_t{0x1234}, device);
965+
ASSERT_NE(nullptr, session);
966+
session->wddm = mockWddm;
967+
session->debugHandle = MockDebugSessionWindows::mockDebugHandle;
968+
session->allContexts.insert(0x12345);
969+
session->moduleDebugAreaCaptured = true;
970+
session->debugAreaVA = 0xABCDABCD;
971+
972+
DebugAreaHeader debugArea;
973+
debugArea.reserved1 = 1;
974+
debugArea.pgsize = uint8_t(4);
975+
debugArea.version = 1;
976+
mockWddm->srcReadBuffer = &debugArea;
977+
978+
auto retVal = session->readModuleDebugArea();
979+
EXPECT_TRUE(retVal);
980+
ASSERT_EQ(1, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_READ_GFX_MEMORY]);
981+
EXPECT_EQ(1u, session->debugArea.reserved1);
982+
EXPECT_EQ(1u, session->debugArea.version);
983+
EXPECT_EQ(4u, session->debugArea.pgsize);
984+
}
985+
986+
TEST_F(DebugApiWindowsTest, GivenModuleDebugAreaVaWhenReadingModuleDebugAreaReturnsIncorrectDataThenFailIsReturned) {
987+
auto session = std::make_unique<MockDebugSessionWindows>(zet_debug_config_t{0x1234}, device);
988+
ASSERT_NE(nullptr, session);
989+
session->wddm = mockWddm;
990+
session->debugHandle = MockDebugSessionWindows::mockDebugHandle;
991+
session->allContexts.insert(0x12345);
992+
session->moduleDebugAreaCaptured = true;
993+
session->debugAreaVA = 0xABCDABCD;
994+
995+
DebugAreaHeader debugArea;
996+
debugArea.magic[0] = 'x';
997+
mockWddm->srcReadBuffer = &debugArea;
998+
999+
auto retVal = session->readModuleDebugArea();
1000+
EXPECT_FALSE(retVal);
1001+
}
1002+
1003+
TEST_F(DebugApiWindowsTest, GivenErrorInModuleDebugAreaDataWhenReadingModuleDebugAreaThenGpuMemoryIsNotReadAndFalseReturned) {
1004+
auto session = std::make_unique<MockDebugSessionWindows>(zet_debug_config_t{0x1234}, device);
1005+
ASSERT_NE(nullptr, session);
1006+
session->wddm = mockWddm;
1007+
session->debugHandle = MockDebugSessionWindows::mockDebugHandle;
1008+
1009+
auto retVal = session->readModuleDebugArea();
1010+
EXPECT_FALSE(retVal);
1011+
ASSERT_EQ(0, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_READ_GFX_MEMORY]);
1012+
session->moduleDebugAreaCaptured = true;
1013+
retVal = session->readModuleDebugArea();
1014+
EXPECT_FALSE(retVal);
1015+
ASSERT_EQ(0, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_READ_GFX_MEMORY]);
1016+
session->allContexts.insert(0x12345);
1017+
mockWddm->escapeReturnStatus = DBGUMD_RETURN_INVALID_ARGS;
1018+
retVal = session->readModuleDebugArea();
1019+
EXPECT_FALSE(retVal);
1020+
ASSERT_EQ(1, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_READ_GFX_MEMORY]);
1021+
}
1022+
1023+
TEST_F(DebugApiWindowsTest, GivenStateSaveAreaVaWhenReadingStateSaveAreaThenGpuMemoryIsRead) {
1024+
auto session = std::make_unique<MockDebugSessionWindows>(zet_debug_config_t{0x1234}, device);
1025+
ASSERT_NE(nullptr, session);
1026+
session->wddm = mockWddm;
1027+
session->debugHandle = MockDebugSessionWindows::mockDebugHandle;
1028+
session->allContexts.insert(0x12345);
1029+
session->stateSaveAreaCaptured = true;
1030+
session->stateSaveAreaVA.store(0xABCDABCD);
1031+
auto stateSaveAreaHeader = MockSipData::createStateSaveAreaHeader(2);
1032+
mockWddm->srcReadBuffer = stateSaveAreaHeader.data();
1033+
1034+
session->readStateSaveAreaHeader();
1035+
ASSERT_EQ(1, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_READ_GFX_MEMORY]);
1036+
auto stateSaveAreaRead = session->getStateSaveAreaHeader();
1037+
ASSERT_NE(nullptr, stateSaveAreaRead);
1038+
EXPECT_EQ(0, memcmp(stateSaveAreaRead, stateSaveAreaHeader.data(), sizeof(SIP::StateSaveAreaHeader)));
1039+
}
1040+
1041+
TEST_F(DebugApiWindowsTest, GivenStateSaveAreaVaWhenReadingStateSaveAreaReturnsIncorrectDataThenStateSaveAreaIsNotUpdated) {
1042+
auto session = std::make_unique<MockDebugSessionWindows>(zet_debug_config_t{0x1234}, device);
1043+
ASSERT_NE(nullptr, session);
1044+
session->wddm = mockWddm;
1045+
session->debugHandle = MockDebugSessionWindows::mockDebugHandle;
1046+
session->allContexts.insert(0x12345);
1047+
session->stateSaveAreaCaptured = true;
1048+
session->stateSaveAreaVA.store(0xABCDABCD);
1049+
auto stateSaveAreaHeader = MockSipData::createStateSaveAreaHeader(2);
1050+
stateSaveAreaHeader[3] = 'x';
1051+
mockWddm->srcReadBuffer = stateSaveAreaHeader.data();
1052+
1053+
session->readStateSaveAreaHeader();
1054+
ASSERT_EQ(1, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_READ_GFX_MEMORY]);
1055+
auto stateSaveAreaRead = session->getStateSaveAreaHeader();
1056+
ASSERT_EQ(nullptr, stateSaveAreaRead);
1057+
}
1058+
1059+
TEST_F(DebugApiWindowsTest, GivenErrorCasesWhenReadingStateSaveAreThenMemoryIsNotRead) {
1060+
auto session = std::make_unique<MockDebugSessionWindows>(zet_debug_config_t{0x1234}, device);
1061+
ASSERT_NE(nullptr, session);
1062+
session->wddm = mockWddm;
1063+
session->debugHandle = MockDebugSessionWindows::mockDebugHandle;
1064+
session->readStateSaveAreaHeader();
1065+
ASSERT_EQ(0, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_READ_GFX_MEMORY]);
1066+
session->stateSaveAreaCaptured = true;
1067+
session->readStateSaveAreaHeader();
1068+
ASSERT_EQ(0, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_READ_GFX_MEMORY]);
1069+
session->allContexts.insert(0x12345);
1070+
mockWddm->escapeReturnStatus = DBGUMD_RETURN_INVALID_ARGS;
1071+
session->readStateSaveAreaHeader();
1072+
ASSERT_EQ(1, mockWddm->dbgUmdEscapeActionCalled[DBGUMD_ACTION_READ_GFX_MEMORY]);
1073+
}
1074+
9301075
} // namespace ult
9311076
} // namespace L0

0 commit comments

Comments
 (0)