diff --git a/lldb/include/lldb/Utility/GPUGDBRemotePackets.h b/lldb/include/lldb/Utility/GPUGDBRemotePackets.h index 437c993dc0b64..e261331d94a0c 100644 --- a/lldb/include/lldb/Utility/GPUGDBRemotePackets.h +++ b/lldb/include/lldb/Utility/GPUGDBRemotePackets.h @@ -177,13 +177,13 @@ llvm::json::Value toJSON(const GPUPluginConnectionInfo &data); ///----------------------------------------------------------------------------- struct GPUActions { GPUActions() = default; - GPUActions(llvm::StringRef _plugin_name) : - plugin_name(_plugin_name) {} - GPUActions(llvm::StringRef _plugin_name, uint32_t _stop_id) : - plugin_name(_plugin_name), stop_id(_stop_id) {} + GPUActions(llvm::StringRef plugin_name, uint32_t gpu_action_id) + : plugin_name(plugin_name), identifier(gpu_action_id) {} /// The name of the plugin. std::string plugin_name; + /// Unique identifier for every GPU action. + uint32_t identifier = 0; /// The stop ID in the process that this action is associated with. If the /// wait_for_gpu_process_to_stop is true, this stop ID will be used to wait /// for. If the wait_for_gpu_process_to_resume is set to true it will wait @@ -284,8 +284,8 @@ llvm::json::Value toJSON(const GPUDynamicLoaderLibraryInfo &data); ///----------------------------------------------------------------------------- struct GPUPluginBreakpointHitResponse { GPUPluginBreakpointHitResponse() = default; - GPUPluginBreakpointHitResponse(llvm::StringRef plugin_name, uint32_t stop_id) - : actions(plugin_name, stop_id) {} + GPUPluginBreakpointHitResponse(GPUActions gpu_actions) + : actions(std::move(gpu_actions)) {} ///< Set to true if this berakpoint should be disabled. bool disable_bp = false; diff --git a/lldb/source/Plugins/Process/gdb-remote/LLDBServerPlugin.h b/lldb/source/Plugins/Process/gdb-remote/LLDBServerPlugin.h index a5c98ce26c177..d048350643d5c 100644 --- a/lldb/source/Plugins/Process/gdb-remote/LLDBServerPlugin.h +++ b/lldb/source/Plugins/Process/gdb-remote/LLDBServerPlugin.h @@ -40,6 +40,7 @@ class LLDBServerPlugin { std::unique_ptr m_gdb_server; bool m_is_listening = false; bool m_is_connected = false; + uint32_t m_gpu_action_identifier = 0; public: LLDBServerPlugin(GDBServer &native_process, MainLoop &main_loop); @@ -48,6 +49,11 @@ class LLDBServerPlugin { /// Check if we are already connected. bool IsConnected() const { return m_is_connected; } + /// Create a new GPUActions with the next unique identifier and plugin name. + GPUActions GetNewGPUAction() { + return GPUActions(GetPluginName(), ++m_gpu_action_identifier); + } + virtual llvm::StringRef GetPluginName() = 0; /// Stop the native process if it is running. diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 77b78de01ffc6..a8f30ffbc0ed0 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -934,20 +934,21 @@ Status ProcessGDBRemote::HandleGPUActions(const GPUActions &gpu_action) { } // This is the CPU process. - uint32_t current_stop_id = GetStopID(); auto it = m_processed_gpu_actions.find(gpu_action.plugin_name); - if (it != m_processed_gpu_actions.end() && it->second == current_stop_id) { - LLDB_LOG(log, - "ProcessGDBRemote::HandleGPUActions skipping already " - "processed GPU actions for plugin '{0}' with process stop_id {1}", - gpu_action.plugin_name, current_stop_id); + if (it != m_processed_gpu_actions.end() && + it->second == gpu_action.identifier) { + LLDB_LOG( + log, + "ProcessGDBRemote::HandleGPUActions skipping already " + "processed GPU actions for plugin '{0}' with gpu_action_identifier {1}", + gpu_action.plugin_name, gpu_action.identifier); return Status(); } - m_processed_gpu_actions[gpu_action.plugin_name] = current_stop_id; + m_processed_gpu_actions[gpu_action.plugin_name] = gpu_action.identifier; LLDB_LOG(log, "ProcessGDBRemote::HandleGPUActions processing GPU actions " - "for plugin '{0}' with process stop_id {1}", - gpu_action.plugin_name, current_stop_id); + "for plugin '{0}' with gpu_action_identifier {1}", + gpu_action.plugin_name, gpu_action.identifier); Status error; if (!gpu_action.breakpoints.empty()) HandleGPUBreakpoints(gpu_action); diff --git a/lldb/source/Utility/GPUGDBRemotePackets.cpp b/lldb/source/Utility/GPUGDBRemotePackets.cpp index 8e2d638cc58c6..61b62112a084c 100644 --- a/lldb/source/Utility/GPUGDBRemotePackets.cpp +++ b/lldb/source/Utility/GPUGDBRemotePackets.cpp @@ -143,11 +143,12 @@ bool fromJSON(const llvm::json::Value &value, GPUActions &data, llvm::json::Path path) { ObjectMapper o(value, path); return o && o.map("plugin_name", data.plugin_name) && + o.map("identifier", data.identifier) && o.mapOptional("stop_id", data.stop_id) && o.map("breakpoints", data.breakpoints) && o.mapOptional("connect_info", data.connect_info) && o.map("wait_for_gpu_process_to_stop", - data.wait_for_gpu_process_to_stop) && + data.wait_for_gpu_process_to_stop) && o.map("load_libraries", data.load_libraries) && o.map("resume_gpu_process", data.resume_gpu_process) && o.map("wait_for_gpu_process_to_resume", @@ -155,8 +156,19 @@ bool fromJSON(const llvm::json::Value &value, GPUActions &data, } llvm::json::Value toJSON(const GPUActions &data) { + // Fatal if identifier is 0 - this indicates the GPUActions was not properly + // initialized with a valid identifier. + // GPU plugins should initialize their GPUActions objects by calling: + // GPUActions actions = GetNewGPUAction(); + // This method automatically fills in the plugin_name and assigns a unique + // identifier that ensures each action can be tracked and prevents duplicate + // processing. + assert(data.identifier != 0 && + "GPUActions identifier must be set before serialization"); + return json::Value(Object{ {"plugin_name", data.plugin_name}, + {"identifier", data.identifier}, {"stop_id", data.stop_id}, {"breakpoints", data.breakpoints}, {"connect_info", data.connect_info}, diff --git a/lldb/tools/lldb-server/Plugins/AMDGPU/LLDBServerPluginAMDGPU.cpp b/lldb/tools/lldb-server/Plugins/AMDGPU/LLDBServerPluginAMDGPU.cpp index 5e2376f043055..f24b89850fecf 100644 --- a/lldb/tools/lldb-server/Plugins/AMDGPU/LLDBServerPluginAMDGPU.cpp +++ b/lldb/tools/lldb-server/Plugins/AMDGPU/LLDBServerPluginAMDGPU.cpp @@ -668,8 +668,7 @@ LLDBServerPluginAMDGPU::BreakpointWasHit(GPUPluginBreakpointHitArgs &args) { LLDB_LOGF(log, "LLDBServerPluginAMDGPU::BreakpointWasHit(\"%d\"):\nJSON:\n%s", bp_identifier, json_string.c_str()); - GPUPluginBreakpointHitResponse response; - response.actions.plugin_name = GetPluginName(); + GPUPluginBreakpointHitResponse response(GetNewGPUAction()); if (bp_identifier == kGpuLoaderBreakpointIdentifier) { // Make sure the breakpoint address matches the expected value when we set // it by name. diff --git a/lldb/tools/lldb-server/Plugins/MockGPU/LLDBServerPluginMockGPU.cpp b/lldb/tools/lldb-server/Plugins/MockGPU/LLDBServerPluginMockGPU.cpp index ff3809c9add5f..19d1351ed6907 100644 --- a/lldb/tools/lldb-server/Plugins/MockGPU/LLDBServerPluginMockGPU.cpp +++ b/lldb/tools/lldb-server/Plugins/MockGPU/LLDBServerPluginMockGPU.cpp @@ -154,8 +154,7 @@ std::optional LLDBServerPluginMockGPU::NativeProcessIsStopping() { NativeProcessProtocol *native_process = m_native_process.GetCurrentProcess(); // Show that we can return a valid GPUActions object from a stop event. if (native_process->GetStopID() == 3) { - GPUActions actions; - actions.plugin_name = GetPluginName(); + GPUActions actions = GetNewGPUAction(); GPUBreakpointInfo bp; bp.identifier = BreakpointIDThirdStop; bp.name_info = {"a.out", "gpu_third_stop"}; @@ -177,8 +176,7 @@ LLDBServerPluginMockGPU::BreakpointWasHit(GPUPluginBreakpointHitArgs &args) { bp_identifier, json_string.c_str()); } NativeProcessProtocol *gpu_process = m_gdb_server->GetCurrentProcess(); - GPUPluginBreakpointHitResponse response(GetPluginName(), - gpu_process->GetStopID()); + GPUPluginBreakpointHitResponse response(GetNewGPUAction()); if (bp_identifier == BreakpointIDInitialize) { response.disable_bp = true; LLDB_LOGF(log, "LLDBServerPluginMockGPU::BreakpointWasHit(%u) disabling breakpoint", @@ -224,8 +222,7 @@ LLDBServerPluginMockGPU::BreakpointWasHit(GPUPluginBreakpointHitArgs &args) { } GPUActions LLDBServerPluginMockGPU::GetInitializeActions() { - GPUActions init_actions; - init_actions.plugin_name = GetPluginName(); + GPUActions init_actions = GetNewGPUAction(); { GPUBreakpointInfo bp; bp.identifier = BreakpointIDInitialize;