[lldb] Fix broken pipe error (#127100)

During LLDB testing on slow machines with the remote-linux platform all
tests from llgs category fail with python exception `BrokenPipeError`.
The main reason of these failures is slow start of lldb-server in
gdbserver mode. Due to this desired gdbserver socket does not have time
to open by the time the Python script tries to establish a connection.

List of failed tests:

```
TestAppleSimulatorOSType.py
TestGdbRemoteAttach.py
TestGdbRemoteAuxvSupport.py
TestGdbRemoteCompletion.py
TestGdbRemoteExitCode.py
TestGdbRemoteExpeditedRegisters.py
TestGdbRemoteHostInfo.py
TestGdbRemoteKill.py
TestGdbRemoteLaunch.py
TestGdbRemoteModuleInfo.py
TestGdbRemotePlatformFile.py
TestGdbRemoteProcessInfo.py
TestGdbRemoteRegisterState.py
TestGdbRemoteSaveCore.py
TestGdbRemoteSingleStep.py
TestGdbRemoteThreadsInStopReply.py
TestGdbRemote_qThreadStopInfo.py
TestGdbRemote_vCont.py
TestLldbGdbServer.py
TestNonStop.py
TestPtyServer.py
TestGdbRemoteAttachWait.py
TestGdbRemoteConnection.py
TestStubSetSID.py
TestGdbRemoteAbort.py
TestGdbRemoteSegFault.py
TestGdbRemoteLibrariesSvr4Support.py
TestGdbRemoteMemoryAllocation.py
TestGdbRemoteMemoryTagging.py
TestGdbRemoteGPacket.py
TestGdbRemoteTargetXmlPacket.py
TestGdbRemote_QPassSignals.py
TestGdbRemoteThreadName.py
TestPartialResume.py
TestSignal.py
```

This patch implements an additional check for the opened socket on
lldb-server side and fixes this error.
This commit is contained in:
Georgiy Samoylov 2025-02-14 21:39:23 +03:00 committed by GitHub
parent 4b3c6443a1
commit 1042bd7972
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -249,14 +249,11 @@ class GdbRemoteTestCaseBase(Base, metaclass=GdbRemoteTestCaseFactory):
def _verify_socket(self, sock): def _verify_socket(self, sock):
# Normally, when the remote stub is not ready, we will get ECONNREFUSED during the # Normally, when the remote stub is not ready, we will get ECONNREFUSED during the
# connect() attempt. However, due to the way how ADB forwarding works, on android targets # connect() attempt. However, due to the way how port forwarding can work, on some targets
# the connect() will always be successful, but the connection will be immediately dropped # the connect() will always be successful, but the connection will be immediately dropped
# if ADB could not connect on the remote side. This function tries to detect this # if we could not connect on the remote side. This function tries to detect this
# situation, and report it as "connection refused" so that the upper layers attempt the # situation, and report it as "connection refused" so that the upper layers attempt the
# connection again. # connection again.
triple = self.dbg.GetSelectedPlatform().GetTriple()
if not re.match(".*-.*-.*-android", triple):
return # Not android.
can_read, _, _ = select.select([sock], [], [], 0.1) can_read, _, _ = select.select([sock], [], [], 0.1)
if sock not in can_read: if sock not in can_read:
return # Data is not available, but the connection is alive. return # Data is not available, but the connection is alive.
@ -397,13 +394,13 @@ class GdbRemoteTestCaseBase(Base, metaclass=GdbRemoteTestCaseFactory):
# Schedule debug monitor to be shut down during teardown. # Schedule debug monitor to be shut down during teardown.
logger = self.logger logger = self.logger
connect_attemps = 0 connect_attempts = 0
MAX_CONNECT_ATTEMPTS = 10 MAX_CONNECT_ATTEMPTS = 10
while connect_attemps < MAX_CONNECT_ATTEMPTS: while connect_attempts < MAX_CONNECT_ATTEMPTS:
# Create a socket to talk to the server # Create a socket to talk to the server
try: try:
logger.info("Connect attempt %d", connect_attemps + 1) logger.info("Connect attempt %d", connect_attempts + 1)
self.sock = self.create_socket() self.sock = self.create_socket()
self._server = Server(self.sock, server) self._server = Server(self.sock, server)
return server return server
@ -411,7 +408,7 @@ class GdbRemoteTestCaseBase(Base, metaclass=GdbRemoteTestCaseFactory):
# Ignore, and try again. # Ignore, and try again.
pass pass
time.sleep(0.5) time.sleep(0.5)
connect_attemps += 1 connect_attempts += 1
# We should close the server here to be safe. # We should close the server here to be safe.
server.terminate() server.terminate()