@@ -903,7 +903,7 @@ def request_setBreakpoints(self, file_path, line_array, data=None):
903903 "sourceModified" : False ,
904904 }
905905 if line_array is not None :
906- args_dict ["lines" ] = "%s" % line_array
906+ args_dict ["lines" ] = line_array
907907 breakpoints = []
908908 for i , line in enumerate (line_array ):
909909 breakpoint_data = None
@@ -1150,11 +1150,12 @@ def request_setInstructionBreakpoints(self, memory_reference=[]):
11501150 }
11511151 return self .send_recv (command_dict )
11521152
1153+
11531154class DebugAdaptorServer (DebugCommunication ):
11541155 def __init__ (
11551156 self ,
11561157 executable = None ,
1157- port = None ,
1158+ connection = None ,
11581159 init_commands = [],
11591160 log_file = None ,
11601161 env = None ,
@@ -1167,21 +1168,61 @@ def __init__(
11671168
11681169 if log_file :
11691170 adaptor_env ["LLDBDAP_LOG" ] = log_file
1171+ args = [executable ]
1172+
1173+ if connection is not None :
1174+ args .append ("--connection" )
1175+ args .append (connection )
1176+
11701177 self .process = subprocess .Popen (
1171- [ executable ] ,
1178+ args ,
11721179 stdin = subprocess .PIPE ,
11731180 stdout = subprocess .PIPE ,
11741181 stderr = subprocess .PIPE ,
11751182 env = adaptor_env ,
11761183 )
1184+
1185+ if connection is not None :
1186+ # If the process was also launched, parse the connection from the
1187+ # resolved connection. For example, if the connection
1188+ # `connection://localhost:0` was specified then the OS would pick a
1189+ # random port for listening and lldb-dap would print the listening
1190+ # port to stdout.
1191+ if self .process is not None :
1192+ # lldb-dap will print the listening address once the listener is
1193+ # made to stdout. The listener is formatted like
1194+ # `connection://host:port` or `unix-connection:///path`.
1195+ expected_prefix = "Listening for: "
1196+ out = self .process .stdout .readline ().decode ()
1197+ if not out .startswith (expected_prefix ):
1198+ self .process .kill ()
1199+ raise ValueError (
1200+ "lldb-dap failed to print listening address, expected '{}', got '{}'" .format (
1201+ expected_prefix , out
1202+ )
1203+ )
1204+
1205+ # If the listener expanded into multiple addresses, use the first.
1206+ connection = (
1207+ out .removeprefix (expected_prefix ).rstrip ("\r \n " ).split ("," , 1 )[0 ]
1208+ )
1209+
1210+ if connection .startswith ("unix-connect://" ): # unix-connect:///path
1211+ s = socket .socket (socket .AF_UNIX , socket .SOCK_STREAM )
1212+ s .connect (connection .removeprefix ("unix-connect://" ))
1213+ elif connection .startswith ("connection://" ): # connection://[host]:port
1214+ host , port = connection .removeprefix ("connection://" ).rsplit (":" , 1 )
1215+ # create_connection with try both ipv4 and ipv6.
1216+ s = socket .create_connection ((host .strip ("[]" ), int (port )))
1217+ else :
1218+ raise ValueError ("invalid connection: {}" .format (connection ))
11771219 DebugCommunication .__init__ (
1178- self , self . process . stdout , self . process . stdin , init_commands , log_file
1220+ self , s . makefile ( "rb" ), s . makefile ( "wb" ) , init_commands , log_file
11791221 )
1180- elif port is not None :
1181- s = socket .socket (socket .AF_INET , socket .SOCK_STREAM )
1182- s .connect (("127.0.0.1" , port ))
1222+ self .connection = connection
1223+ else :
11831224 DebugCommunication .__init__ (
1184- self , s . makefile ( "r" ), s . makefile ( "w" ) , init_commands
1225+ self , self . process . stdout , self . process . stdin , init_commands , log_file
11851226 )
11861227
11871228 def get_pid (self ):
0 commit comments