mirror of
https://github.com/microsoft/debugpy.git
synced 2025-12-23 08:48:12 +00:00
Use "connect":{...} and "listen":{...} to indicate direction of connection in debug configuration.
This commit is contained in:
parent
2d013e58ec
commit
dccb5e6198
6 changed files with 83 additions and 47 deletions
|
|
@ -284,10 +284,43 @@ class Client(components.Component):
|
||||||
if self.session.no_debug:
|
if self.session.no_debug:
|
||||||
raise request.isnt_valid('"noDebug" is not supported for "attach"')
|
raise request.isnt_valid('"noDebug" is not supported for "attach"')
|
||||||
|
|
||||||
listen = request("listen", False)
|
host = request("host", unicode, optional=True)
|
||||||
if listen:
|
port = request("port", int, optional=True)
|
||||||
host = request("host", "127.0.0.1")
|
listen = request("listen", dict, optional=True)
|
||||||
port = request("port", int)
|
connect = request("connect", dict, optional=True)
|
||||||
|
pid = request("processId", (int, unicode), optional=True)
|
||||||
|
sub_pid = request("subProcessId", int, optional=True)
|
||||||
|
|
||||||
|
if host != () or port != ():
|
||||||
|
if listen != ():
|
||||||
|
raise request.isnt_valid(
|
||||||
|
'"listen" and "host"/"port" are mutually exclusive'
|
||||||
|
)
|
||||||
|
if connect != ():
|
||||||
|
raise request.isnt_valid(
|
||||||
|
'"connect" and "host"/"port" are mutually exclusive'
|
||||||
|
)
|
||||||
|
if listen != ():
|
||||||
|
if connect != ():
|
||||||
|
raise request.isnt_valid(
|
||||||
|
'"listen" and "connect" are mutually exclusive'
|
||||||
|
)
|
||||||
|
if pid != ():
|
||||||
|
raise request.isnt_valid(
|
||||||
|
'"listen" and "processId" are mutually exclusive'
|
||||||
|
)
|
||||||
|
if sub_pid != ():
|
||||||
|
raise request.isnt_valid(
|
||||||
|
'"listen" and "subProcessId" are mutually exclusive'
|
||||||
|
)
|
||||||
|
if pid != () and sub_pid != ():
|
||||||
|
raise request.isnt_valid(
|
||||||
|
'"processId" and "subProcessId" are mutually exclusive'
|
||||||
|
)
|
||||||
|
|
||||||
|
if listen != ():
|
||||||
|
host = listen("host", "127.0.0.1")
|
||||||
|
port = listen("port", int)
|
||||||
adapter.access_token = None
|
adapter.access_token = None
|
||||||
host, port = servers.serve(host, port)
|
host, port = servers.serve(host, port)
|
||||||
else:
|
else:
|
||||||
|
|
@ -303,30 +336,22 @@ class Client(components.Component):
|
||||||
# in response to a "debugpyAttach" event. If so, the debug server should be
|
# in response to a "debugpyAttach" event. If so, the debug server should be
|
||||||
# connected already, and thus the wait timeout is zero.
|
# connected already, and thus the wait timeout is zero.
|
||||||
#
|
#
|
||||||
# If neither is specified, and "listen" is true, this is attach-by-socket
|
# If "listen" is specified, this is attach-by-socket with the server expected
|
||||||
# with the server expected to connect to the adapter via debugpy.connect(). There
|
# to connect to the adapter via debugpy.connect(). There is no PID known in
|
||||||
# is no PID known in advance, so just wait until the first server connection
|
# advance, so just wait until the first server connection indefinitely, with
|
||||||
# indefinitely, with no timeout.
|
# no timeout.
|
||||||
#
|
#
|
||||||
# If neither is specified, and "listen" is false, this is attach-by-socket
|
# If "connect" is specified, this is attach-by-socket in which the server has
|
||||||
# in which the server has spawned the adapter via debugpy.listen(). There
|
# spawned the adapter via debugpy.listen(). There is no PID known to the client
|
||||||
# is no PID known to the client in advance, but the server connection should be
|
# in advance, but the server connection should be either be there already, or
|
||||||
# either be there already, or the server should be connecting shortly, so there
|
# the server should be connecting shortly, so there must be a timeout.
|
||||||
# must be a timeout.
|
|
||||||
#
|
#
|
||||||
# In the last two cases, if there's more than one server connection already,
|
# In the last two cases, if there's more than one server connection already,
|
||||||
# this is a multiprocess re-attach. The client doesn't know the PID, so we just
|
# this is a multiprocess re-attach. The client doesn't know the PID, so we just
|
||||||
# connect it to the oldest server connection that we have - in most cases, it
|
# connect it to the oldest server connection that we have - in most cases, it
|
||||||
# will be the one for the root debuggee process, but if it has exited already,
|
# will be the one for the root debuggee process, but if it has exited already,
|
||||||
# it will be some subprocess.
|
# it will be some subprocess.
|
||||||
|
|
||||||
pid = request("processId", (int, unicode), optional=True)
|
|
||||||
sub_pid = request("subProcessId", int, optional=True)
|
|
||||||
if pid != ():
|
if pid != ():
|
||||||
if sub_pid != ():
|
|
||||||
raise request.isnt_valid(
|
|
||||||
'"processId" and "subProcessId" are mutually exclusive'
|
|
||||||
)
|
|
||||||
if not isinstance(pid, int):
|
if not isinstance(pid, int):
|
||||||
try:
|
try:
|
||||||
pid = int(pid)
|
pid = int(pid)
|
||||||
|
|
@ -339,7 +364,7 @@ class Client(components.Component):
|
||||||
else:
|
else:
|
||||||
if sub_pid == ():
|
if sub_pid == ():
|
||||||
pred = lambda conn: True
|
pred = lambda conn: True
|
||||||
timeout = None if listen else 10
|
timeout = 10 if listen == () else None
|
||||||
else:
|
else:
|
||||||
pred = lambda conn: conn.pid == sub_pid
|
pred = lambda conn: conn.pid == sub_pid
|
||||||
timeout = 0
|
timeout = 0
|
||||||
|
|
@ -447,16 +472,21 @@ class Client(components.Component):
|
||||||
self._known_subprocesses.add(conn)
|
self._known_subprocesses.add(conn)
|
||||||
|
|
||||||
body.pop("processId", None)
|
body.pop("processId", None)
|
||||||
if body.pop("listen", False):
|
body.pop("listen", None)
|
||||||
body.pop("host", None)
|
|
||||||
body.pop("port", None)
|
|
||||||
body["name"] = fmt("Subprocess {0}", conn.pid)
|
body["name"] = fmt("Subprocess {0}", conn.pid)
|
||||||
body["request"] = "attach"
|
body["request"] = "attach"
|
||||||
body["subProcessId"] = conn.pid
|
body["subProcessId"] = conn.pid
|
||||||
if "host" not in body:
|
|
||||||
body["host"] = "127.0.0.1"
|
host = body.pop("host", None)
|
||||||
if "port" not in body:
|
port = body.pop("port", None)
|
||||||
_, body["port"] = listener.getsockname()
|
if "connect" not in body:
|
||||||
|
body["connect"] = {}
|
||||||
|
if "host" not in body["connect"]:
|
||||||
|
body["connect"]["host"] = host if host is not None else "127.0.0.1"
|
||||||
|
if "port" not in body["connect"]:
|
||||||
|
if port is None:
|
||||||
|
_, port = listener.getsockname()
|
||||||
|
body["connect"]["port"] = port
|
||||||
|
|
||||||
self.channel.send_event("debugpyAttach", body)
|
self.channel.send_event("debugpyAttach", body)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,9 +63,8 @@ class DebugConfig(collections.MutableMapping):
|
||||||
"waitOnNormalExit": False,
|
"waitOnNormalExit": False,
|
||||||
"waitOnAbnormalExit": False,
|
"waitOnAbnormalExit": False,
|
||||||
# Attach by socket
|
# Attach by socket
|
||||||
"host": (),
|
"listen": (),
|
||||||
"port": (),
|
"connect": (),
|
||||||
"listen": False,
|
|
||||||
# Attach by PID
|
# Attach by PID
|
||||||
"processId": (),
|
"processId": (),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -215,8 +215,9 @@ def attach_connect(session, target, method, cwd=None, wait=True, log_dir=None):
|
||||||
assert method in ("api", "cli")
|
assert method in ("api", "cli")
|
||||||
|
|
||||||
config = _attach_common_config(session, target, cwd)
|
config = _attach_common_config(session, target, cwd)
|
||||||
config["host"] = host = attach_connect.host
|
config["connect"] = {}
|
||||||
config["port"] = port = attach_connect.port
|
config["connect"]["host"] = host = attach_connect.host
|
||||||
|
config["connect"]["port"] = port = attach_connect.port
|
||||||
|
|
||||||
if method == "cli":
|
if method == "cli":
|
||||||
args = [
|
args = [
|
||||||
|
|
@ -267,9 +268,9 @@ def attach_listen(session, target, method, cwd=None, log_dir=None):
|
||||||
assert method in ("api", "cli")
|
assert method in ("api", "cli")
|
||||||
|
|
||||||
config = _attach_common_config(session, target, cwd)
|
config = _attach_common_config(session, target, cwd)
|
||||||
config["listen"] = True
|
config["listen"] = {}
|
||||||
config["host"] = host = attach_listen.host
|
config["listen"]["host"] = host = attach_listen.host
|
||||||
config["port"] = port = attach_listen.port
|
config["listen"]["port"] = port = attach_listen.port
|
||||||
|
|
||||||
if method == "cli":
|
if method == "cli":
|
||||||
args = [
|
args = [
|
||||||
|
|
|
||||||
|
|
@ -432,8 +432,8 @@ class Session(object):
|
||||||
config = self.config
|
config = self.config
|
||||||
request = config.get("request", None)
|
request = config.get("request", None)
|
||||||
if request == "attach":
|
if request == "attach":
|
||||||
host = config["host"]
|
host = config["connect"]["host"]
|
||||||
port = config["port"]
|
port = config["connect"]["port"]
|
||||||
self.connect_to_adapter((host, port))
|
self.connect_to_adapter((host, port))
|
||||||
return self.request_attach()
|
return self.request_attach()
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ def test_attach_api(pyfile, target, wait_for_client, is_client_connected, stop_m
|
||||||
|
|
||||||
with debug.Session() as session:
|
with debug.Session() as session:
|
||||||
host, port = runners.attach_connect.host, runners.attach_connect.port
|
host, port = runners.attach_connect.host, runners.attach_connect.port
|
||||||
session.config.update({"host": host, "port": port})
|
session.config.update({"connect": {"host": host, "port": port}})
|
||||||
|
|
||||||
backchannel = session.open_backchannel()
|
backchannel = session.open_backchannel()
|
||||||
session.spawn_debuggee(
|
session.spawn_debuggee(
|
||||||
|
|
@ -128,9 +128,9 @@ def test_reattach(pyfile, target, run):
|
||||||
|
|
||||||
with debug.Session() as session2:
|
with debug.Session() as session2:
|
||||||
session2.config.update(session1.config)
|
session2.config.update(session1.config)
|
||||||
if "host" in session2.config:
|
if "connect" in session2.config:
|
||||||
session2.connect_to_adapter(
|
session2.connect_to_adapter(
|
||||||
(session2.config["host"], session2.config["port"])
|
(session2.config["connect"]["host"], session2.config["connect"]["port"])
|
||||||
)
|
)
|
||||||
|
|
||||||
with session2.request_attach():
|
with session2.request_attach():
|
||||||
|
|
|
||||||
|
|
@ -109,8 +109,10 @@ def test_multiprocessing(pyfile, target, run, start_method):
|
||||||
"name": some.str,
|
"name": some.str,
|
||||||
"request": "attach",
|
"request": "attach",
|
||||||
"subProcessId": some.int,
|
"subProcessId": some.int,
|
||||||
"host": some.str,
|
"connect": {
|
||||||
"port": some.int,
|
"host": some.str,
|
||||||
|
"port": some.int,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -129,8 +131,10 @@ def test_multiprocessing(pyfile, target, run, start_method):
|
||||||
"name": some.str,
|
"name": some.str,
|
||||||
"request": "attach",
|
"request": "attach",
|
||||||
"subProcessId": some.int,
|
"subProcessId": some.int,
|
||||||
"host": some.str,
|
"connect": {
|
||||||
"port": some.int,
|
"host": some.str,
|
||||||
|
"port": some.int,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -191,8 +195,10 @@ def test_subprocess(pyfile, target, run):
|
||||||
"name": some.str,
|
"name": some.str,
|
||||||
"request": "attach",
|
"request": "attach",
|
||||||
"subProcessId": some.int,
|
"subProcessId": some.int,
|
||||||
"host": some.str,
|
"connect": {
|
||||||
"port": some.int,
|
"host": some.str,
|
||||||
|
"port": some.int,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue