Commit 45549a4
[build] Fix parallel make hang by disabling dotnet build servers (#24903)
Parallel make (e.g. 'make all -j8', 'make world') has been hanging
for a while at the end of the build. This is a long-standing issue
(#13355) that has been patched
three times
(#15407,
#21315,
#22300) without fully fixing the
root cause.
The problem: when using parallel make, GNU Make uses a jobserver with
pipe-based file descriptors to coordinate sub-makes. The dotnet CLI
can start background build servers (MSBuild server, Roslyn/VBCSCompiler)
that inherit these file descriptors but never close them. Make then
waits for those file descriptors to close (which won't happen until
the servers exit - which they typically do about 10 minutes without
activity), thinking there are still active jobs.
The previous workaround attempted to shut down and force-kill dotnet
processes after the build via a 'shutdown-build-server' target. This
approach was unreliable because:
- The shutdown ran from a double-colon all-hook:: rule with no
prerequisites, so with -j it could execute in parallel with (or
before) the actual build, killing nothing.
- Build servers started by later subdirectories (e.g. tests/) after
the dotnet/ shutdown were never killed.
- The process-matching regex pattern might not match all server
processes.
Ideally this would be fixed in when launching the build servers, by
making them not inherit handles. Unfortunately this is currently not
possible: dotnet/runtime#13943 (although this
might change in a not so
distant future: dotnet/runtime#123959)
The workaround: disable build servers entirely via environment variables
in
Make.config:
- DOTNET_CLI_USE_MSBUILD_SERVER=0: prevents the MSBuild server
https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-server
https://github.com/dotnet/msbuild/blob/main/documentation/MSBuild-Server.md
- UseSharedCompilation=false: prevents the Roslyn compiler server
(VBCSCompiler)
dotnet/roslyn#27975
- MSBUILDDISABLENODEREUSE=1: prevents MSBuild node reuse
https://github.com/dotnet/msbuild/wiki/MSBuild-Tips-&-Tricks
This eliminates the root cause - no background servers means no
inherited file descriptors means no hang. The shutdown-build-server
target and its invocations are removed as they are no longer needed.
Additionally, 'make world' now prints the installed workloads at the
end of the build for visibility.
Build without changes:
> make world 2149.57s user 258.32s system 107% cpu 37:30.19 total
Build with changes:
> make world 2242.74s user 286.38s system 354% cpu 11:52.55 total
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>1 parent 08716c7 commit 45549a4
3 files changed
Lines changed: 11 additions & 23 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
403 | 403 | | |
404 | 404 | | |
405 | 405 | | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
406 | 415 | | |
407 | 416 | | |
408 | 417 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
32 | 32 | | |
33 | 33 | | |
34 | 34 | | |
| 35 | + | |
| 36 | + | |
35 | 37 | | |
36 | 38 | | |
37 | 39 | | |
| |||
68 | 70 | | |
69 | 71 | | |
70 | 72 | | |
71 | | - | |
72 | | - | |
73 | | - | |
74 | 73 | | |
75 | 74 | | |
76 | 75 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
536 | 536 | | |
537 | 537 | | |
538 | 538 | | |
539 | | - | |
540 | | - | |
541 | | - | |
542 | | - | |
543 | | - | |
544 | | - | |
545 | | - | |
546 | | - | |
547 | | - | |
548 | | - | |
549 | | - | |
550 | | - | |
551 | | - | |
552 | | - | |
553 | | - | |
554 | | - | |
555 | | - | |
556 | | - | |
557 | | - | |
558 | | - | |
0 commit comments