1import lldb 2from lldbsuite.test.lldbtest import * 3from lldbsuite.test.decorators import * 4from lldbsuite.test.gdbclientutils import * 5from lldbsuite.test.lldbgdbclient import GDBRemoteTestBase 6 7 8@skipIfWindows 9class TestPty(GDBRemoteTestBase): 10 mydir = TestBase.compute_mydir(__file__) 11 server_socket_class = PtyServerSocket 12 13 def get_term_attrs(self): 14 import termios 15 return termios.tcgetattr(self._secondary_socket) 16 17 def setUp(self): 18 super().setUp() 19 # Duplicate the pty descriptors so we can inspect the pty state after 20 # they are closed 21 self._primary_socket = os.dup(self.server._socket._primary.name) 22 self._secondary_socket = os.dup(self.server._socket._secondary.name) 23 self.orig_attr = self.get_term_attrs() 24 25 def assert_raw_mode(self, current_attr): 26 import termios 27 self.assertEqual(current_attr[0] & (termios.BRKINT | 28 termios.PARMRK | 29 termios.ISTRIP | termios.INLCR | 30 termios.IGNCR | termios.ICRNL | 31 termios.IXON), 32 0) 33 self.assertEqual(current_attr[1] & termios.OPOST, 0) 34 self.assertEqual(current_attr[2] & termios.CSIZE, termios.CS8) 35 self.assertEqual(current_attr[3] & (termios.ICANON | termios.ECHO | 36 termios.ISIG | termios.IEXTEN), 37 0) 38 self.assertEqual(current_attr[6][termios.VMIN], 1) 39 self.assertEqual(current_attr[6][termios.VTIME], 0) 40 41 def get_parity_flags(self, attr): 42 import termios 43 return attr[2] & (termios.PARENB | termios.PARODD) 44 45 def get_stop_bit_flags(self, attr): 46 import termios 47 return attr[2] & termios.CSTOPB 48 49 def test_process_connect_sync(self): 50 """Test the process connect command in synchronous mode""" 51 try: 52 self.dbg.SetAsync(False) 53 self.expect("platform select remote-gdb-server", 54 substrs=['Platform: remote-gdb-server', 'Connected: no']) 55 self.expect("process connect " + self.server.get_connect_url(), 56 substrs=['Process', 'stopped']) 57 58 current_attr = self.get_term_attrs() 59 # serial:// should set raw mode 60 self.assert_raw_mode(current_attr) 61 # other parameters should be unmodified 62 self.assertEqual(current_attr[4:6], self.orig_attr[4:6]) 63 self.assertEqual(self.get_parity_flags(current_attr), 64 self.get_parity_flags(self.orig_attr)) 65 self.assertEqual(self.get_stop_bit_flags(current_attr), 66 self.get_stop_bit_flags(self.orig_attr)) 67 finally: 68 self.dbg.GetSelectedTarget().GetProcess().Kill() 69 # original mode should be restored on exit 70 self.assertEqual(self.get_term_attrs(), self.orig_attr) 71 72 def test_process_connect_async(self): 73 """Test the process connect command in asynchronous mode""" 74 try: 75 self.dbg.SetAsync(True) 76 self.expect("platform select remote-gdb-server", 77 substrs=['Platform: remote-gdb-server', 'Connected: no']) 78 self.expect("process connect " + self.server.get_connect_url(), 79 matching=False, 80 substrs=['Process', 'stopped']) 81 lldbutil.expect_state_changes(self, self.dbg.GetListener(), 82 self.process(), [lldb.eStateStopped]) 83 84 current_attr = self.get_term_attrs() 85 # serial:// should set raw mode 86 self.assert_raw_mode(current_attr) 87 # other parameters should be unmodified 88 self.assertEqual(current_attr[4:6], self.orig_attr[4:6]) 89 self.assertEqual(self.get_parity_flags(current_attr), 90 self.get_parity_flags(self.orig_attr)) 91 self.assertEqual(self.get_stop_bit_flags(current_attr), 92 self.get_stop_bit_flags(self.orig_attr)) 93 finally: 94 self.dbg.GetSelectedTarget().GetProcess().Kill() 95 lldbutil.expect_state_changes(self, self.dbg.GetListener(), 96 self.process(), [lldb.eStateExited]) 97 # original mode should be restored on exit 98 self.assertEqual(self.get_term_attrs(), self.orig_attr) 99 100 def test_connect_via_file(self): 101 """Test connecting via the legacy file:// URL""" 102 import termios 103 try: 104 self.expect("platform select remote-gdb-server", 105 substrs=['Platform: remote-gdb-server', 'Connected: no']) 106 self.expect("process connect file://" + 107 self.server.get_connect_address(), 108 substrs=['Process', 'stopped']) 109 110 # file:// sets baud rate and some raw-related flags 111 current_attr = self.get_term_attrs() 112 self.assertEqual(current_attr[3] & (termios.ICANON | termios.ECHO | 113 termios.ECHOE | termios.ISIG), 114 0) 115 self.assertEqual(current_attr[4], termios.B115200) 116 self.assertEqual(current_attr[5], termios.B115200) 117 self.assertEqual(current_attr[6][termios.VMIN], 1) 118 self.assertEqual(current_attr[6][termios.VTIME], 0) 119 finally: 120 self.dbg.GetSelectedTarget().GetProcess().Kill() 121 122 def test_process_connect_params(self): 123 """Test serial:// URL with parameters""" 124 import termios 125 try: 126 self.expect("platform select remote-gdb-server", 127 substrs=['Platform: remote-gdb-server', 'Connected: no']) 128 self.expect("process connect " + self.server.get_connect_url() + 129 "?baud=115200&stop-bits=2", 130 substrs=['Process', 'stopped']) 131 132 current_attr = self.get_term_attrs() 133 self.assert_raw_mode(current_attr) 134 self.assertEqual(current_attr[4:6], 2 * [termios.B115200]) 135 self.assertEqual(self.get_parity_flags(current_attr), 136 self.get_parity_flags(self.orig_attr)) 137 self.assertEqual(self.get_stop_bit_flags(current_attr), 138 termios.CSTOPB) 139 finally: 140 self.dbg.GetSelectedTarget().GetProcess().Kill() 141 # original mode should be restored on exit 142 self.assertEqual(self.get_term_attrs(), self.orig_attr) 143