microsoft / microsoft/vscode-makefile-tools
Dry-run during configure executes workspace recipes and can terminate VS Code (kill 0 in a Makefile trap)
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 242
- Forks
- 78
- PR merge metrics
- No merged PRs in 30d
Description
Summary
Opening a folder whose Makefile contains a trap '...' EXIT with kill 0 terminates the entire VS Code application, before the user can interact with the window.
Two separate problems combine to cause this:
- The configure step's
make --dry-runis treated as inert. It isn't — GNU make deliberately executes recipe lines containing$(MAKE)even under-n. - That
makeis spawned in VS Code's own process group, so anything the workspace's Makefile signals hits the editor.
The result is that merely opening a folder lets that folder's contents kill VS Code.
Repro
Minimal Makefile, no .vscode config needed:
dev:
@trap 'kill 0' EXIT; $(MAKE) sub & wait
sub:
@true
Open the containing folder in VS Code. Makefile Tools activates, runs its configure dry-run, and the application dies.
The same thing from a terminal, isolated into its own session so it only kills itself:
$ perl -e 'use POSIX; if(fork()==0){ POSIX::setsid();
exec("make --dry-run --always-make --keep-going --print-directory > out.txt 2>&1; echo EXIT=\$? >> out.txt"); } wait;'
$ cat out.txt
make: Entering directory `/tmp/repro'
trap 'kill 0' EXIT; /usr/bin/make sub & wait
make[1]: Entering directory `/tmp/repro' <-- sub-make actually ran under --dry-run
true <-- and so did its recipe
make[1]: Leaving directory `/tmp/repro'
Note there is no EXIT= line: the shell was killed by the signal before it could report a status. Under VS Code that signal goes to VS Code's process group instead.
Why --dry-run doesn't protect you
From the GNU make manual, on -n: lines in the recipe that contain $(MAKE) or ${MAKE} (and lines prefixed with +) are run regardless, so that recursive builds can be traced. This is intended behavior, not a make bug — but it means --dry-run is not a sandbox, and the configure step cannot assume it won't execute workspace code.
--always-make, which the extension also passes, widens this: every such line is considered out of date and runs.
Actual behavior
Entire VS Code application exits. No error, no crash dialog, no DiagnosticReports entry (it's a clean SIGTERM, not a crash). main.log shows no failure — from the logs it looks like a normal shutdown, which makes this very hard to diagnose. The only trace is the command in ms-vscode.makefile-tools/dryrun.log in the workspace storage folder.
Expected behavior
Opening a folder should never allow that folder's contents to terminate the editor.
Suggested fix
Spawn the configure/dry-run child detached, in its own process group/session (detached: true in child_process.spawn, and don't unref it if you need to await it). Then kill 0 from a workspace recipe can only reach the dry-run's own subtree, which is the correct blast radius. This also bounds the damage from #397 (recursive Makefile exhausting process resources) and any other recipe the dry-run ends up executing.
Secondarily, it would be worth documenting that the dry-run may execute recipe lines, since "we only dry-run it" is a reasonable thing for users to assume and it isn't true.
Related
- #397 — "A broken makefile that recurses kills server". Same class (dry-run executing recipes takes down the host), different mechanism, and it stalled because the reporter couldn't reproduce it. This one reproduces deterministically in 4 lines.
Environment
- VS Code: 1.139.0-insider (
046944034292b5479b4e9a50ad1a508033ffb64f), arm64 - Makefile Tools: 0.12.17
- OS: macOS 26.6.2, Apple Silicon
- GNU Make 3.81 (Apple Command Line Tools)
Not macOS-specific — the process-group behavior is the same on Linux.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the configure/dry-run child process creation using Node's child_process.spawn and inspect how its output reaches dryrun.log. Reproduce with the four-line Makefile and verify that the child runs in its own process group or session, so kill 0 cannot terminate VS Code. Done means the folder opens without the editor exiting and the dry-run behavior remains observable.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- build-system, devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 62/100