| import lldb | |
| from lldbsuite.test.lldbtest import * | |
| from lldbsuite.test.decorators import * | |
| from lldbsuite.test.gdbclientutils import * | |
| from lldbsuite.test.lldbgdbclient import GDBRemoteTestBase | |
| @skipIf(hostoslist=["windows"]) | |
| class TestPty(GDBRemoteTestBase): | |
| SHARED_BUILD_TESTCASE = False | |
| server_socket_class = PtyServerSocket | |
| def get_term_attrs(self): | |
| import termios | |
| return termios.tcgetattr(self._secondary_socket) | |
| def setUp(self): | |
| super().setUp() | |
| # Duplicate the pty descriptors so we can inspect the pty state after | |
| # they are closed | |
| self._primary_socket = os.dup(self.server._socket._primary.name) | |
| self._secondary_socket = os.dup(self.server._socket._secondary.name) | |
| self.orig_attr = self.get_term_attrs() | |
| def assert_raw_mode(self, current_attr): | |
| import termios | |
| self.assertEqual( | |
| current_attr[0] | |
| & ( | |
| termios.BRKINT | |
| | termios.PARMRK | |
| | termios.ISTRIP | |
| | termios.INLCR | |
| | termios.IGNCR | |
| | termios.ICRNL | |
| | termios.IXON | |
| ), | |
| 0, | |
| ) | |
| self.assertEqual(current_attr[1] & termios.OPOST, 0) | |
| self.assertEqual(current_attr[2] & termios.CSIZE, termios.CS8) | |
| self.assertEqual( | |
| current_attr[3] | |
| & (termios.ICANON | termios.ECHO | termios.ISIG | termios.IEXTEN), | |
| 0, | |
| ) | |
| self.assertEqual(current_attr[6][termios.VMIN], 1) | |
| self.assertEqual(current_attr[6][termios.VTIME], 0) | |
| def get_parity_flags(self, attr): | |
| import termios | |
| return attr[2] & (termios.PARENB | termios.PARODD) | |
| def get_stop_bit_flags(self, attr): | |
| import termios | |
| return attr[2] & termios.CSTOPB | |
| def test_process_connect_sync(self): | |
| """Test the process connect command in synchronous mode""" | |
| try: | |
| self.dbg.SetAsync(False) | |
| self.expect( | |
| "platform select remote-gdb-server", | |
| substrs=["Platform: remote-gdb-server", "Connected: no"], | |
| ) | |
| self.expect( | |
| "process connect " + self.server.get_connect_url(), | |
| substrs=["Process", "stopped"], | |
| ) | |
| current_attr = self.get_term_attrs() | |
| # serial:// should set raw mode | |
| self.assert_raw_mode(current_attr) | |
| # other parameters should be unmodified | |
| self.assertEqual(current_attr[4:6], self.orig_attr[4:6]) | |
| self.assertEqual( | |
| self.get_parity_flags(current_attr), | |
| self.get_parity_flags(self.orig_attr), | |
| ) | |
| self.assertEqual( | |
| self.get_stop_bit_flags(current_attr), | |
| self.get_stop_bit_flags(self.orig_attr), | |
| ) | |
| finally: | |
| self.dbg.GetSelectedTarget().GetProcess().Kill() | |
| # original mode should be restored on exit | |
| self.assertEqual(self.get_term_attrs(), self.orig_attr) | |
| def test_process_connect_async(self): | |
| """Test the process connect command in asynchronous mode""" | |
| try: | |
| self.dbg.SetAsync(True) | |
| self.expect( | |
| "platform select remote-gdb-server", | |
| substrs=["Platform: remote-gdb-server", "Connected: no"], | |
| ) | |
| self.expect( | |
| "process connect " + self.server.get_connect_url(), | |
| matching=False, | |
| substrs=["Process", "stopped"], | |
| ) | |
| lldbutil.expect_state_changes( | |
| self, self.dbg.GetListener(), self.process(), [lldb.eStateStopped] | |
| ) | |
| current_attr = self.get_term_attrs() | |
| # serial:// should set raw mode | |
| self.assert_raw_mode(current_attr) | |
| # other parameters should be unmodified | |
| self.assertEqual(current_attr[4:6], self.orig_attr[4:6]) | |
| self.assertEqual( | |
| self.get_parity_flags(current_attr), | |
| self.get_parity_flags(self.orig_attr), | |
| ) | |
| self.assertEqual( | |
| self.get_stop_bit_flags(current_attr), | |
| self.get_stop_bit_flags(self.orig_attr), | |
| ) | |
| finally: | |
| self.dbg.GetSelectedTarget().GetProcess().Kill() | |
| lldbutil.expect_state_changes( | |
| self, self.dbg.GetListener(), self.process(), [lldb.eStateExited] | |
| ) | |
| # original mode should be restored on exit | |
| self.assertEqual(self.get_term_attrs(), self.orig_attr) | |
| def test_connect_via_file(self): | |
| """Test connecting via the legacy file:// URL""" | |
| import termios | |
| try: | |
| self.expect( | |
| "platform select remote-gdb-server", | |
| substrs=["Platform: remote-gdb-server", "Connected: no"], | |
| ) | |
| self.expect( | |
| "process connect file://" + self.server.get_connect_address(), | |
| substrs=["Process", "stopped"], | |
| ) | |
| # file:// sets baud rate and some raw-related flags | |
| current_attr = self.get_term_attrs() | |
| self.assertEqual( | |
| current_attr[3] | |
| & (termios.ICANON | termios.ECHO | termios.ECHOE | termios.ISIG), | |
| 0, | |
| ) | |
| self.assertEqual(current_attr[4], termios.B115200) | |
| self.assertEqual(current_attr[5], termios.B115200) | |
| self.assertEqual(current_attr[6][termios.VMIN], 1) | |
| self.assertEqual(current_attr[6][termios.VTIME], 0) | |
| finally: | |
| self.dbg.GetSelectedTarget().GetProcess().Kill() | |
| def test_process_connect_params(self): | |
| """Test serial:// URL with parameters""" | |
| import termios | |
| try: | |
| self.expect( | |
| "platform select remote-gdb-server", | |
| substrs=["Platform: remote-gdb-server", "Connected: no"], | |
| ) | |
| self.expect( | |
| "process connect " | |
| + self.server.get_connect_url() | |
| + "?baud=115200&stop-bits=2", | |
| substrs=["Process", "stopped"], | |
| ) | |
| current_attr = self.get_term_attrs() | |
| self.assert_raw_mode(current_attr) | |
| self.assertEqual(current_attr[4:6], 2 * [termios.B115200]) | |
| self.assertEqual( | |
| self.get_parity_flags(current_attr), | |
| self.get_parity_flags(self.orig_attr), | |
| ) | |
| self.assertEqual(self.get_stop_bit_flags(current_attr), termios.CSTOPB) | |
| finally: | |
| self.dbg.GetSelectedTarget().GetProcess().Kill() | |
| # original mode should be restored on exit | |
| self.assertEqual(self.get_term_attrs(), self.orig_attr) |