[Lldb-commits] [lldb] r263439 - [test] Correctly retry connections on android targets

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


Author: labath
Date: Mon Mar 14 10:33:25 2016
New Revision: 263439

URL: http://llvm.org/viewvc/llvm-project?rev=263439&view=rev
Log:
[test] Correctly retry connections on android targets

Summary:
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 commit tries to detect this situation, and report it as "connection
refused" so that the upper test layers attempt the connection again.

Reviewers: tfiala, tberghammer

Subscribers: tberghammer, danalbert, srhines, lldb-commits

Differential Revision: http://reviews.llvm.org/D18146

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

Modified: lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py?rev=263439&r1=263438&r2=263439&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py Mon Mar 14 10:33:25 2016
@@ -24,6 +24,9 @@ from lldbsuite.test.lldbtest import *
 from lldbgdbserverutils import *
 import logging
 
+class _ConnectionRefused(IOError):
+    pass
+
 class GdbRemoteTestCaseBase(TestBase):
 
     _TIMEOUT_SECONDS = 7
@@ -265,6 +268,22 @@ class GdbRemoteTestCaseBase(TestBase):
         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 @@ class GdbRemoteTestCaseBase(TestBase):
 
         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 @@ class GdbRemoteTestCaseBase(TestBase):
 
         self.addTearDownHook(shutdown_socket)
 
+        self._verify_socket(sock)
+
         return sock
 
     def set_inferior_startup_launch(self):
@@ -379,12 +405,12 @@ class GdbRemoteTestCaseBase(TestBase):
             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
 




More information about the lldb-commits mailing list