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