https://github.com/eleviant updated https://github.com/llvm/llvm-project/pull/145072
>From 8436977c0331765ab17dbb47cd7113352642e575 Mon Sep 17 00:00:00 2001 From: Evgeny Leviant <elevi...@accesssoftek.com> Date: Fri, 20 Jun 2025 18:46:24 +0200 Subject: [PATCH 1/2] [lldb] Fix qEcho message handling Patch fixes the sync-on-timeout logic in lldb and switches to qEcho based ping, instead of qC. This fixes vRun message case, when there is no process yet and qC returns an error. --- .../Python/lldbsuite/test/gdbclientutils.py | 10 +++ .../gdb-remote/GDBRemoteCommunication.cpp | 3 +- .../GDBRemoteCommunicationClient.cpp | 2 +- .../gdb_remote_client/TestGDBRemoteClient.py | 74 +++++++++++++++++++ 4 files changed, 87 insertions(+), 2 deletions(-) diff --git a/lldb/packages/Python/lldbsuite/test/gdbclientutils.py b/lldb/packages/Python/lldbsuite/test/gdbclientutils.py index 753de22b9cfee..b603c35c8df09 100644 --- a/lldb/packages/Python/lldbsuite/test/gdbclientutils.py +++ b/lldb/packages/Python/lldbsuite/test/gdbclientutils.py @@ -92,6 +92,9 @@ class MockGDBServerResponder: class RESPONSE_DISCONNECT: pass + class RESPONSE_NONE: + pass + def __init__(self): self.packetLog = [] @@ -181,6 +184,8 @@ def respond(self, packet): return self.qQueryGDBServer() if packet == "qHostInfo": return self.qHostInfo() + if packet.startswith("qEcho"): + return self.qEcho(int(packet.split(":")[1])) if packet == "qGetWorkingDir": return self.qGetWorkingDir() if packet == "qOffsets": @@ -237,6 +242,9 @@ def qProcessInfo(self): def qHostInfo(self): return "ptrsize:8;endian:little;" + def qEcho(self): + return "E04" + def qQueryGDBServer(self): return "E04" @@ -655,6 +663,8 @@ def _handlePacket(self, packet): if not isinstance(response, list): response = [response] for part in response: + if part is MockGDBServerResponder.RESPONSE_NONE: + continue if part is MockGDBServerResponder.RESPONSE_DISCONNECT: raise self.TerminateConnectionException() self._sendPacket(part) diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp index 2aea7c6b781d7..f244f7abe45e3 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -354,8 +354,9 @@ GDBRemoteCommunication::WaitForPacketNoLock(StringExtractorGDBRemote &packet, disconnected = true; Disconnect(); } + } else { + timed_out = true; } - timed_out = true; break; case eConnectionStatusSuccess: // printf ("status = success but error = %s\n", diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index adbf06b9a19a0..d8130cae71ce6 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -406,7 +406,7 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() { m_supports_qXfer_memory_map_read = eLazyBoolYes; else if (x == "qXfer:siginfo:read+") m_supports_qXfer_siginfo_read = eLazyBoolYes; - else if (x == "qEcho") + else if (x == "qEcho+") m_supports_qEcho = eLazyBoolYes; else if (x == "QPassSignals+") m_supports_QPassSignals = eLazyBoolYes; diff --git a/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py b/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py index 08ac9290ee85a..49e589226b0ef 100644 --- a/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py +++ b/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py @@ -356,6 +356,80 @@ def A(self, packet): ["vRun;%s;61726731;61726732;61726733" % (exe_hex,)] ) + def test_launch_lengthy_vRun(self): + class MyResponder(MockGDBServerResponder): + def __init__(self, *args, **kwargs): + self.started = False + return super().__init__(*args, **kwargs) + + def qC(self): + if self.started: + return "QCp10.10" + else: + return "E42" + + def qfThreadInfo(self): + if self.started: + return "mp10.10" + else: + return "E42" + + def qsThreadInfo(self): + return "l" + + def qEcho(self, num): + resp = "qEcho:" + str(num) + if num >= 2: + # We have launched our program + self.started = True + return [resp, "T13"] + + return resp + + def qSupported(self, client_supported): + return "PacketSize=3fff;QStartNoAckMode+;qEcho+;" + + def qHostInfo(self): + return "default_packet_timeout:1;" + + def vRun(self, packet): + return [self.RESPONSE_NONE] + + def A(self, packet): + return "E28" + + #self.runCmd("log enable -f /tmp/lldb.log gdb-remote all") + #self.runCmd("settings set plugin.process.gdb-remote.packet-timeout 1") + self.server.responder = MyResponder() + + target = self.createTarget("a.yaml") + # NB: apparently GDB packets are using "/" on Windows too + exe_path = self.getBuildArtifact("a").replace(os.path.sep, "/") + exe_hex = binascii.b2a_hex(exe_path.encode()).decode() + process = self.connect(target) + lldbutil.expect_state_changes( + self, self.dbg.GetListener(), process, [lldb.eStateConnected] + ) + + process = target.Launch( + lldb.SBListener(), + ["arg1", "arg2", "arg3"], # argv + [], # envp + None, # stdin_path + None, # stdout_path + None, # stderr_path + None, # working_directory + 0, # launch_flags + True, # stop_at_entry + lldb.SBError(), + ) # error + self.assertTrue(process, PROCESS_IS_VALID) + self.assertEqual(process.GetProcessID(), 16) + + self.assertPacketLogContains( + ["vRun;%s;61726731;61726732;61726733" % (exe_hex,)] + ) + def test_launch_QEnvironment(self): class MyResponder(MockGDBServerResponder): def qC(self): >From ddd17cafa7033c0d061b126ba6698744d8728f67 Mon Sep 17 00:00:00 2001 From: Evgeny Leviant <elevi...@accesssoftek.com> Date: Fri, 20 Jun 2025 18:54:56 +0200 Subject: [PATCH 2/2] Remove commented code --- .../functionalities/gdb_remote_client/TestGDBRemoteClient.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py b/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py index 49e589226b0ef..12b464d3397eb 100644 --- a/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py +++ b/lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py @@ -398,8 +398,6 @@ def vRun(self, packet): def A(self, packet): return "E28" - #self.runCmd("log enable -f /tmp/lldb.log gdb-remote all") - #self.runCmd("settings set plugin.process.gdb-remote.packet-timeout 1") self.server.responder = MyResponder() target = self.createTarget("a.yaml") _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits