diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -1543,14 +1543,16 @@ } } - if (pid != LLDB_INVALID_PROCESS_ID) { - if (!m_supports_multiprocess) { - error.SetErrorString( - "Multiprocess extension not supported by the server."); - return error; - } + if (m_supports_multiprocess) { + // Some servers (e.g. qemu) require specifying the PID even if only a single + // process is running. + if (pid == LLDB_INVALID_PROCESS_ID) + pid = GetCurrentProcessID(); packet.PutChar(';'); packet.PutHex64(pid); + } else if (pid != LLDB_INVALID_PROCESS_ID) { + error.SetErrorString("Multiprocess extension not supported by the server."); + return error; } StringExtractorGDBRemote response; diff --git a/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py b/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py --- a/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py +++ b/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py @@ -354,3 +354,46 @@ "QEnvironmentHexEncoded:4e45454453454e43343d6623726f62", "QEnvironmentHexEncoded:455155414c533d666f6f3d626172", ]) + + def test_detach_no_multiprocess(self): + class MyResponder(MockGDBServerResponder): + def __init__(self): + super().__init__() + self.detached = None + + def qfThreadInfo(self): + return "10200" + + def D(self, packet): + self.detached = packet + return "OK" + + self.server.responder = MyResponder() + target = self.dbg.CreateTarget('') + process = self.connect(target) + process.Detach() + self.assertEqual(self.server.responder.detached, "D") + + def test_detach_pid(self): + class MyResponder(MockGDBServerResponder): + def __init__(self, test_case): + super().__init__() + self.test_case = test_case + self.detached = None + + def qSupported(self, client_supported): + self.test_case.assertIn("multiprocess+", client_supported) + return "multiprocess+;" + super().qSupported(client_supported) + + def qfThreadInfo(self): + return "mp400.10200" + + def D(self, packet): + self.detached = packet + return "OK" + + self.server.responder = MyResponder(self) + target = self.dbg.CreateTarget('') + process = self.connect(target) + process.Detach() + self.assertRegex(self.server.responder.detached, r"D;0*400")