diff --git a/setup.cfg b/setup.cfg index 88336d05..a109d40d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,5 @@ [metadata] -license_file = LICENSE +license_files = LICENSE [versioneer] VCS = git @@ -10,4 +10,4 @@ tag_prefix = v parentdir_prefix = debugpy- [aliases] -test=pytest +test = pytest diff --git a/src/debugpy/adapter/clients.py b/src/debugpy/adapter/clients.py index bc4bc50a..82985e60 100644 --- a/src/debugpy/adapter/clients.py +++ b/src/debugpy/adapter/clients.py @@ -470,12 +470,16 @@ class Client(components.Component): ) if listen != (): + if servers.is_serving(): + raise request.isnt_valid('Multiple concurrent "listen" sessions are not supported') host = listen("host", "127.0.0.1") port = listen("port", int) adapter.access_token = None host, port = servers.serve(host, port) else: - host, port = servers.serve() + if not servers.is_serving(): + servers.serve() + host, port = servers.listener.getsockname() # There are four distinct possibilities here. # diff --git a/src/debugpy/adapter/servers.py b/src/debugpy/adapter/servers.py index 176c4b0e..b860558c 100644 --- a/src/debugpy/adapter/servers.py +++ b/src/debugpy/adapter/servers.py @@ -19,6 +19,9 @@ from debugpy.adapter import components access_token = None """Access token used to authenticate with the servers.""" +listener = None +"""Listener socket that accepts server connections.""" + _lock = threading.RLock() _connections = [] @@ -433,9 +436,16 @@ def serve(host="127.0.0.1", port=0): return listener.getsockname() +def is_serving(): + return listener is not None + + def stop_serving(): + global listener try: - listener.close() + if listener is not None: + listener.close() + listener = None except Exception: log.swallow_exception(level="warning") diff --git a/src/debugpy/common/log.py b/src/debugpy/common/log.py index 80003b53..2859dc20 100644 --- a/src/debugpy/common/log.py +++ b/src/debugpy/common/log.py @@ -339,6 +339,7 @@ def describe_environment(header): report_paths("os.__file__") report_paths("threading.__file__") + report_paths("debugpy.__file__") result = "".join(result).rstrip("\n") info("{0}", result) @@ -376,3 +377,8 @@ def _vars(*names): # pragma: no cover def _stack(): # pragma: no cover stack = "\n".join(traceback.format_stack()) warning("$STACK:\n\n{0}", stack) + + +def _threads(): # pragma: no cover + output = "\n".join([str(t) for t in threading.enumerate()]) + warning("$THREADS:\n\n{0}", output)