microsoft / microsoft/vscode-makefile-tools

Dry-run during configure executes workspace recipes and can terminate VS Code (kill 0 in a Makefile trap)

Open
#835 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

more info needed
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:

  1. The configure step's make --dry-run is treated as inert. It isn't — GNU make deliberately executes recipe lines containing $(MAKE) even under -n.
  2. That make is 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.