@@ -50,9 +50,38 @@ def _pause_threads(unwinder, blocking):
5050# Maximum number of consecutive identical samples to keep before flushing.
5151MAX_PENDING_SAMPLES = 8192
5252
53+
54+ def _resolve_python_pid (pid ):
55+ """On Windows, if pid is a venvlauncher process, return the child Python PID.
56+
57+ The venvlauncher (used as python.exe in venvs) spawns the real Python
58+ interpreter as a child process via CreateProcessW. The RemoteUnwinder
59+ needs the child's PID, not the launcher's.
60+
61+ Returns the original pid if not on Windows, not a venv launcher,
62+ or no child process is found.
63+ """
64+ if os .name != "nt" or sys .prefix == sys .base_prefix :
65+ return pid
66+ try :
67+ children = _remote_debugging .get_child_pids (pid , recursive = False )
68+ python_children = [
69+ child for child in children
70+ if _remote_debugging .is_python_process (child )
71+ ]
72+ if len (python_children ) == 1 :
73+ return python_children [0 ]
74+ except (OSError , RuntimeError ) as err :
75+ raise SystemExit (
76+ f"Failed to initialize profiler from virtualenv: { err } \n "
77+ f"Try running with the base interpreter: { sys ._base_executable } "
78+ ) from err
79+ return pid
80+
81+
5382class SampleProfiler :
5483 def __init__ (self , pid , sample_interval_usec , all_threads , * , mode = PROFILING_MODE_WALL , native = False , gc = True , opcodes = False , skip_non_matching_threads = True , collect_stats = False , blocking = False ):
55- self .pid = pid
84+ self .pid = _resolve_python_pid ( pid )
5685 self .sample_interval_usec = sample_interval_usec
5786 self .all_threads = all_threads
5887 self .mode = mode # Store mode for later use
@@ -61,10 +90,6 @@ def __init__(self, pid, sample_interval_usec, all_threads, *, mode=PROFILING_MOD
6190 try :
6291 self .unwinder = self ._new_unwinder (native , gc , opcodes , skip_non_matching_threads )
6392 except RuntimeError as err :
64- if os .name == "nt" and sys .executable .endswith ("python.exe" ):
65- raise SystemExit (
66- "Running profiling.sampling from virtualenv on Windows platform is not supported"
67- ) from err
6893 raise SystemExit (err ) from err
6994 # Track sample intervals and total sample count
7095 self .sample_intervals = deque (maxlen = 100 )
0 commit comments