1""" 2Test lldb-dap "port" configuration to "attach" request 3""" 4 5 6import dap_server 7from lldbsuite.test.decorators import * 8from lldbsuite.test.lldbtest import * 9from lldbsuite.test import lldbutil 10from lldbsuite.test import lldbplatformutil 11from lldbgdbserverutils import Pipe 12import lldbdap_testcase 13import os 14import shutil 15import subprocess 16import tempfile 17import threading 18import sys 19import socket 20 21 22class TestDAP_attachByPortNum(lldbdap_testcase.DAPTestCaseBase): 23 default_timeout = 20 24 25 def set_and_hit_breakpoint(self, continueToExit=True): 26 source = "main.c" 27 main_source_path = os.path.join(os.getcwd(), source) 28 breakpoint1_line = line_number(main_source_path, "// breakpoint 1") 29 lines = [breakpoint1_line] 30 # Set breakpoint in the thread function so we can step the threads 31 breakpoint_ids = self.set_source_breakpoints(main_source_path, lines) 32 self.assertEqual( 33 len(breakpoint_ids), len(lines), "expect correct number of breakpoints" 34 ) 35 self.continue_to_breakpoints(breakpoint_ids) 36 if continueToExit: 37 self.continue_to_exit() 38 39 def get_debug_server_command_line_args(self): 40 args = [] 41 if lldbplatformutil.getPlatform() == "linux": 42 args = ["gdbserver"] 43 elif lldbplatformutil.getPlatform() == "macosx": 44 args = ["--listen"] 45 if lldb.remote_platform: 46 args += ["*:0"] 47 else: 48 args += ["localhost:0"] 49 return args 50 51 def get_debug_server_pipe(self): 52 pipe = Pipe(self.getBuildDir()) 53 self.addTearDownHook(lambda: pipe.close()) 54 pipe.finish_connection(self.default_timeout) 55 return pipe 56 57 @skipIfWindows 58 @skipIfNetBSD 59 def test_by_port(self): 60 """ 61 Tests attaching to a process by port. 62 """ 63 self.build_and_create_debug_adaptor() 64 program = self.getBuildArtifact("a.out") 65 66 debug_server_tool = self.getBuiltinDebugServerTool() 67 68 pipe = self.get_debug_server_pipe() 69 args = self.get_debug_server_command_line_args() 70 args += [program] 71 args += ["--named-pipe", pipe.name] 72 73 self.process = self.spawnSubprocess( 74 debug_server_tool, args, install_remote=False 75 ) 76 77 # Read the port number from the debug server pipe. 78 port = pipe.read(10, self.default_timeout) 79 # Trim null byte, convert to int 80 port = int(port[:-1]) 81 self.assertIsNotNone( 82 port, " Failed to read the port number from debug server pipe" 83 ) 84 85 self.attach(program=program, gdbRemotePort=port, sourceInitFile=True) 86 self.set_and_hit_breakpoint(continueToExit=True) 87 self.process.terminate() 88 89 @skipIfWindows 90 @skipIfNetBSD 91 def test_by_port_and_pid(self): 92 """ 93 Tests attaching to a process by process ID and port number. 94 """ 95 self.build_and_create_debug_adaptor() 96 program = self.getBuildArtifact("a.out") 97 98 # It is not necessary to launch "lldb-server" to obtain the actual port and pid for attaching. 99 # However, when providing the port number and pid directly, "lldb-dap" throws an error message, which is expected. 100 # So, used random pid and port numbers here. 101 102 pid = 1354 103 port = 1234 104 105 response = self.attach( 106 program=program, 107 pid=pid, 108 gdbRemotePort=port, 109 sourceInitFile=True, 110 expectFailure=True, 111 ) 112 if not (response and response["success"]): 113 self.assertFalse( 114 response["success"], "The user can't specify both pid and port" 115 ) 116 117 @skipIfWindows 118 @skipIfNetBSD 119 def test_by_invalid_port(self): 120 """ 121 Tests attaching to a process by invalid port number 0. 122 """ 123 self.build_and_create_debug_adaptor() 124 program = self.getBuildArtifact("a.out") 125 126 port = 0 127 response = self.attach( 128 program=program, gdbRemotePort=port, sourceInitFile=True, expectFailure=True 129 ) 130 if not (response and response["success"]): 131 self.assertFalse( 132 response["success"], 133 "The user can't attach with invalid port (%s)" % port, 134 ) 135 136 @skipIfWindows 137 @skipIfNetBSD 138 def test_by_illegal_port(self): 139 """ 140 Tests attaching to a process by illegal/greater port number 65536 141 """ 142 self.build_and_create_debug_adaptor() 143 program = self.getBuildArtifact("a.out") 144 145 port = 65536 146 args = [program] 147 debug_server_tool = self.getBuiltinDebugServerTool() 148 self.process = self.spawnSubprocess( 149 debug_server_tool, args, install_remote=False 150 ) 151 152 response = self.attach( 153 program=program, gdbRemotePort=port, sourceInitFile=True, expectFailure=True 154 ) 155 if not (response and response["success"]): 156 self.assertFalse( 157 response["success"], 158 "The user can't attach with illegal port (%s)" % port, 159 ) 160 self.process.terminate() 161