def for_popen(self):
     """Returns a copy of this dict, with all strings converted to the type
     suitable for subprocess.Popen() and other similar APIs.
     """
     return {
         compat.filename_str(k): compat.filename_str(v)
         for k, v in self.items()
     }
Beispiel #2
0
    def spawn_debuggee(self,
                       args,
                       cwd=None,
                       exe=sys.executable,
                       debug_me=None):
        assert self.debuggee is None
        assert not len(self.captured_output - {"stdout", "stderr"})

        args = [exe] + [
            compat.filename_str(
                s.strpath if isinstance(s, py.path.local) else s) for s in args
        ]

        cwd = compat.filename_str(cwd) if isinstance(cwd,
                                                     py.path.local) else cwd

        env = self._make_env(self.spawn_debuggee.env, codecov=False)
        env["PTVSD_ADAPTER_ENDPOINTS"] = self.adapter_endpoints = (
            self.tmpdir / "adapter_endpoints")
        if debug_me is not None:
            env["PTVSD_TEST_DEBUG_ME"] = debug_me

        log.info(
            "Spawning {0}:\n\n"
            "Current directory: {1!j}\n\n"
            "Command line: {2!j}\n\n"
            "Environment variables: {3!j}\n\n",
            self.debuggee_id,
            cwd,
            args,
            env,
        )

        popen_fds = {}
        capture_fds = {}
        for stream_name in self.captured_output:
            rfd, wfd = os.pipe()
            popen_fds[stream_name] = wfd
            capture_fds[stream_name] = rfd
        self.debuggee = psutil.Popen(args,
                                     cwd=cwd,
                                     env=env.for_popen(),
                                     bufsize=0,
                                     stdin=subprocess.PIPE,
                                     **popen_fds)
        log.info("Spawned {0} with PID={1}", self.debuggee_id,
                 self.debuggee.pid)
        watchdog.register_spawn(self.debuggee.pid, self.debuggee_id)

        if len(capture_fds):
            self.captured_output = output.CapturedOutput(self, **capture_fds)
        for fd in popen_fds.values():
            os.close(fd)
Beispiel #3
0
    def spawn_debuggee(self,
                       args,
                       cwd=None,
                       exe=sys.executable,
                       debug_me=None):
        assert self.debuggee is None

        args = [exe] + [
            compat.filename_str(
                s.strpath if isinstance(s, py.path.local) else s) for s in args
        ]

        cwd = compat.filename_str(cwd) if isinstance(cwd,
                                                     py.path.local) else cwd

        env = self._make_env(self.spawn_debuggee.env, codecov=False)
        env["PTVSD_LISTENER_FILE"] = self.listener_file = self.tmpdir / "listener"
        if debug_me is not None:
            env["PTVSD_TEST_DEBUG_ME"] = debug_me

        log.info(
            "Spawning {0}:\n\n"
            "Current directory: {1!j}\n\n"
            "Command line: {2!j}\n\n"
            "Environment variables: {3!j}\n\n",
            self.debuggee_id,
            cwd,
            args,
            env,
        )
        self.debuggee = psutil.Popen(
            args,
            cwd=cwd,
            env=env.for_popen(),
            bufsize=0,
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
        )
        log.info("Spawned {0} with PID={1}", self.debuggee_id,
                 self.debuggee.pid)
        watchdog.register_spawn(self.debuggee.pid, self.debuggee_id)

        if self.captured_output:
            self.captured_output = output.CapturedOutput(self)
Beispiel #4
0
def attach_by_socket(session,
                     target,
                     method,
                     listener="server",
                     cwd=None,
                     wait=True,
                     log_dir=None):
    log.info("Attaching {0} to {1} by socket using {2}.", session, target,
             method.upper())

    assert method in ("api", "cli")
    assert listener in ("server")  # TODO: ("adapter", "server")

    config = _attach_common_config(session, target, cwd)

    host = config["host"] = attach_by_socket.host
    port = config["port"] = attach_by_socket.port

    if method == "cli":
        args = [os.path.dirname(ptvsd.__file__)]
        if wait:
            args += ["--wait"]
        args += ["--host", compat.filename_str(host), "--port", str(port)]
        if not config["subProcess"]:
            args += ["--no-subprocesses"]
        if log_dir is not None:
            args += ["--log-dir", log_dir]
        debug_me = None
    elif method == "api":
        args = []
        debug_me = """
import ptvsd
ptvsd.enable_attach(({host!r}, {port!r}), {args})
if {wait!r}:
    ptvsd.wait_for_attach()
"""
        attach_args = "" if log_dir is None else fmt("log_dir={0!r}", log_dir)
        debug_me = fmt(debug_me,
                       host=host,
                       port=port,
                       wait=wait,
                       args=attach_args)
    else:
        raise ValueError
    args += target.cli(session.spawn_debuggee.env)

    session.spawn_debuggee(args, cwd=cwd, debug_me=debug_me)
    if wait:
        session.wait_for_enable_attach()

    session.connect_to_adapter((host, port))
    return session.request_attach()
Beispiel #5
0
    def spawn_launcher():
        with session.accept_connection_from_launcher() as (_, launcher_port):
            env[str("PTVSD_LAUNCHER_PORT")] = str(launcher_port)
            if common_options.log_dir is not None:
                env[str("PTVSD_LOG_DIR")] = compat.filename_str(
                    common_options.log_dir)
            if adapter_options.log_stderr:
                env[str("PTVSD_LOG_STDERR")] = str("debug info warning error")

            if console == "internalConsole":
                log.info("{0} spawning launcher: {1!r}", session, cmdline)

                # If we are talking to the IDE over stdio, sys.stdin and sys.stdout are
                # redirected to avoid mangling the DAP message stream. Make sure the
                # launcher also respects that.
                subprocess.Popen(
                    cmdline,
                    env=dict(list(os.environ.items()) + list(env.items())),
                    stdin=sys.stdin,
                    stdout=sys.stdout,
                    stderr=sys.stderr,
                )

            else:
                log.info('{0} spawning launcher via "runInTerminal" request.',
                         session)
                session.ide.capabilities.require(
                    "supportsRunInTerminalRequest")
                kinds = {
                    "integratedTerminal": "integrated",
                    "externalTerminal": "external",
                }
                session.ide.channel.request(
                    "runInTerminal",
                    {
                        "kind": kinds[console],
                        "title": console_title,
                        "args": cmdline,
                        "env": env,
                    },
                )

        try:
            session.launcher.channel.request(start_request.command, arguments)
        except messaging.MessageHandlingError as exc:
            exc.propagate(start_request)
Beispiel #6
0
 def __str__(self):
     return compat.filename_str(self.path)