mirror of
https://github.com/microsoft/debugpy.git
synced 2025-12-23 08:48:12 +00:00
Attach to pid support (#1701)
* Fix launcher test * Attach to pid support * Address comments. * Minor tweaks
This commit is contained in:
parent
e94980f86c
commit
9ece432dff
3 changed files with 82 additions and 4 deletions
|
|
@ -80,6 +80,48 @@ def spawn_and_connect(request):
|
|||
before_accept=lambda address: _parse_request_and_spawn(request, address),
|
||||
)
|
||||
|
||||
def attach_by_pid(request):
|
||||
"""Start server to receive connection from the debug server injected into the
|
||||
debuggee process.
|
||||
"""
|
||||
def _parse_request_and_inject(request, address):
|
||||
cmdline = [sys.executable]
|
||||
|
||||
host, port = address
|
||||
ptvsd_args = request("ptvsdArgs", json.array(unicode))
|
||||
cmdline += [
|
||||
compat.filename(ptvsd.__main__.__file__),
|
||||
"--client",
|
||||
"--host",
|
||||
host,
|
||||
"--port",
|
||||
str(port),
|
||||
"--pid",
|
||||
str(request("processId", int))
|
||||
] + ptvsd_args
|
||||
|
||||
log.debug("Launching debugger injector: {0!r}", cmdline)
|
||||
|
||||
try:
|
||||
# This process will immediately exit after injecting debug server
|
||||
proc = subprocess.Popen(
|
||||
cmdline,
|
||||
bufsize=0,
|
||||
)
|
||||
except Exception as exc:
|
||||
raise request.cant_handle("Error launching debug process: {0}", exc)
|
||||
proc.wait()
|
||||
if proc.returncode != 0:
|
||||
raise request.cant_handle(
|
||||
"Failed to inject debugger with error code: {0}",
|
||||
proc.returncode,
|
||||
)
|
||||
|
||||
channels.Channels().accept_connection_from_server(
|
||||
("127.0.0.1", 0),
|
||||
before_accept=lambda address: _parse_request_and_inject(address),
|
||||
)
|
||||
|
||||
|
||||
def _parse_request_and_spawn(request, address):
|
||||
spawn_info = _parse_request(request, address)
|
||||
|
|
|
|||
|
|
@ -199,9 +199,12 @@ class IDEMessages(Messages):
|
|||
_Shared.readonly_attrs.add("terminate_on_disconnect")
|
||||
self._debug_config(request)
|
||||
|
||||
options.host = request("host", options.host)
|
||||
options.port = request("port", options.port)
|
||||
_channels.connect_to_server(address=(options.host, options.port))
|
||||
if "processId" in request:
|
||||
debuggee.attach_by_pid(request)
|
||||
else:
|
||||
options.host = request("host", options.host)
|
||||
options.port = request("port", options.port)
|
||||
_channels.connect_to_server(address=(options.host, options.port))
|
||||
|
||||
return self._configure(request)
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import errno
|
|||
import os.path
|
||||
import platform
|
||||
import pytest
|
||||
import socket
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
|
@ -17,10 +18,31 @@ from ptvsd.common import launcher
|
|||
launcher_py = os.path.abspath(launcher.__file__)
|
||||
|
||||
|
||||
class ReceivePid(object):
|
||||
def start_server(self):
|
||||
self.listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.listener.bind(("127.0.0.1", 0))
|
||||
self.listener.listen(1)
|
||||
self.host, self.port = self.listener.getsockname()
|
||||
return (self.host, self.port)
|
||||
|
||||
def wait_for_pid(self):
|
||||
try:
|
||||
sock, _ = self.listener.accept()
|
||||
finally:
|
||||
self.listener.close()
|
||||
try:
|
||||
data = sock.makefile().read()
|
||||
finally:
|
||||
sock.close()
|
||||
return -1 if data == b"" else int(data)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("run_as", ["program", "module", "code"])
|
||||
@pytest.mark.parametrize("mode", ["normal", "abnormal", "normal+abnormal", ""])
|
||||
@pytest.mark.parametrize("seperator", ["seperator", ""])
|
||||
def test_launcher_parser(mode, seperator, run_as):
|
||||
@pytest.mark.parametrize("port", ["12345", ""])
|
||||
def test_launcher_parser(mode, seperator, run_as, port):
|
||||
args = []
|
||||
|
||||
switch = mode.split("+")
|
||||
|
|
@ -31,9 +53,13 @@ def test_launcher_parser(mode, seperator, run_as):
|
|||
if "abnormal" in switch:
|
||||
args += [launcher.WAIT_ON_ABNORMAL_SWITCH]
|
||||
|
||||
if port:
|
||||
args += [launcher.INTERNAL_PORT_SWITCH, port]
|
||||
|
||||
if seperator:
|
||||
args += ["--"]
|
||||
|
||||
|
||||
if run_as == "file":
|
||||
expected = ["myscript.py", "--arg1", "--arg2", "--arg3", "--", "more args"]
|
||||
elif run_as == "module":
|
||||
|
|
@ -67,12 +93,17 @@ def test_launcher(pyfile, mode, exit_code, run_as):
|
|||
|
||||
switch = mode.split("+")
|
||||
|
||||
pid_server = ReceivePid()
|
||||
_, port = pid_server.start_server()
|
||||
|
||||
if "normal" in switch:
|
||||
args += [launcher.WAIT_ON_NORMAL_SWITCH]
|
||||
|
||||
if "abnormal" in switch:
|
||||
args += [launcher.WAIT_ON_ABNORMAL_SWITCH]
|
||||
|
||||
args += [launcher.INTERNAL_PORT_SWITCH, str(port)]
|
||||
|
||||
args += ["--"]
|
||||
|
||||
if run_as == "file":
|
||||
|
|
@ -110,6 +141,8 @@ def test_launcher(pyfile, mode, exit_code, run_as):
|
|||
stdout=subprocess.PIPE,
|
||||
)
|
||||
|
||||
assert pid_server.wait_for_pid() >= -1
|
||||
|
||||
if wait_for_user:
|
||||
outstr = b""
|
||||
while not outstr.endswith(b". . . "):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue