`pet server` `configure` hangs in a filesystem-scan busy-loop on large workspaces → 30s timeout × 3 retries = ~90s 100% CPU (thermal shutdown on laptops)

Aperta
#1,747 0 commenti 0 reazioni 1 assegnatario Vedi su GitHub

@DonJayamanne ci sta già lavorando.

Dal 31/8/2026.

Valutazione

Questa issue non è ancora stata valutata.

Descrizione

area-environment bug

Summary

The pet binary (python-env-tools, shipped by ms-python.vscode-python-envs) busy-loops inside a filesystem stat/close scan when handling a configure JSON-RPC request whose environmentDirectories glob is evaluated against a large workspace. The scan does not complete within the extension's 30-second configure timeout, so the extension kills pet (SIGTERM), restarts it, and re-sends configure — which hangs again. After 3 attempts (~90 s of sustained 100% CPU on one core) the extension gives up.

On a thermally-constrained laptop this ~90 s 100% CPU spike pushes the package past 105 °C and the embedded controller cuts power with no OS-level log (no OOM, no panic, no thermal trip in journald — the journal just ends mid-normal-activity). The bug therefore masquerades as a hardware/BIOS issue and is very hard to diagnose. Worth fixing for that reason alone, not just the wasted CPU.

Environment

  • Extension: ms-python.vscode-python-envs v1.20.1 — the latest version compatible with my VS Code. (I have 1.22.0–1.36.0 installed too, but VS Code refuses to load them: "Extension is not compatible with Code 1.108.1. Extension requires: ^1.110.0-20260204". So I can't test newer versions without also upgrading VS Code. Happy to re-test on 1.36.0 if a maintainer confirms whether the scan/timeout behavior changed.)
  • VS Code: 1.108.1
  • OS: Ubuntu 24.04.3 LTS, kernel 6.17.0-22-generic, x86_64
  • pet binary: ELF 64-bit, static-pie, with debug_info, not stripped
  • Hardware: HP OMEN laptop, Intel Core Ultra (Arrow Lake-H) + NVIDIA RTX 5070 Laptop (degraded cooling — needs repaste)

The trigger workspace

The crash only happens for one of my open workspaces. Its size is the key:

$ find /home/<user>/workspace/large-project | wc -l
279488
$ du -sh /home/<user>/workspace/large-project
101G

279,488 files / 101 GB, including several node_modules trees with symlinks. The other workspaces I have open (346 / ~small files) configure in <1 s and never spin. The configure params the extension sends for this workspace:

{"workspaceDirectories":["/home/<user>/workspace/large-project"],
 "environmentDirectories":["/home/<user>/workspace/large-project/**/.venv"],
 "pipenvExecutable":"pipenv","poetryExecutable":"poetry",
 "cacheDirectory":".../pythonLocator"}

Note the **/.venv glob — pet walks the entire 279k-file tree looking for .venv dirs.

Reproduction (CLI, deterministic, ~12 s)

pet server reads JSON-RPC over stdio with Content-Length framing. Sending the exact configure request the extension sends hangs pet in a stat/close scan loop:

$ # request body in configure.json (the JSON above)
$ ( printf "Content-Length: %s\n\n" "$(wc -c < configure.json)"; cat configure.json; sleep 13 ) \
    | timeout -s INT 12 strace -c -f -e trace=futex,poll,ppoll,read,write,stat,newfstatat,openat,close \
      ~/.vscode/extensions/ms-python.vscode-python-envs-1.20.1-linux-x64/python-env-tools/bin/pet server
# exit code 124  (pet never responded within 12 s)

strace summary (12 s, no pet find, just configure):

% time     seconds  usecs/call     calls    errors syscall
 72.50    0.203708           1    138906           close
 27.50    0.077264          11      6792      4317 stat
  0.00    0.000000           0         1           read
  0.00    0.000000           0         1           poll
100.00    0.280972          1    145700      4317 total

So pet is in a tight stat/close loop walking the workspace, 64% of stats returning ENOENT (probing for .venv/python/etc. at every entry). 12 s wasn't enough to finish; the extension's 30 s timeout isn't either.

Extension log (from the actual crash session)

~/.config/Code/logs/20260829T164624/window2/exthost/ms-python.vscode-python-envs/Python Environments.log:

16:47:32.185 [info] [pet] Starting Python Locator .../pet server
16:47:32.186 [info] [pet] configure: Sending configuration update: {"workspaceDirectories":[".../<large-workspace>"],"environmentDirectories":[".../<large-workspace>/**/.venv"],...}
16:48:02.186 [warning] [pet] Configure request timed out, killing hung process for restart
16:48:02.186 [error]  [pet] configure: Configuration error Request 'configure' timed out after 30000ms
16:48:02.187 [warning] [pet] Restarting Python Environment Tools (attempt 3/3, waiting 4000ms)
16:48:02.188 [error]  [pet] Python Environment Tools exited unexpectedly with code null, signal SIGTERM
16:48:06.195 [info] [pet] Starting Python Locator .../pet server     # restart, send configure again
16:48:36.197 [warning] [pet] Configure request timed out, killing hung process for restart   # 30s later, again
16:48:36.197 [error]  PET failed after 3 restart attempts.
16:48:36.199 [warning] [priorityChain] .../<large-workspace> defaultInterpreterPath '/bin/python3' unresolvable, falling back to auto-discovery

Same pattern reproduces every time this workspace is opened (also seen in the 20260829T213146 session). Other workspaces configure in <1 s.

Impact / why this matters

  • Wasted CPU + battery on any machine: ~90 s of one pinned core per workspace open.
  • Silent hard power-off on thermally-constrained laptops: I confirmed the causal link — killing the spinning pet dropped CPU package temp from 100 °C → 90 °C in 2 s. The ~90 s spike pushes the package past 105 °C and the EC cuts power with no OS log. I had repeated unexplained "auto-shutdowns" for weeks before tracing them here.
  • The empty "Extension causes high cpu load" auto-issues (#1074, #1379, #1469, #1709) are very likely this same bug, never diagnosed because the reporters never attached a profile.

Secondary issue: pet busy-loops on malformed input too

While figuring out the framing I sent a request without a valid Content-Length header. Instead of failing gracefully, pet entered an infinite error-spam loop writing the same error to stderr — 941,762 write calls in 12 s (~78k writes/s), 100% CPU:

% time  calls    syscall
 58%   941762   write
 24%    98908   open
 11%   188354   read
  ...

stderr was the error message recursively nesting itself. A malformed request should error once and continue, not spin. Likely the same lack of backoff/bounding that causes the configure hang.

What I'd suggest (and can help validate)

  1. Bound the configure scan: skip / prune common heavy dirs (node_modules, .git, __pycache__, .venv contents), cap depth or entry count, or make discovery incremental/lazy instead of a full synchronous walk that must finish before configure responds.
  2. Don't retry 3× with no backoff: a workspace that times out once will time out 3 times — that's 90 s of guaranteed 100% CPU. Exponential backoff or a single retry would cut the blast radius.
  3. Fix the error-spam loop on malformed input (fail once, don't busy-write).
  4. If a maintainer can tell me which pet subcommand/request path is the right one to exercise, I can attach a perf record call graph (I have perf + the binary's debug symbols ready, just need to temporarily relax perf_event_paranoid). The strace above already localizes it to the env-discovery glob scan, but a flamegraph would pin the exact function.

Workaround

Disable / uninstall the ms-python.vscode-python-envs extension, or avoid opening the large workspace, or narrow python.envs.environmentDirectories so the glob doesn't span the whole tree.

Related

  • #1709 (open), #1469, #1379, #1074 (closed) — empty "Extension causes high cpu load" auto-reports, likely this.
  • #1289 / #1290 (v1.22.0) — related but different: that's unresolved ${workspaceFolder} causing a clean ENOENT failure; this is a hang/spin on a valid (but large) workspace.
Lingua principale
TypeScript
Stelle
140
Fork
63
Merge medio
1g 4h
PR unite (30g)
35

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di microsoft/vscode-python-environments

Tutte le issue di microsoft/vscode-python-environments

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.