diff --git a/lldb/include/lldb/Host/common/NativeProcessProtocol.h b/lldb/include/lldb/Host/common/NativeProcessProtocol.h index 5ef9f14c5ab3c..82a8458c7c069 100644 --- a/lldb/include/lldb/Host/common/NativeProcessProtocol.h +++ b/lldb/include/lldb/Host/common/NativeProcessProtocol.h @@ -301,8 +301,6 @@ class NativeProcessProtocol { return std::nullopt; }; - - /// Extension flag constants, returned by Manager::GetSupportedExtensions() /// and passed to SetEnabledExtension() enum class Extension { diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp index 4bc3c31ea80c3..5e8b4b3f46694 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp @@ -1140,6 +1140,12 @@ void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Exited( Log *log = GetLog(LLDBLog::Process); LLDB_LOGF(log, "GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__); + // Notify GPU plugins that the native process has exited + std::optional exit_status = process->GetExitStatus(); + if (exit_status.has_value()) + for (std::unique_ptr &plugin_up : m_plugins) + plugin_up->NativeProcessDidExit(*exit_status); + PacketResult result = SendStopReasonForState( *process, StateType::eStateExited, /*force_synchronous=*/false); if (result != PacketResult::Success) { diff --git a/lldb/source/Plugins/Process/gdb-remote/LLDBServerPlugin.h b/lldb/source/Plugins/Process/gdb-remote/LLDBServerPlugin.h index a5c98ce26c177..8a692f0ffe59e 100644 --- a/lldb/source/Plugins/Process/gdb-remote/LLDBServerPlugin.h +++ b/lldb/source/Plugins/Process/gdb-remote/LLDBServerPlugin.h @@ -82,6 +82,14 @@ class LLDBServerPlugin { return std::nullopt; }; + /// Get the GPU plug-in notified when the native process exits. + /// + /// This function will get called when the native process exits. This allows + /// GPU plugins to perform proper termination. + /// + /// \param[in] exit_status The exit status of the native process. + virtual void NativeProcessDidExit(const WaitStatus &exit_status) = 0; + /// Get the GPU plug-in initialization actions. /// /// Each GPU plugin can return a structure that describes the GPU plug-in and diff --git a/lldb/tools/lldb-server/Plugins/AMDGPU/LLDBServerPluginAMDGPU.cpp b/lldb/tools/lldb-server/Plugins/AMDGPU/LLDBServerPluginAMDGPU.cpp index d94bb0b712e37..5cb44f1b2e0a8 100644 --- a/lldb/tools/lldb-server/Plugins/AMDGPU/LLDBServerPluginAMDGPU.cpp +++ b/lldb/tools/lldb-server/Plugins/AMDGPU/LLDBServerPluginAMDGPU.cpp @@ -562,6 +562,13 @@ LLDBServerPluginAMDGPU::BreakpointWasHit(GPUPluginBreakpointHitArgs &args) { return response; } +void LLDBServerPluginAMDGPU::NativeProcessDidExit(const WaitStatus &exit_status) { + // Bare bones implementation for exit behavior if GPU process exits. + ProcessAMDGPU *gpu_process = GetGPUProcess(); + if (gpu_process) + gpu_process->HandleNativeProcessExit(exit_status); +} + GPUActions LLDBServerPluginAMDGPU::GetInitializeActions() { GPUActions init_actions; init_actions.plugin_name = GetPluginName(); diff --git a/lldb/tools/lldb-server/Plugins/AMDGPU/LLDBServerPluginAMDGPU.h b/lldb/tools/lldb-server/Plugins/AMDGPU/LLDBServerPluginAMDGPU.h index 134b4518b5da3..7ecbfd732a126 100644 --- a/lldb/tools/lldb-server/Plugins/AMDGPU/LLDBServerPluginAMDGPU.h +++ b/lldb/tools/lldb-server/Plugins/AMDGPU/LLDBServerPluginAMDGPU.h @@ -56,6 +56,7 @@ class LLDBServerPluginAMDGPU : public LLDBServerPlugin { bool HandleEventFileDescriptorEvent(int fd) override; GPUActions GetInitializeActions() override; std::optional NativeProcessIsStopping() override; + void NativeProcessDidExit(const WaitStatus &exit_status) override; llvm::Expected BreakpointWasHit(GPUPluginBreakpointHitArgs &args) override; diff --git a/lldb/tools/lldb-server/Plugins/AMDGPU/ProcessAMDGPU.cpp b/lldb/tools/lldb-server/Plugins/AMDGPU/ProcessAMDGPU.cpp index 67a081021910c..66a9ed061dced 100644 --- a/lldb/tools/lldb-server/Plugins/AMDGPU/ProcessAMDGPU.cpp +++ b/lldb/tools/lldb-server/Plugins/AMDGPU/ProcessAMDGPU.cpp @@ -146,6 +146,11 @@ void ProcessAMDGPU::SetLaunchInfo(ProcessLaunchInfo &launch_info) { static_cast(launch_info); } +void ProcessAMDGPU::HandleNativeProcessExit(const WaitStatus &exit_status) { + // Set our exit status to match the native process and notify delegates + SetExitStatus(exit_status, true); +} + bool ProcessAMDGPU::GetProcessInfo(ProcessInstanceInfo &proc_info) { Log *log = GetLog(GDBRLog::Plugin); LLDB_LOGF(log, "ProcessAMDGPU::%s() entered", __FUNCTION__); diff --git a/lldb/tools/lldb-server/Plugins/AMDGPU/ProcessAMDGPU.h b/lldb/tools/lldb-server/Plugins/AMDGPU/ProcessAMDGPU.h index 2db9096f6104f..1dd4ee0c6c9f1 100644 --- a/lldb/tools/lldb-server/Plugins/AMDGPU/ProcessAMDGPU.h +++ b/lldb/tools/lldb-server/Plugins/AMDGPU/ProcessAMDGPU.h @@ -86,6 +86,9 @@ class ProcessAMDGPU : public NativeProcessProtocol { std::optional GetGPUDynamicLoaderLibraryInfos(const GPUDynamicLoaderArgs &args) override; + /// Called when the native process exits to exit the GPU process + void HandleNativeProcessExit(const WaitStatus &exit_status); + bool handleWaveStop(amd_dbgapi_event_id_t eventId); bool handleDebugEvent(amd_dbgapi_event_id_t eventId, diff --git a/lldb/tools/lldb-server/Plugins/MockGPU/LLDBServerPluginMockGPU.cpp b/lldb/tools/lldb-server/Plugins/MockGPU/LLDBServerPluginMockGPU.cpp index c781e071f94d9..d1a0ccc4d2b96 100644 --- a/lldb/tools/lldb-server/Plugins/MockGPU/LLDBServerPluginMockGPU.cpp +++ b/lldb/tools/lldb-server/Plugins/MockGPU/LLDBServerPluginMockGPU.cpp @@ -164,6 +164,14 @@ std::optional LLDBServerPluginMockGPU::NativeProcessIsStopping() { return std::nullopt; } +void LLDBServerPluginMockGPU::NativeProcessDidExit( + const WaitStatus &exit_status) { + // Tell the GPU process to exit + NativeProcessProtocol *gpu_process = m_gdb_server->GetCurrentProcess(); + if (auto *mock_gpu_process = static_cast(gpu_process)) + mock_gpu_process->HandleNativeProcessExit(exit_status); +} + llvm::Expected LLDBServerPluginMockGPU::BreakpointWasHit(GPUPluginBreakpointHitArgs &args) { const auto bp_identifier = args.breakpoint.identifier; diff --git a/lldb/tools/lldb-server/Plugins/MockGPU/LLDBServerPluginMockGPU.h b/lldb/tools/lldb-server/Plugins/MockGPU/LLDBServerPluginMockGPU.h index 6c52830e911d7..b481ece2a2aa8 100644 --- a/lldb/tools/lldb-server/Plugins/MockGPU/LLDBServerPluginMockGPU.h +++ b/lldb/tools/lldb-server/Plugins/MockGPU/LLDBServerPluginMockGPU.h @@ -80,6 +80,7 @@ class LLDBServerPluginMockGPU : public LLDBServerPlugin { bool HandleEventFileDescriptorEvent(int fd) override; GPUActions GetInitializeActions() override; std::optional NativeProcessIsStopping() override; + void NativeProcessDidExit(const WaitStatus &exit_status) override; llvm::Expected BreakpointWasHit(GPUPluginBreakpointHitArgs &args) override; diff --git a/lldb/tools/lldb-server/Plugins/MockGPU/ProcessMockGPU.cpp b/lldb/tools/lldb-server/Plugins/MockGPU/ProcessMockGPU.cpp index c1e984ff47c18..a37fe619c72af 100644 --- a/lldb/tools/lldb-server/Plugins/MockGPU/ProcessMockGPU.cpp +++ b/lldb/tools/lldb-server/Plugins/MockGPU/ProcessMockGPU.cpp @@ -249,3 +249,12 @@ ProcessMockGPU::Extension ProcessMockGPU::Manager::GetSupportedExtensions() const { return Extension::gpu_dyld | Extension::address_spaces; } + +void ProcessMockGPU::HandleNativeProcessExit(const WaitStatus &exit_status) { + Log *log = GetLog(GDBRLog::Plugin); + LLDB_LOG(log, "ProcessMockGPU::{0}() native process exited with status=({1})", + __FUNCTION__, exit_status); + + // Set our exit status to match the native process and notify delegates + SetExitStatus(exit_status, true); +} diff --git a/lldb/tools/lldb-server/Plugins/MockGPU/ProcessMockGPU.h b/lldb/tools/lldb-server/Plugins/MockGPU/ProcessMockGPU.h index 32111f2e6e857..9e5e38c931040 100644 --- a/lldb/tools/lldb-server/Plugins/MockGPU/ProcessMockGPU.h +++ b/lldb/tools/lldb-server/Plugins/MockGPU/ProcessMockGPU.h @@ -105,6 +105,9 @@ class Manager : public NativeProcessProtocol::Manager { // Custom accessors void SetLaunchInfo(ProcessLaunchInfo &launch_info); + + /// Called when the native process exits to set the GPU process exit status + void HandleNativeProcessExit(const WaitStatus &exit_status); };