Ejemplo n.º 1
0
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.")
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
    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),
        )
Ejemplo n.º 4
0
    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
Ejemplo n.º 5
0
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.")
Ejemplo n.º 6
0
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.")