def main(args): from ptvsd.common import log, options as common_options from ptvsd.adapter import ide, servers, sessions, options as adapter_options if args.log_stderr: log.stderr.levels |= set(log.LEVELS) adapter_options.log_stderr = True if args.log_dir is not None: common_options.log_dir = args.log_dir log.to_file(prefix="ptvsd.adapter") log.describe_environment("ptvsd.adapter startup environment:") if args.for_enable_attach and args.port is None: log.error("--for-enable-attach requires --port") sys.exit(64) server_host, server_port = servers.listen() ide_host, ide_port = ide.listen(port=args.port) if args.for_enable_attach: endpoints = { "ide": { "host": ide_host, "port": ide_port }, "server": { "host": server_host, "port": server_port }, } log.info("Sending endpoints to stdout: {0!r}", endpoints) print(json.dumps(endpoints)) sys.stdout.flush() if args.port is None: ide.IDE("stdio") 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 _dump_worker_log(command, problem, exc_info=None): reason = fmt("{0}.{1}() {2}", _name, command, problem) if _worker_log_filename is None: reason += ", but there is no log." else: try: with open(_worker_log_filename) as f: worker_log = f.read() except Exception: reason += fmt(", but log {0} could not be retrieved.", _worker_log_filename) else: reason += fmt("; watchdog worker process log:\n\n{0}", worker_log) if exc_info is None: log.error("{0}", reason) else: log.exception("{0}", reason, exc_info=exc_info) return reason
def expect_no_unobserved(self): if not self: return unobserved = [ occ for occ in self if not occ.observed and all( exp != occ for exp in self.timeline.ignore_unobserved) ] if not unobserved: return raise log.error( "Unobserved occurrences detected:\n\n{0}\n\nignoring unobserved:\n\n{1}", "\n\n".join(repr(occ) for occ in unobserved), "\n\n".join(repr(exp) for exp in self.timeline.ignore_unobserved), )
def __init__(self, *expectations): self.expectations = expectations assert len(expectations) > 0 assert all(isinstance(exp, Expectation) for exp in expectations) timelines = {id(exp.timeline): exp.timeline for exp in expectations} timelines.pop(id(None), None) if len(timelines) > 1: offending_expectations = "" for tl_id, tl in timelines.items(): offending_expectations += fmt("\n {0}: {1!r}\n", tl_id, tl) raise log.error( "Cannot mix expectations from multiple timelines:\n{0}", offending_expectations, ) for tl in timelines.values(): self.timeline = tl
def main(args): from ptvsd import adapter from ptvsd.common import compat, log, sockets from ptvsd.adapter import ide, 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="ptvsd.adapter") log.describe_environment("ptvsd.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")) try: server_host, server_port = servers.listen() except Exception as exc: if args.for_server is None: raise endpoints = { "error": "Can't listen for server connections: " + str(exc) } else: endpoints = {"server": {"host": server_host, "port": server_port}} try: ide_host, ide_port = ide.listen(port=args.port) except Exception as exc: if args.for_server is None: raise endpoints = { "error": "Can't listen for IDE connections: " + str(exc) } else: endpoints["ide"] = {"host": ide_host, "port": ide_port} if args.for_server is not None: 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: raise log.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("PTVSD_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.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: raise log.exception("Error writing endpoints info to file:") if args.port is None: ide.IDE("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_listening) atexit.register(ide.stop_listening) 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 main(args): from ptvsd import adapter from ptvsd.common import compat, log from ptvsd.adapter import ide, servers, sessions 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="ptvsd.adapter") log.describe_environment("ptvsd.adapter startup environment:") if args.for_server and args.port is None: log.error("--for-server requires --port") sys.exit(64) servers.access_token = args.server_access_token if not args.for_server: adapter.access_token = compat.force_str( codecs.encode(os.urandom(32), "hex")) server_host, server_port = servers.listen() ide_host, ide_port = ide.listen(port=args.port) endpoints_info = { "ide": { "host": ide_host, "port": ide_port }, "server": { "host": server_host, "port": server_port }, } if args.for_server: log.info("Writing endpoints info to stdout:\n{0!r}", endpoints_info) print(json.dumps(endpoints_info)) sys.stdout.flush() if args.port is None: ide.IDE("stdio") listener_file = os.getenv("PTVSD_ADAPTER_ENDPOINTS") if listener_file is not None: log.info("Writing endpoints info to {0!r}:\n{1!r}", listener_file, endpoints_info) def delete_listener_file(): log.info("Listener ports closed; deleting {0!r}", listener_file) try: os.remove(listener_file) except Exception: log.exception("Failed to delete {0!r}", listener_file, level="warning") with open(listener_file, "w") as f: atexit.register(delete_listener_file) print(json.dumps(endpoints_info), file=f) # 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_listening) atexit.register(ide.stop_listening) 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.")