diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py b/lldb/packages/Python/lldbsuite/test/lldbtest.py --- a/lldb/packages/Python/lldbsuite/test/lldbtest.py +++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py @@ -422,6 +422,9 @@ def poll(self): return self._proc.poll() + def wait(self, timeout=None): + return self._proc.wait(timeout) + class _RemoteProcess(_BaseProcess): diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp --- a/lldb/source/Target/Platform.cpp +++ b/lldb/source/Target/Platform.cpp @@ -1044,25 +1044,11 @@ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PLATFORM)); LLDB_LOGF(log, "Platform::%s, pid %" PRIu64, __FUNCTION__, pid); - // Try to find a process plugin to handle this Kill request. If we can't, - // fall back to the default OS implementation. - size_t num_debuggers = Debugger::GetNumDebuggers(); - for (size_t didx = 0; didx < num_debuggers; ++didx) { - DebuggerSP debugger = Debugger::GetDebuggerAtIndex(didx); - lldb_private::TargetList &targets = debugger->GetTargetList(); - for (int tidx = 0; tidx < targets.GetNumTargets(); ++tidx) { - ProcessSP process = targets.GetTargetAtIndex(tidx)->GetProcessSP(); - if (process->GetID() == pid) - return process->Destroy(true); - } - } - if (!IsHost()) { return Status( - "base lldb_private::Platform class can't kill remote processes unless " - "they are controlled by a process plugin"); + "base lldb_private::Platform class can't kill remote processes"); } - Host::Kill(pid, SIGTERM); + Host::Kill(pid, SIGKILL); return Status(); } diff --git a/lldb/test/API/functionalities/gdb_remote_client/Makefile b/lldb/test/API/functionalities/gdb_remote_client/Makefile new file mode 100644 --- /dev/null +++ b/lldb/test/API/functionalities/gdb_remote_client/Makefile @@ -0,0 +1 @@ +include Makefile.rules diff --git a/lldb/test/API/functionalities/gdb_remote_client/TestPlatformKill.py b/lldb/test/API/functionalities/gdb_remote_client/TestPlatformKill.py new file mode 100644 --- /dev/null +++ b/lldb/test/API/functionalities/gdb_remote_client/TestPlatformKill.py @@ -0,0 +1,47 @@ +import lldb +import time +from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import * +from gdbclientutils import * + +class TestPlatformKill(GDBRemoteTestBase): + + @skipIfRemote + def test_kill_different_platform(self): + """Test connecting to a remote linux platform""" + + self.build(dictionary={"CXX_SOURCES":"sleep.cpp"}) + host_process = self.spawnSubprocess(self.getBuildArtifact()) + + # Create a fake remote process with the same PID as host_process + class MyResponder(MockGDBServerResponder): + def __init__(self): + MockGDBServerResponder.__init__(self) + self.got_kill = False + + def qC(self): + return "QC%x"%host_process.pid + + def k(self): + self.got_kill = True + return "X09" + + self.server.responder = MyResponder() + + error = lldb.SBError() + target = self.dbg.CreateTarget("", "x86_64-pc-linux", "remote-linux", + False, error) + self.assertSuccess(error) + process = self.connect(target) + self.assertEqual(process.GetProcessID(), host_process.pid) + + host_platform = lldb.SBPlatform("host") + self.assertSuccess(host_platform.Kill(host_process.pid)) + + # Host dies, remote process lives. + self.assertFalse(self.server.responder.got_kill) + self.assertIsNotNone(host_process.wait(timeout=10)) + + # Now kill the remote one as well + self.assertSuccess(process.Kill()) + self.assertTrue(self.server.responder.got_kill) diff --git a/lldb/test/API/functionalities/gdb_remote_client/gdbclientutils.py b/lldb/test/API/functionalities/gdb_remote_client/gdbclientutils.py --- a/lldb/test/API/functionalities/gdb_remote_client/gdbclientutils.py +++ b/lldb/test/API/functionalities/gdb_remote_client/gdbclientutils.py @@ -203,6 +203,8 @@ if packet.startswith("qRegisterInfo"): regnum = int(packet[len("qRegisterInfo"):], 16) return self.qRegisterInfo(regnum) + if packet == "k": + return self.k() return self.other(packet) @@ -331,6 +333,9 @@ def qRegisterInfo(self, num): return "" + def k(self): + return "" + """ Raised when we receive a packet for which there is no default action. Override the responder class to implement behavior suitable for the test at diff --git a/lldb/test/API/functionalities/gdb_remote_client/sleep.cpp b/lldb/test/API/functionalities/gdb_remote_client/sleep.cpp new file mode 100644 --- /dev/null +++ b/lldb/test/API/functionalities/gdb_remote_client/sleep.cpp @@ -0,0 +1,6 @@ +#include + +int main() { + std::this_thread::sleep_for(std::chrono::minutes(1)); + return 0; +}