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))
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()
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()
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))