2022-03-29 15:39:27 +00:00
|
|
|
/*
|
2024-01-18 18:39:41 +00:00
|
|
|
* Copyright (C) 2021-2024 Intel Corporation
|
2022-03-29 15:39:27 +00:00
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: MIT
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "level_zero/tools/source/debug/debug_session.h"
|
|
|
|
|
|
2023-12-05 21:03:49 +00:00
|
|
|
#include "shared/source/helpers/sleep.h"
|
2023-10-19 20:35:35 +00:00
|
|
|
#include "shared/source/os_interface/linux/drm_allocation.h"
|
|
|
|
|
#include "shared/source/os_interface/linux/drm_neo.h"
|
2023-12-05 21:03:49 +00:00
|
|
|
#include "shared/source/os_interface/linux/sys_calls.h"
|
2023-10-19 20:35:35 +00:00
|
|
|
|
2022-03-29 15:39:27 +00:00
|
|
|
#include "level_zero/core/source/device/device.h"
|
2023-10-23 23:35:40 +00:00
|
|
|
#include "level_zero/tools/source/debug/linux/debug_session.h"
|
2023-10-19 20:35:35 +00:00
|
|
|
#include "level_zero/tools/source/debug/linux/debug_session_factory.h"
|
2022-03-29 15:39:27 +00:00
|
|
|
|
|
|
|
|
namespace L0 {
|
2023-11-23 17:09:04 +00:00
|
|
|
DebugSessionLinuxAllocatorFn debugSessionLinuxFactory[DEBUG_SESSION_LINUX_TYPE_MAX] = {};
|
2022-03-29 15:39:27 +00:00
|
|
|
|
2022-09-23 14:56:32 +00:00
|
|
|
DebugSession *DebugSession::create(const zet_debug_config_t &config, Device *device, ze_result_t &result, bool isRootAttach) {
|
2023-10-19 20:35:35 +00:00
|
|
|
|
|
|
|
|
if (!device->getOsInterface().isDebugAttachAvailable()) {
|
|
|
|
|
result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
auto drm = device->getOsInterface().getDriverModel()->as<NEO::Drm>();
|
|
|
|
|
auto drmVersion = NEO::Drm::getDrmVersion(drm->getFileDescriptor());
|
|
|
|
|
|
|
|
|
|
DebugSessionLinuxAllocatorFn allocator = nullptr;
|
|
|
|
|
if ("xe" == drmVersion) {
|
2023-11-23 17:09:04 +00:00
|
|
|
allocator = debugSessionLinuxFactory[DEBUG_SESSION_LINUX_TYPE_XE];
|
2023-10-19 20:35:35 +00:00
|
|
|
} else {
|
2023-11-23 17:09:04 +00:00
|
|
|
allocator = debugSessionLinuxFactory[DEBUG_SESSION_LINUX_TYPE_I915];
|
2023-10-19 20:35:35 +00:00
|
|
|
}
|
2023-12-05 21:03:49 +00:00
|
|
|
UNRECOVERABLE_IF(!allocator)
|
2023-10-19 20:35:35 +00:00
|
|
|
|
|
|
|
|
auto debugSession = allocator(config, device, result, isRootAttach);
|
|
|
|
|
if (result != ZE_RESULT_SUCCESS) {
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
debugSession->setAttachMode(isRootAttach);
|
|
|
|
|
result = debugSession->initialize();
|
|
|
|
|
if (result != ZE_RESULT_SUCCESS) {
|
|
|
|
|
debugSession->closeConnection();
|
|
|
|
|
delete debugSession;
|
|
|
|
|
debugSession = nullptr;
|
|
|
|
|
} else {
|
|
|
|
|
debugSession->startAsyncThread();
|
|
|
|
|
}
|
|
|
|
|
return debugSession;
|
2022-03-29 15:39:27 +00:00
|
|
|
}
|
2023-10-23 23:35:40 +00:00
|
|
|
|
|
|
|
|
ze_result_t DebugSessionLinux::translateDebuggerOpenErrno(int error) {
|
|
|
|
|
|
|
|
|
|
ze_result_t result = ZE_RESULT_ERROR_UNKNOWN;
|
|
|
|
|
switch (error) {
|
|
|
|
|
case ENODEV:
|
|
|
|
|
result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
|
|
|
|
break;
|
|
|
|
|
case EBUSY:
|
|
|
|
|
result = ZE_RESULT_ERROR_NOT_AVAILABLE;
|
|
|
|
|
break;
|
|
|
|
|
case EACCES:
|
|
|
|
|
result = ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-05 21:03:49 +00:00
|
|
|
bool DebugSessionLinux::closeFd() {
|
|
|
|
|
if (fd == 0) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto ret = NEO::SysCalls::close(fd);
|
|
|
|
|
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
PRINT_DEBUGGER_ERROR_LOG("Debug connection close() on fd: %d failed: retCode: %d\n", fd, ret);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
fd = 0;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void *DebugSessionLinux::readInternalEventsThreadFunction(void *arg) {
|
|
|
|
|
DebugSessionLinux *self = reinterpret_cast<DebugSessionLinux *>(arg);
|
|
|
|
|
PRINT_DEBUGGER_INFO_LOG("Debugger internal event thread started\n", "");
|
|
|
|
|
self->internalThreadHasStarted = true;
|
|
|
|
|
|
|
|
|
|
while (self->internalEventThread.threadActive) {
|
|
|
|
|
self->readInternalEventsAsync();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PRINT_DEBUGGER_INFO_LOG("Debugger internal event thread closing\n", "");
|
|
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::unique_ptr<uint64_t[]> DebugSessionLinux::getInternalEvent() {
|
|
|
|
|
std::unique_ptr<uint64_t[]> eventMemory;
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
std::unique_lock<std::mutex> lock(internalEventThreadMutex);
|
|
|
|
|
|
|
|
|
|
if (internalEventQueue.empty()) {
|
|
|
|
|
NEO::waitOnCondition(internalEventCondition, lock, std::chrono::milliseconds(100));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!internalEventQueue.empty()) {
|
|
|
|
|
eventMemory = std::move(internalEventQueue.front());
|
|
|
|
|
internalEventQueue.pop();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return eventMemory;
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-18 18:39:41 +00:00
|
|
|
void DebugSessionLinux::closeAsyncThread() {
|
|
|
|
|
asyncThread.close();
|
|
|
|
|
internalEventThread.close();
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-29 15:39:27 +00:00
|
|
|
} // namespace L0
|