[Lldb-commits] [PATCH] D18146: [test] Correctly retry connections on android targets

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Mon Mar 14 08:37:42 PDT 2016


labath updated this revision to Diff 50600.
labath added a comment.

Fix comment


http://reviews.llvm.org/D18146

Files:
  packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py

Index: packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py
===================================================================
--- packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py
+++ packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py
@@ -24,6 +24,9 @@
 from lldbgdbserverutils import *
 import logging
 
+class _ConnectionRefused(IOError):
+    pass
+
 class GdbRemoteTestCaseBase(TestBase):
 
     _TIMEOUT_SECONDS = 7
@@ -265,6 +268,22 @@
         subprocess.call(adb + [ "tcp:%d" % source, "tcp:%d" % target])
         self.addTearDownHook(remove_port_forward)
 
+    def _verify_socket(self, sock):
+        # 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
+        # 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
+        # situation, and report it as "connection refused" so that the upper layers attempt the
+        # connection again.
+        triple = self.dbg.GetSelectedPlatform().GetTriple()
+        if not re.match(".*-.*-.*-android", triple):
+            return # Not android.
+        can_read, _, _ = select.select([sock], [], [], 0.1)
+        if sock not in can_read:
+            return # Data is not available, but the connection is alive.
+        if len(sock.recv(1, socket.MSG_PEEK)) == 0:
+            raise _ConnectionRefused() # Got EOF, connection dropped.
+
     def create_socket(self):
         sock = socket.socket()
         logger = self.logger
@@ -275,7 +294,12 @@
 
         logger.info("Connecting to debug monitor on %s:%d", self.stub_hostname, self.port)
         connect_info = (self.stub_hostname, self.port)
-        sock.connect(connect_info)
+        try:
+            sock.connect(connect_info)
+        except socket.error as serr:
+            if serr.errno == errno.ECONNREFUSED:
+                raise _ConnectionRefused()
+            raise serr
 
         def shutdown_socket():
             if sock:
@@ -292,6 +316,8 @@
 
         self.addTearDownHook(shutdown_socket)
 
+        self._verify_socket(sock)
+
         return sock
 
     def set_inferior_startup_launch(self):
@@ -379,12 +405,12 @@
             while connect_attemps < MAX_CONNECT_ATTEMPTS:
                 # Create a socket to talk to the server
                 try:
+                    logger.info("Connect attempt %d", connect_attemps+1)
                     self.sock = self.create_socket()
                     return server
-                except socket.error as serr:
-                    # We're only trying to handle connection refused.
-                    if serr.errno != errno.ECONNREFUSED:
-                        raise serr
+                except _ConnectionRefused as serr:
+                    # Ignore, and try again.
+                    pass
                 time.sleep(0.5)
                 connect_attemps += 1
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D18146.50600.patch
Type: text/x-patch
Size: 3088 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20160314/0122f4b1/attachment-0001.bin>


More information about the lldb-commits mailing list