Ejemplo n.º 1
0
def inject(pid, ptvsd_args):
    host, port = Connection.listener.getsockname()

    cmdline = [
        sys.executable,
        compat.filename(os.path.dirname(ptvsd.__file__)),
        "--client",
        "--host",
        host,
        "--port",
        str(port),
    ]
    cmdline += ptvsd_args
    cmdline += ["--pid", str(pid)]

    log.info("Spawning attach-to-PID debugger injector: {0!r}", cmdline)
    try:
        subprocess.Popen(
            cmdline,
            bufsize=0,
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
        )
    except Exception as exc:
        log.exception(
            "Failed to inject debug server into process with PID={0}", pid)
        raise messaging.MessageHandlingError(
            "Failed to inject debug server into process with PID={0}: {1}",
            pid, exc)
    def inject_server(self, pid, ptvsd_args):
        with self.accept_connection_from_server() as (host, port):
            cmdline = [
                sys.executable,
                compat.filename(os.path.dirname(ptvsd.__file__)),
                "--client",
                "--host",
                host,
                "--port",
                str(port),
            ]
            cmdline += ptvsd_args
            cmdline += ["--pid", str(pid)]

            log.info("{0} spawning attach-to-PID debugger injector: {1!r}",
                     self, cmdline)

            try:
                subprocess.Popen(
                    cmdline,
                    bufsize=0,
                    stdin=subprocess.PIPE,
                    stdout=subprocess.PIPE,
                    stderr=subprocess.PIPE,
                )
            except Exception as exc:
                log.exception("{0} failed to inject debugger", self)
                raise messaging.MessageHandlingError(
                    fmt("Failed to inject debugger: {0}", exc))
Ejemplo n.º 3
0
def inject(pid, ptvsd_args):
    host, port = Connection.listener.getsockname()

    cmdline = [
        sys.executable,
        compat.filename(os.path.dirname(ptvsd.__file__)),
        "--client",
        "--host",
        host,
        "--port",
        str(port),
    ]
    if adapter.access_token is not None:
        cmdline += ["--client-access-token", adapter.access_token]
    cmdline += ptvsd_args
    cmdline += ["--pid", str(pid)]

    log.info("Spawning attach-to-PID debugger injector: {0!r}", cmdline)
    try:
        injector = subprocess.Popen(
            cmdline,
            bufsize=0,
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
        )
    except Exception as exc:
        log.exception("Failed to inject debug server into process with PID={0}", pid)
        raise messaging.MessageHandlingError(
            fmt(
                "Failed to inject debug server into process with PID={0}: {1}", pid, exc
            )
        )

    # We need to capture the output of the injector - otherwise it can get blocked
    # on a write() syscall when it tries to print something.

    def capture_output():
        while True:
            line = injector.stdout.readline()
            if not line:
                break
            log.info("Injector[PID={0}] output:\n{1}", pid, line.rstrip())
        log.info("Injector[PID={0}] exited.", pid)

    thread = threading.Thread(
        target=capture_output, name=fmt("Injector[PID={0}] output", pid)
    )
    thread.daemon = True
    thread.start()
Ejemplo n.º 4
0
def spawn(process_name, cmdline, cwd, env, redirect_output):
    log.info(
        "Spawning debuggee process:\n\n"
        "Current directory: {0!j}\n\n"
        "Command line: {1!j}\n\n"
        "Environment variables: {2!j}\n\n",
        cwd,
        cmdline,
        env,
    )

    close_fds = set()
    try:
        if redirect_output:
            # subprocess.PIPE behavior can vary substantially depending on Python version
            # and platform; using our own pipes keeps it simple, predictable, and fast.
            stdout_r, stdout_w = os.pipe()
            stderr_r, stderr_w = os.pipe()
            close_fds |= {stdout_r, stdout_w, stderr_r, stderr_w}
            kwargs = dict(stdout=stdout_w, stderr=stderr_w)
        else:
            kwargs = {}

        try:
            global process
            process = subprocess.Popen(cmdline,
                                       cwd=cwd,
                                       env=env,
                                       bufsize=0,
                                       **kwargs)
        except Exception as exc:
            raise messaging.MessageHandlingError(
                fmt("Couldn't spawn debuggee: {0}\n\nCommand line:{1!r}", exc,
                    cmdline))

        log.info("Spawned {0}.", describe())
        atexit.register(kill)
        launcher.channel.send_event(
            "process",
            {
                "startMethod": "launch",
                "isLocalProcess": True,
                "systemProcessId": process.pid,
                "name": process_name,
                "pointerSize": struct.calcsize(compat.force_str("P")) * 8,
            },
        )

        if redirect_output:
            for category, fd, tee in [
                ("stdout", stdout_r, sys.stdout),
                ("stderr", stderr_r, sys.stderr),
            ]:
                output.CaptureOutput(describe(), category, fd, tee)
                close_fds.remove(fd)

        wait_thread = threading.Thread(target=wait_for_exit,
                                       name="wait_for_exit()")
        wait_thread.daemon = True
        wait_thread.start()

    finally:
        for fd in close_fds:
            try:
                os.close(fd)
            except Exception:
                log.exception()
Ejemplo n.º 5
0
 def require(self, *keys):
     for key in keys:
         if not self[key]:
             raise messaging.MessageHandlingError(
                 fmt("{0} does not have capability {1!j}", self.component,
                     key))