[lldb] Fix qEcho message handling (#145072)
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.
This commit is contained in:
@@ -92,6 +92,9 @@ class MockGDBServerResponder:
|
||||
class RESPONSE_DISCONNECT:
|
||||
pass
|
||||
|
||||
class RESPONSE_NONE:
|
||||
pass
|
||||
|
||||
def __init__(self):
|
||||
self.packetLog = []
|
||||
|
||||
@@ -181,6 +184,8 @@ class MockGDBServerResponder:
|
||||
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 @@ class MockGDBServerResponder:
|
||||
def qHostInfo(self):
|
||||
return "ptrsize:8;endian:little;"
|
||||
|
||||
def qEcho(self):
|
||||
return "E04"
|
||||
|
||||
def qQueryGDBServer(self):
|
||||
return "E04"
|
||||
|
||||
@@ -655,6 +663,8 @@ class MockGDBServer:
|
||||
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)
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -356,6 +356,78 @@ class TestGDBRemoteClient(GDBRemoteTestBase):
|
||||
["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.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):
|
||||
|
||||
Reference in New Issue
Block a user