diff --git a/src/debugpy/adapter/clients.py b/src/debugpy/adapter/clients.py index 3351118f7..e1bc417f9 100644 --- a/src/debugpy/adapter/clients.py +++ b/src/debugpy/adapter/clients.py @@ -8,7 +8,7 @@ import sys import debugpy -from debugpy import adapter, launcher +from debugpy import adapter, common, launcher from debugpy.common import compat, fmt, json, log, messaging, sockets from debugpy.common.compat import unicode from debugpy.adapter import components, servers, sessions @@ -436,12 +436,12 @@ def attach_request(self, request): raise request.isnt_valid('"processId" must be parseable as int') debugpy_args = request("debugpyArgs", json.array(unicode)) servers.inject(pid, debugpy_args) - timeout = 10 + timeout = common.PROCESS_SPAWN_TIMEOUT pred = lambda conn: conn.pid == pid else: if sub_pid == (): pred = lambda conn: True - timeout = 10 if listen == () else None + timeout = common.PROCESS_SPAWN_TIMEOUT if listen == () else None else: pred = lambda conn: conn.pid == sub_pid timeout = 0 diff --git a/src/debugpy/adapter/launchers.py b/src/debugpy/adapter/launchers.py index 65cc043a2..00ba945da 100644 --- a/src/debugpy/adapter/launchers.py +++ b/src/debugpy/adapter/launchers.py @@ -8,7 +8,7 @@ import subprocess import sys -from debugpy import adapter +from debugpy import adapter, common from debugpy.common import compat, fmt, log, messaging, sockets from debugpy.adapter import components, servers @@ -162,7 +162,7 @@ def on_launcher_connected(sock): # If using sudo, it might prompt for password, and launcher won't start running # until the user enters it, so don't apply timeout in that case. if not session.wait_for( - lambda: session.launcher, timeout=(None if sudo else 10) + lambda: session.launcher, timeout=(None if sudo else common.PROCESS_SPAWN_TIMEOUT) ): raise start_request.cant_handle("Timed out waiting for launcher to connect") @@ -174,14 +174,14 @@ def on_launcher_connected(sock): if session.no_debug: return - if not session.wait_for(lambda: session.launcher.pid is not None, timeout=10): + if not session.wait_for(lambda: session.launcher.pid is not None, timeout=common.PROCESS_SPAWN_TIMEOUT): raise start_request.cant_handle( 'Timed out waiting for "process" event from launcher' ) # Wait for the first incoming connection regardless of the PID - it won't # necessarily match due to the use of stubs like py.exe or "conda run". - conn = servers.wait_for_connection(session, lambda conn: True, timeout=10) + conn = servers.wait_for_connection(session, lambda conn: True, timeout=common.PROCESS_SPAWN_TIMEOUT) if conn is None: raise start_request.cant_handle("Timed out waiting for debuggee to spawn") conn.attach_to_session(session) diff --git a/src/debugpy/adapter/sessions.py b/src/debugpy/adapter/sessions.py index 8287fc700..62a316a6a 100644 --- a/src/debugpy/adapter/sessions.py +++ b/src/debugpy/adapter/sessions.py @@ -10,6 +10,7 @@ import threading import time +from debugpy import common from debugpy.common import fmt, log, util from debugpy.adapter import components, launchers, servers @@ -197,7 +198,8 @@ def _finalize(self, why, terminate_debuggee): if self.server: log.info('{0} waiting for "exited" event...', self) if not self.wait_for( - lambda: self.launcher.exit_code is not None, timeout=5 + lambda: self.launcher.exit_code is not None, + timeout=common.PROCESS_EXIT_TIMEOUT, ): log.warning('{0} timed out waiting for "exited" event.', self) diff --git a/src/debugpy/common/__init__.py b/src/debugpy/common/__init__.py index 2d77c3033..aead53f60 100644 --- a/src/debugpy/common/__init__.py +++ b/src/debugpy/common/__init__.py @@ -4,5 +4,13 @@ from __future__ import absolute_import, division, print_function, unicode_literals +import os + __all__ = [] + +# The lower time bound for assuming that the process hasn't spawned successfully. +PROCESS_SPAWN_TIMEOUT = os.getenv("DEBUGPY_PROCESS_SPAWN_TIMEOUT", 15) + +# The lower time bound for assuming that the process hasn't exited gracefully. +PROCESS_EXIT_TIMEOUT = os.getenv("DEBUGPY_PROCESS_EXIT_TIMEOUT", 5)