From 0f6a881acebd3977d09a594c5bd1954c075ae19f Mon Sep 17 00:00:00 2001 From: David Peixotto Date: Wed, 20 Aug 2025 16:12:16 -0700 Subject: [PATCH] [GPU][AMD] Refactor initialization code and delay connection This PR refactors the amdgpu plugin initialization logic to make it more flexible so that we can choose when to initialize the debug library separately from attaching the process and creating the connection. The change mostly shuffles around and cleans up existing code, but we now also explicitly track the state of the amd debug library (e.g. initialized, attached, runtime-initialized) so that we can use that to guide decisions around when to generate the debug connection. We also fixed the connection logic after the changes in f1343a4. It now delays the connection until after the initial stop that occurs for the native process when it first ptrace attaches. The initial stop does not handle the GPUActions so we need to wait for a later stop. I played with delaying the connection even further to when the rocm runtime is initialized. That works, but it makes it awkward to use the debugger to set gpu breakpoints. The runtime is initialized on demand so there is not always a good place to set a cpu breakpoint where we can halt the process and create the gpu breakpoints. If we change the debugger to propagate the breakpoints from the cpu to gpu then this will not be an issue because we can set the breakpoints before the gpu target is created. --- .../test/tools/gpu/amdgpu_testcase.py | 1 + .../Plugins/AMDGPU/LLDBServerPluginAMDGPU.cpp | 335 ++++++++++++------ .../Plugins/AMDGPU/LLDBServerPluginAMDGPU.h | 31 +- .../Plugins/AMDGPU/ProcessAMDGPU.cpp | 73 ++-- 4 files changed, 283 insertions(+), 157 deletions(-) diff --git a/lldb/packages/Python/lldbsuite/test/tools/gpu/amdgpu_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/gpu/amdgpu_testcase.py index f1602e2793031..b4731afc9c0fa 100644 --- a/lldb/packages/Python/lldbsuite/test/tools/gpu/amdgpu_testcase.py +++ b/lldb/packages/Python/lldbsuite/test/tools/gpu/amdgpu_testcase.py @@ -25,6 +25,7 @@ def run_to_gpu_breakpoint( self.assertEqual(cpu_target, self.cpu_target) # Switch to the GPU target so we can set a breakpoint. + self.assertTrue(self.gpu_target.IsValid()) self.select_gpu() # Set a breakpoint in the GPU source. diff --git a/lldb/tools/lldb-server/Plugins/AMDGPU/LLDBServerPluginAMDGPU.cpp b/lldb/tools/lldb-server/Plugins/AMDGPU/LLDBServerPluginAMDGPU.cpp index d94bb0b712e37..42ef81b80828a 100644 --- a/lldb/tools/lldb-server/Plugins/AMDGPU/LLDBServerPluginAMDGPU.cpp +++ b/lldb/tools/lldb-server/Plugins/AMDGPU/LLDBServerPluginAMDGPU.cpp @@ -13,9 +13,17 @@ #include "ThreadAMDGPU.h" #include "lldb/Host/common/TCPSocket.h" #include "lldb/Host/posix/ConnectionFileDescriptorPosix.h" +#include "lldb/Utility/GPUGDBRemotePackets.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Status.h" #include "llvm/Support/Error.h" +#include "llvm/Support/Threading.h" +#include "Plugins/Utils/Utils.h" +#include #include +#include +#include #include #include #include @@ -141,31 +149,45 @@ LLDBServerPluginAMDGPU::LLDBServerPluginAMDGPU( m_process_manager_up.reset(new ProcessManagerAMDGPU(main_loop)); m_gdb_server.reset(new GDBRemoteCommunicationServerLLGS( m_main_loop, *m_process_manager_up, "amd-gpu.server")); + + Status error = InitializeAmdDbgApi(); + if (error.Fail()) { + logAndReportFatalError("{} Failed to initialize debug library: {}", + __FUNCTION__, error); + } } LLDBServerPluginAMDGPU::~LLDBServerPluginAMDGPU() { } llvm::StringRef LLDBServerPluginAMDGPU::GetPluginName() { return "amd-gpu"; } -bool LLDBServerPluginAMDGPU::initRocm() { +Status LLDBServerPluginAMDGPU::InitializeAmdDbgApi() { + LLDB_LOGF(GetLog(GDBRLog::Plugin), "%s called", __FUNCTION__); + // Initialize AMD Debug API with callbacks amd_dbgapi_status_t status = amd_dbgapi_initialize(&s_dbgapi_callbacks); if (status != AMD_DBGAPI_STATUS_SUCCESS) { - LLDB_LOGF(GetLog(GDBRLog::Plugin), "Failed to initialize AMD debug API"); - exit(-1); + return Status::FromErrorStringWithFormat( + "Failed to initialize AMD debug API: %d", status); } + m_amd_dbg_api_state = AmdDbgApiState::Initialized; + return Status(); +} + +Status LLDBServerPluginAMDGPU::AttachAmdDbgApi() { + Log *log = GetLog(GDBRLog::Plugin); + LLDB_LOGF(log, "%s called", __FUNCTION__); // Attach to the process with AMD Debug API - status = amd_dbgapi_process_attach( + amd_dbgapi_status_t status = amd_dbgapi_process_attach( reinterpret_cast( this), // Use pid_ as client_process_id &m_gpu_pid); if (status != AMD_DBGAPI_STATUS_SUCCESS) { - LLDB_LOGF(GetLog(GDBRLog::Plugin), - "Failed to attach to process with AMD debug API: %d", status); - amd_dbgapi_finalize(); - return false; + return HandleAmdDbgApiAttachError( + "Failed to attach to process with AMD debug API", status); } + m_amd_dbg_api_state = AmdDbgApiState::Attached; // Get the process notifier status = @@ -173,19 +195,39 @@ bool LLDBServerPluginAMDGPU::initRocm() { sizeof(m_notifier_fd), &m_notifier_fd); if (status != AMD_DBGAPI_STATUS_SUCCESS) { - LLDB_LOGF(GetLog(GDBRLog::Plugin), "Failed to get process notifier: %d", - status); - amd_dbgapi_process_detach(m_gpu_pid); - amd_dbgapi_finalize(); - return false; + return HandleAmdDbgApiAttachError("Failed to get process notifier", status); + } + LLDB_LOGF(log, "Process notifier fd: %d", m_notifier_fd); + + Status error = InstallAmdDbgApiNotifierOnMainLoop(); + if (error.Fail()) { + return HandleAmdDbgApiAttachError(error.AsCString(), + AMD_DBGAPI_STATUS_ERROR); + } + + // TODO: read the architecture from the attached agent. + amd_dbgapi_architecture_id_t architecture_id; + const uint32_t elf_amdgpu_machine = 0x04C; + status = amd_dbgapi_get_architecture(elf_amdgpu_machine, &architecture_id); + if (status != AMD_DBGAPI_STATUS_SUCCESS) { + return HandleAmdDbgApiAttachError("Failed to get architecture", status); } + m_architecture_id = architecture_id; - // event_handler_.addNotifierFd(m_notifier_fd); - LLDB_LOGF(GetLog(GDBRLog::Plugin), "Process notifier fd: %d", m_notifier_fd); + // The process from LLDB’s PoV is the entire portion of logical GPU bound to + // the CPU host process. It does not represent a real process on the GPU. The + // The GPU process is fake and shouldn't fail to launch. Let's abort if we see + // an error. + error = CreateGpuProcess(); + if (error.Fail()) { + return HandleAmdDbgApiAttachError(error.AsCString(), + AMD_DBGAPI_STATUS_ERROR); + } + // Process all pending events + LLDB_LOGF(log, "%s Processing any pending dbgapi events", __FUNCTION__); amd_dbgapi_event_id_t eventId; amd_dbgapi_event_kind_t eventKind; - // Process all pending events if (amd_dbgapi_process_next_pending_event(m_gpu_pid, &eventId, &eventKind) == AMD_DBGAPI_STATUS_SUCCESS) { GetGPUProcess()->handleDebugEvent(eventId, eventKind); @@ -194,17 +236,58 @@ bool LLDBServerPluginAMDGPU::initRocm() { amd_dbgapi_event_processed(eventId); } - amd_dbgapi_architecture_id_t architecture_id; - // TODO: do not hardcode the device id - status = amd_dbgapi_get_architecture(0x04C, &architecture_id); + LLDB_LOGF(log, "%s successfully attached to debug library", __FUNCTION__); + return Status(); +} + +Status +LLDBServerPluginAMDGPU::HandleAmdDbgApiAttachError(llvm::StringRef error_msg, + amd_dbgapi_status_t status) { + Log *log = GetLog(GDBRLog::Plugin); + LLDB_LOGF(log, "%s called", __FUNCTION__); + // Cleanup any partial initialization + if (m_amd_dbg_api_state == AmdDbgApiState::Attached) { + Status error = DetachAmdDbgApi(); + if (error.Fail()) { + LLDB_LOGF(log, "%s: failed DetachAmdDbgApi: %s", __FUNCTION__, + error.AsCString()); + } + } + + // Finalize the AMD Debug API + amd_dbgapi_status_t finalize_status = amd_dbgapi_finalize(); + if (finalize_status != AMD_DBGAPI_STATUS_SUCCESS) { + LLDB_LOGF(GetLog(GDBRLog::Plugin), "amd_dbgapi_finalize failed: %d", + finalize_status); + } + + // Reset the state to error state + m_amd_dbg_api_state = AmdDbgApiState::Error; + + // Return a status with the error message and additional context + return Status::FromErrorStringWithFormat( + "AMD Debug API attach failed: %s (status: %d)", error_msg.data(), status); +} + +Status LLDBServerPluginAMDGPU::DetachAmdDbgApi() { + LLDB_LOGF(GetLog(GDBRLog::Plugin), "%s called", __FUNCTION__); + + if (m_amd_dbg_api_state == AmdDbgApiState::Detached) { + LLDB_LOGF(GetLog(GDBRLog::Plugin), "%s -- already detached from process", + __FUNCTION__); + return Status(); + } + + amd_dbgapi_status_t status = amd_dbgapi_process_detach(m_gpu_pid); if (status != AMD_DBGAPI_STATUS_SUCCESS) { - // Handle error - LLDB_LOGF(GetLog(GDBRLog::Plugin), "amd_dbgapi_get_architecture failed"); - return false; + return Status::FromErrorStringWithFormat( + "Failed to detach from process: %d", status); } - m_architecture_id = architecture_id; + m_gpu_pid = AMD_DBGAPI_PROCESS_NONE; + m_notifier_fd = INVALID_NOTIFIER_ID; - return true; + m_amd_dbg_api_state = AmdDbgApiState::Detached; + return Status(); } bool LLDBServerPluginAMDGPU::processGPUEvent() { @@ -292,6 +375,7 @@ LLDBServerPluginAMDGPU::CreateConnection() { llvm::toString(res.takeError()).c_str()); } + connection_info.synchronous = true; return connection_info; } else { std::string error = llvm::toString(sock.takeError()); @@ -302,84 +386,118 @@ LLDBServerPluginAMDGPU::CreateConnection() { return std::nullopt; } +Status LLDBServerPluginAMDGPU::InstallAmdDbgApiNotifierOnMainLoop() { + Status error; + LLDBServerPluginAMDGPU *amdGPUPlugin = this; + m_gpu_event_io_obj_sp = std::make_shared(m_notifier_fd); + m_gpu_event_read_up = m_main_loop.RegisterReadObject( + m_gpu_event_io_obj_sp, + [amdGPUPlugin](MainLoopBase &) { + amdGPUPlugin->HandleEventFileDescriptorEvent( + amdGPUPlugin->m_notifier_fd); + }, + error); + return error; +} + +Status LLDBServerPluginAMDGPU::CreateGpuProcess() { + ProcessManagerAMDGPU *manager = + (ProcessManagerAMDGPU *)m_process_manager_up.get(); + manager->m_debugger = this; + + // During initialization, there might be no code objects loaded, so we don't + // have anything tangible to use as the identifier or file for the GPU + // process. Thus, we create a fake process and we pretend we just launched it. + Log *log = GetLog(GDBRLog::Plugin); + LLDB_LOGF(log, "%s faking launch...", __FUNCTION__); + ProcessLaunchInfo info; + info.GetFlags().Set(eLaunchFlagStopAtEntry | eLaunchFlagDebug | + eLaunchFlagDisableASLR); + Args args; + args.AppendArgument("/pretend/path/to/amdgpu"); + info.SetArguments(args, true); + info.GetEnvironment() = Host::GetEnvironment(); + info.SetProcessID(m_gpu_pid.handle); + m_gdb_server->SetLaunchInfo(info); + + return m_gdb_server->LaunchProcess(); +} + +bool LLDBServerPluginAMDGPU::ReadyToSendConnectionRequest() { + // We are ready to send a connection request if we are attached to the debug + // library and we have not yet sent a connection request. + // The GPUActions are ignored on the initial stop when the process is first + // launched so we wait until the second stop to send the connection request. + const bool ready = m_amd_dbg_api_state == AmdDbgApiState::Attached && + !m_is_connected && !m_is_listening && + GetNativeProcess()->GetStopID() > 1; + + LLDB_LOGF(GetLog(GDBRLog::Plugin), + "%s - ready: %d dbg_api_state: %d, connected: %d, listening: %d, " + "native-stop-id: %d", + __FUNCTION__, ready, (int)m_amd_dbg_api_state, m_is_connected, + m_is_listening, GetNativeProcess()->GetStopID()); + return ready; +} + +bool LLDBServerPluginAMDGPU::ReadyToAttachDebugLibrary() { + return m_amd_dbg_api_state == AmdDbgApiState::Initialized; +} + +bool LLDBServerPluginAMDGPU::ReadyToSetGpuLoaderBreakpointByAddress() { + return m_wait_for_gpu_internal_bp_stop && m_gpu_internal_bp.has_value(); +} + +GPUActions LLDBServerPluginAMDGPU::SetConnectionInfo() { + GPUActions actions; + actions.plugin_name = GetPluginName(); + actions.connect_info = CreateConnection(); + return actions; +} + +GPUActions LLDBServerPluginAMDGPU::SetGpuLoaderBreakpointByAddress() { + Log *log = GetLog(GDBRLog::Plugin); + LLDB_LOGF(log, "%s Requesting gpu breakpoint at 0x%p", __FUNCTION__, + (void *)m_gpu_internal_bp->addr); + assert(!kSetDbgApiBreakpointByName); + GPUActions actions; + actions.plugin_name = GetPluginName(); + + GPUBreakpointByAddress bp_addr; + bp_addr.load_address = m_gpu_internal_bp->addr; + + GPUBreakpointInfo bp; + bp.identifier = kGpuLoaderBreakpointIdentifier; + bp.addr_info.emplace(bp_addr); + + std::vector breakpoints; + breakpoints.emplace_back(std::move(bp)); + + actions.breakpoints = std::move(breakpoints); + m_wait_for_gpu_internal_bp_stop = false; + return actions; +} + std::optional LLDBServerPluginAMDGPU::NativeProcessIsStopping() { Log *log = GetLog(GDBRLog::Plugin); - if (!m_is_connected) { - initRocm(); - ProcessManagerAMDGPU *manager = - (ProcessManagerAMDGPU *)m_process_manager_up.get(); - manager->m_debugger = this; - - GPUActions actions; - actions.plugin_name = GetPluginName(); - - Status error; - LLDBServerPluginAMDGPU *amdGPUPlugin = this; - m_gpu_event_io_obj_sp = std::make_shared(m_notifier_fd); - m_gpu_event_read_up = m_main_loop.RegisterReadObject( - m_gpu_event_io_obj_sp, - [amdGPUPlugin](MainLoopBase &) { - amdGPUPlugin->HandleEventFileDescriptorEvent( - amdGPUPlugin->m_notifier_fd); - }, - error); + LLDB_LOGF(log, "%s called", __FUNCTION__); + + if (ReadyToAttachDebugLibrary()) { + Status error = AttachAmdDbgApi(); if (error.Fail()) { - LLDB_LOGF(log, "LLDBServerPluginAMDGPU::NativeProcessIsStopping() failed " - "to RegisterReadObject"); - // TODO: how to report this error? - } else { - LLDB_LOGF( - log, - "LLDBServerPluginAMDGPU::LLDBServerPluginAMDGPU() faking launch..."); - ProcessLaunchInfo info; - info.GetFlags().Set(eLaunchFlagStopAtEntry | eLaunchFlagDebug | - eLaunchFlagDisableASLR); - Args args; - args.AppendArgument("/pretend/path/to/amdgpu"); - args.AppendArgument("--option1"); - args.AppendArgument("--option2"); - args.AppendArgument("--option3"); - info.SetArguments(args, true); - info.GetEnvironment() = Host::GetEnvironment(); - info.SetProcessID(m_gpu_pid.handle); - m_gdb_server->SetLaunchInfo(info); - Status error = m_gdb_server->LaunchProcess(); - if (error.Fail()) { - LLDB_LOGF(log, - "LLDBServerPluginAMDGPU::LLDBServerPluginAMDGPU() failed to " - "launch: %s", - error.AsCString()); - } else { - LLDB_LOGF(log, "LLDBServerPluginAMDGPU::LLDBServerPluginAMDGPU() " - "launched successfully"); - } - actions.connect_info = CreateConnection(); - actions.connect_info->synchronous = true; - } - return actions; - } else { - if (m_wait_for_gpu_internal_bp_stop && m_gpu_internal_bp.has_value()) { - LLDB_LOGF(GetLog(GDBRLog::Plugin), "Please set gpu breakpoint at 0x%p", - (void *)m_gpu_internal_bp->addr); - assert(!kSetDbgApiBreakpointByName); - GPUActions actions; - actions.plugin_name = GetPluginName(); - - GPUBreakpointByAddress bp_addr; - bp_addr.load_address = m_gpu_internal_bp->addr; - - GPUBreakpointInfo bp; - bp.identifier = kGpuLoaderBreakpointIdentifier; - bp.addr_info.emplace(bp_addr); - - std::vector breakpoints; - breakpoints.emplace_back(std::move(bp)); - - actions.breakpoints = std::move(breakpoints); - m_wait_for_gpu_internal_bp_stop = false; - return actions; + LLDB_LOGF(log, "%s failed to attach debug library: %s", __FUNCTION__, + error.AsCString()); + return std::nullopt; } } + + if (ReadyToSendConnectionRequest()) { + return SetConnectionInfo(); + } + + if (ReadyToSetGpuLoaderBreakpointByAddress()) { + return SetGpuLoaderBreakpointByAddress(); + } return std::nullopt; } @@ -449,6 +567,17 @@ void LLDBServerPluginAMDGPU::FreeDbgApiClientMemory(void *mem) { s_dbgapi_callbacks.deallocate_memory(mem); } +void LLDBServerPluginAMDGPU::GpuRuntimeDidLoad() { + Log *log = GetLog(GDBRLog::Plugin); + LLDB_LOGF(log, "%s called", __FUNCTION__); + if (m_amd_dbg_api_state == AmdDbgApiState::RuntimeLoaded) { + LLDB_LOGF(log, "%s -- runtime loaded event already handled", __FUNCTION__); + return; + } + + m_amd_dbg_api_state = AmdDbgApiState::RuntimeLoaded; +} + bool LLDBServerPluginAMDGPU::SetGPUBreakpoint(uint64_t addr, const uint8_t *bp_instruction, size_t size) { @@ -549,14 +678,18 @@ LLDBServerPluginAMDGPU::BreakpointWasHit(GPUPluginBreakpointHitArgs &args) { return llvm::createStringError( "Breakpoint address does not match expected value from ROCdbgapi"); } + bool success = HandleGPUInternalBreakpointHit(m_gpu_internal_bp.value()); assert(success); if (GetGPUProcess()->HasDyldChangesToReport()) { - response.actions.wait_for_gpu_process_to_resume = true; auto *process = m_gdb_server->GetCurrentProcess(); - ThreadAMDGPU *thread = (ThreadAMDGPU *)process->GetCurrentThread(); - thread->SetStopReason(lldb::eStopReasonDynamicLoader); - process->Halt(); + if (process->IsRunning()) { + response.actions.wait_for_gpu_process_to_resume = true; + response.actions.stop_id = GetGPUProcess()->GetNextStopID(); + ThreadAMDGPU *thread = (ThreadAMDGPU *)process->GetCurrentThread(); + thread->SetStopReason(lldb::eStopReasonDynamicLoader); + process->Halt(); + } } } return response; diff --git a/lldb/tools/lldb-server/Plugins/AMDGPU/LLDBServerPluginAMDGPU.h b/lldb/tools/lldb-server/Plugins/AMDGPU/LLDBServerPluginAMDGPU.h index 134b4518b5da3..ce62f2e88a1a0 100644 --- a/lldb/tools/lldb-server/Plugins/AMDGPU/LLDBServerPluginAMDGPU.h +++ b/lldb/tools/lldb-server/Plugins/AMDGPU/LLDBServerPluginAMDGPU.h @@ -10,10 +10,12 @@ #define LLDB_TOOLS_LLDB_SERVER_LLDBSERVERPLUGINAMDGPU_H #include "Plugins/Process/gdb-remote/LLDBServerPlugin.h" +#include "lldb/Utility/GPUGDBRemotePackets.h" #include "lldb/Utility/Status.h" #include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h" #include "ProcessAMDGPU.h" +#include "llvm/ADT/StringRef.h" #include namespace lldb_private { @@ -71,6 +73,8 @@ class LLDBServerPluginAMDGPU : public LLDBServerPlugin { bool CreateGPUBreakpoint(uint64_t addr); + void GpuRuntimeDidLoad(); + // TODO: make this private struct GPUInternalBreakpoinInfo { uint64_t addr; @@ -81,17 +85,26 @@ class LLDBServerPluginAMDGPU : public LLDBServerPlugin { amd_dbgapi_architecture_id_t m_architecture_id = AMD_DBGAPI_ARCHITECTURE_NONE; private: + Status InitializeAmdDbgApi(); + Status AttachAmdDbgApi(); + Status DetachAmdDbgApi(); + Status InstallAmdDbgApiNotifierOnMainLoop(); + Status CreateGpuProcess(); std::optional CreateConnection(); - void CloseFDs(); - void AcceptAndMainLoopThread(std::unique_ptr listen_socket_up); + GPUActions SetGpuLoaderBreakpointByAddress(); + GPUActions SetConnectionInfo(); + Status HandleAmdDbgApiAttachError(llvm::StringRef error_msg, + amd_dbgapi_status_t status); - bool initRocm(); bool HandleGPUInternalBreakpointHit(const GPUInternalBreakpoinInfo &bp); amd_dbgapi_event_id_t process_event_queue(amd_dbgapi_event_kind_t until_event_kind); bool processGPUEvent(); bool SetGPUBreakpoint(uint64_t addr, const uint8_t *bp_instruction, size_t size); + bool ReadyToAttachDebugLibrary(); + bool ReadyToSendConnectionRequest(); + bool ReadyToSetGpuLoaderBreakpointByAddress(); Status m_main_loop_status; MainLoopBase::ReadHandleUP m_gpu_event_read_up; @@ -100,7 +113,17 @@ class LLDBServerPluginAMDGPU : public LLDBServerPlugin { std::shared_ptr m_gpu_event_io_obj_sp; amd_dbgapi_process_id_t m_gpu_pid = AMD_DBGAPI_PROCESS_NONE; - int m_notifier_fd = -1; + static constexpr int INVALID_NOTIFIER_ID = -1; + int m_notifier_fd = INVALID_NOTIFIER_ID; + enum class AmdDbgApiState { + Uninitialized, + Initialized, + Attached, + RuntimeLoaded, + Detached, + Error, + }; + AmdDbgApiState m_amd_dbg_api_state = AmdDbgApiState::Uninitialized; }; } // namespace lldb_server diff --git a/lldb/tools/lldb-server/Plugins/AMDGPU/ProcessAMDGPU.cpp b/lldb/tools/lldb-server/Plugins/AMDGPU/ProcessAMDGPU.cpp index 67a081021910c..064ede4094719 100644 --- a/lldb/tools/lldb-server/Plugins/AMDGPU/ProcessAMDGPU.cpp +++ b/lldb/tools/lldb-server/Plugins/AMDGPU/ProcessAMDGPU.cpp @@ -38,9 +38,6 @@ Status ProcessAMDGPU::Resume(const ResumeActionList &resume_actions) { SetState(StateType::eStateRunning, true); ThreadAMDGPU *thread = (ThreadAMDGPU *)GetCurrentThread(); thread->GetRegisterContext().InvalidateAllRegisters(); - // if (!m_debugger->resume_process()) { - // return Status::FromErrorString("resume_process failed"); - // } return Status(); } @@ -92,7 +89,6 @@ size_t ProcessAMDGPU::UpdateThreads() { if (m_threads.empty()) { lldb::tid_t tid = 3456; m_threads.push_back(std::make_unique(*this, 3456)); - // ThreadAMDGPU &thread = static_cast(*m_threads.back()); SetCurrentThreadID(tid); } return m_threads.size(); @@ -288,7 +284,6 @@ bool ProcessAMDGPU::handleWaveStop(amd_dbgapi_event_id_t eventId) { return false; } if ((stop_reason & AMD_DBGAPI_WAVE_STOP_REASON_BREAKPOINT) != 0) { - // auto ip = getPC(); uint64_t pc; status = amd_dbgapi_wave_get_info(wave_id, AMD_DBGAPI_WAVE_INFO_PC, sizeof(pc), &pc); @@ -314,9 +309,6 @@ bool ProcessAMDGPU::handleWaveStop(amd_dbgapi_event_id_t eventId) { status); exit(-1); } - // RemoveGPUBreakpoint(pc); - // auto thread = std::make_unique(*this, wave_id.handle, - // wave_id); thread->SetStopReason(lldb::eStopReasonBreakpoint); m_wave_ids.emplace_back(wave_id); if (m_threads.size() == 1 && m_gpu_state == State::Initializing) { @@ -371,28 +363,6 @@ bool ProcessAMDGPU::handleDebugEvent(amd_dbgapi_event_id_t eventId, if (eventKind == AMD_DBGAPI_EVENT_KIND_NONE) return result; - amd_dbgapi_runtime_state_t runtimeState = AMD_DBGAPI_RUNTIME_STATE_UNLOADED; - - // Get runtime state for the event - amd_dbgapi_status_t status = - amd_dbgapi_event_get_info(eventId, AMD_DBGAPI_EVENT_INFO_RUNTIME_STATE, - sizeof(runtimeState), &runtimeState); - - if (status == AMD_DBGAPI_STATUS_SUCCESS) { - // Handle different runtime states - switch (runtimeState) { - case AMD_DBGAPI_RUNTIME_STATE_LOADED_SUCCESS: - LLDB_LOGF(GetLog(GDBRLog::Plugin), "Runtime loaded successfully"); - break; - case AMD_DBGAPI_RUNTIME_STATE_LOADED_ERROR_RESTRICTION: - LLDB_LOGF(GetLog(GDBRLog::Plugin), "Runtime load restricted"); - break; - case AMD_DBGAPI_RUNTIME_STATE_UNLOADED: - LLDB_LOGF(GetLog(GDBRLog::Plugin), "Runtime unloaded"); - break; - } - } - // Handle event kinds switch (eventKind) { case AMD_DBGAPI_EVENT_KIND_WAVE_STOP: { @@ -404,29 +374,28 @@ bool ProcessAMDGPU::handleDebugEvent(amd_dbgapi_event_id_t eventId, break; } - // case AMD_DBGAPI_EVENT_KIND_BREAKPOINT: { - // std::cout << "Breakpoint event received" << std::endl; - - // // Get breakpoint information for this event - // amd_dbgapi_breakpoint_id_t breakpointId; - // if (amd_dbgapi_event_get_info(eventId, - // AMD_DBGAPI_EVENT_INFO_BREAKPOINT, - // sizeof(breakpointId), &breakpointId) - // == - // AMD_DBGAPI_STATUS_SUCCESS) { - // std::cout << "Breakpoint ID: " << breakpointId << std::endl; - // } - // break; - // } - case AMD_DBGAPI_EVENT_KIND_RUNTIME: { - LLDB_LOGF(GetLog(GDBRLog::Plugin), - "Runtime event received, runtimeState: %d", runtimeState); - - // Additional runtime-specific handling based on state - if (runtimeState == AMD_DBGAPI_RUNTIME_STATE_LOADED_SUCCESS) { - // Runtime is now loaded, we can set breakpoints or perform other - // initialization + LLDB_LOGF(GetLog(GDBRLog::Plugin), "Runtime event received."); + // Get runtime state for the event + amd_dbgapi_runtime_state_t runtimeState = AMD_DBGAPI_RUNTIME_STATE_UNLOADED; + amd_dbgapi_status_t status = + amd_dbgapi_event_get_info(eventId, AMD_DBGAPI_EVENT_INFO_RUNTIME_STATE, + sizeof(runtimeState), &runtimeState); + + if (status == AMD_DBGAPI_STATUS_SUCCESS) { + // Handle different runtime states + switch (runtimeState) { + case AMD_DBGAPI_RUNTIME_STATE_LOADED_SUCCESS: + LLDB_LOGF(GetLog(GDBRLog::Plugin), "Runtime loaded successfully"); + m_debugger->GpuRuntimeDidLoad(); + break; + case AMD_DBGAPI_RUNTIME_STATE_LOADED_ERROR_RESTRICTION: + LLDB_LOGF(GetLog(GDBRLog::Plugin), "Runtime load restricted"); + break; + case AMD_DBGAPI_RUNTIME_STATE_UNLOADED: + LLDB_LOGF(GetLog(GDBRLog::Plugin), "Runtime unloaded"); + break; + } } break; }