def connect_to_adapter(self, address): assert self.channel is None host, port = address log.info("Connecting to {0} at {1}:{2}", self.adapter_id, host, port) sock = sockets.create_client() sock.connect(address) stream = messaging.JsonIOStream.from_socket(sock, name=self.adapter_id) self._start_channel(stream)
def connect(launcher_port): from debugpy.common import messaging, sockets from debugpy.launcher import handlers global channel assert channel is None sock = sockets.create_client() sock.connect(("127.0.0.1", launcher_port)) stream = messaging.JsonIOStream.from_socket(sock, "Adapter") channel = messaging.JsonMessageChannel(stream, handlers=handlers) channel.start()
def connect(host, port): from debugpy.common import log, messaging, sockets from debugpy.launcher import handlers global channel, adapter_host assert channel is None assert adapter_host is None log.info("Connecting to adapter at {0}:{1}", host, port) sock = sockets.create_client() sock.connect((host, port)) adapter_host = host stream = messaging.JsonIOStream.from_socket(sock, "Adapter") channel = messaging.JsonMessageChannel(stream, handlers=handlers) channel.start()
def main(args): # If we're talking DAP over stdio, stderr is not guaranteed to be read from, # so disable it to avoid the pipe filling and locking up. This must be done # as early as possible, before the logging module starts writing to it. if args.port is None: sys.stderr = open(os.devnull, "w") from debugpy import adapter from debugpy.common import compat, log, sockets from debugpy.adapter import clients, servers, sessions if args.for_server is not None: if os.name == "posix": # On POSIX, we need to leave the process group and its session, and then # daemonize properly by double-forking (first fork already happened when # this process was spawned). os.setsid() if os.fork() != 0: sys.exit(0) for stdio in sys.stdin, sys.stdout, sys.stderr: if stdio is not None: stdio.close() if args.log_stderr: log.stderr.levels |= set(log.LEVELS) if args.log_dir is not None: log.log_dir = args.log_dir log.to_file(prefix="debugpy.adapter") log.describe_environment("debugpy.adapter startup environment:") servers.access_token = args.server_access_token if args.for_server is None: adapter.access_token = compat.force_str( codecs.encode(os.urandom(32), "hex")) endpoints = {} try: client_host, client_port = clients.serve(args.host, args.port) except Exception as exc: if args.for_server is None: raise endpoints = { "error": "Can't listen for client connections: " + str(exc) } else: endpoints["client"] = {"host": client_host, "port": client_port} if args.for_server is not None: try: server_host, server_port = servers.serve() except Exception as exc: endpoints = { "error": "Can't listen for server connections: " + str(exc) } else: endpoints["server"] = {"host": server_host, "port": server_port} log.info( "Sending endpoints info to debug server at localhost:{0}:\n{1!j}", args.for_server, endpoints, ) try: sock = sockets.create_client() try: sock.settimeout(None) sock.connect(("127.0.0.1", args.for_server)) sock_io = sock.makefile("wb", 0) try: sock_io.write(json.dumps(endpoints).encode("utf-8")) finally: sock_io.close() finally: sockets.close_socket(sock) except Exception: log.reraise_exception( "Error sending endpoints info to debug server:") if "error" in endpoints: log.error("Couldn't set up endpoints; exiting.") sys.exit(1) listener_file = os.getenv("DEBUGPY_ADAPTER_ENDPOINTS") if listener_file is not None: log.info("Writing endpoints info to {0!r}:\n{1!j}", listener_file, endpoints) def delete_listener_file(): log.info("Listener ports closed; deleting {0!r}", listener_file) try: os.remove(listener_file) except Exception: log.swallow_exception("Failed to delete {0!r}", listener_file, level="warning") try: with open(listener_file, "w") as f: atexit.register(delete_listener_file) print(json.dumps(endpoints), file=f) except Exception: log.reraise_exception("Error writing endpoints info to file:") if args.port is None: clients.Client("stdio") # These must be registered after the one above, to ensure that the listener sockets # are closed before the endpoint info file is deleted - this way, another process # can wait for the file to go away as a signal that the ports are no longer in use. atexit.register(servers.stop_serving) atexit.register(clients.stop_serving) servers.wait_until_disconnected() log.info( "All debug servers disconnected; waiting for remaining sessions...") sessions.wait_until_ended() log.info("All debug sessions have ended; exiting.")
def start_client(self): self._client_socket = create_client() self._client_socket.connect(("127.0.0.1", self._adapter_args.port)) self._client_stream = JsonIOStream.from_socket(self._client_socket)