Index: lldb/test/API/tools/lldb-server/TestPtyServer.py =================================================================== --- /dev/null +++ lldb/test/API/tools/lldb-server/TestPtyServer.py @@ -0,0 +1,64 @@ +import gdbremote_testcase +import lldbgdbserverutils +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbgdbserverutils import * + + +@skipIfWindows +class PtyServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase): + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + super().setUp() + import pty + import tty + master, slave = pty.openpty() + tty.setraw(master) + self._master = io.FileIO(master, 'r+b') + self._slave = io.FileIO(slave, 'r+b') + + def get_debug_monitor_command_line_args(self, attach_pid=None): + commandline_args = self.debug_monitor_extra_args + if attach_pid: + commandline_args += ["--attach=%d" % attach_pid] + + libc = ctypes.CDLL(None) + libc.ptsname.argtypes = (ctypes.c_int,) + libc.ptsname.restype = ctypes.c_char_p + pty_path = libc.ptsname(self._master.fileno()).decode() + commandline_args += ["serial://%s" % (pty_path,)] + return commandline_args + + def connect_to_debug_monitor(self, attach_pid=None): + self.reverse_connect = False + server = self.launch_debug_monitor(attach_pid=attach_pid) + self.assertIsNotNone(server) + + # TODO: make it into proper abstraction + class FakeSocket: + def __init__(self, fd): + self.fd = fd + + def sendall(self, frame): + self.fd.write(frame) + + def recv(self, count): + return self.fd.read(count) + + self.sock = FakeSocket(self._master) + self._server = Server(self.sock, server) + return server + + @add_test_categories(["llgs"]) + def test_pty_server(self): + server = self.connect_to_debug_monitor() + self.assertIsNotNone(server) + + self.do_handshake() + self.test_sequence.add_log_lines( + ["lldb-server < 26> read packet: $QThreadSuffixSupported#e4", + "lldb-server < 6> send packet: $OK#9a"], + True) + + self.expect_gdbremote_sequence() Index: lldb/tools/lldb-server/lldb-gdbserver.cpp =================================================================== --- lldb/tools/lldb-server/lldb-gdbserver.cpp +++ lldb/tools/lldb-server/lldb-gdbserver.cpp @@ -230,24 +230,27 @@ final_host_and_port.append("localhost"); final_host_and_port.append(host_and_port.str()); - if (reverse_connect) { + bool is_url = host_and_port.contains("://"); + if (reverse_connect || is_url) { // llgs will connect to the gdb-remote client. - // Ensure we have a port number for the connection. - // Note: use rfind, because the host/port may look like "[::1]:12345". - uint32_t connection_portno = 0; - const std::string::size_type colon_pos = final_host_and_port.rfind(':'); - if (colon_pos != std::string::npos) - llvm::to_integer(final_host_and_port.substr(colon_pos + 1), - connection_portno); - if (connection_portno == 0) { - llvm::errs() << "error: port number must be specified on when using " - "reverse connect\n"; - exit(1); - } + if (!is_url) { + // Ensure we have a port number for the connection. + // Note: use rfind, because the host/port may look like "[::1]:12345". + uint32_t connection_portno = 0; + const std::string::size_type colon_pos = final_host_and_port.rfind(':'); + if (colon_pos != std::string::npos) + llvm::to_integer(final_host_and_port.substr(colon_pos + 1), + connection_portno); + if (connection_portno == 0) { + llvm::errs() << "error: port number must be specified on when using " + "reverse connect\n"; + exit(1); + } - // Build the connection string. - final_host_and_port.insert(0, "connect://"); + // Build the connection string. + final_host_and_port.insert(0, "connect://"); + } // Create the connection. connection_up.reset(new ConnectionFileDescriptor);