From 35bc38635dd23dddb260e2dc1add50fc2b4f7b21 Mon Sep 17 00:00:00 2001 From: MichalPavlik Date: Thu, 11 Jul 2024 13:27:11 +0200 Subject: [PATCH] Fix possible ToolTask hang (#10297) Using different overload of WaitForExit to avoid situation when grandchild process is keeping the MSBuild waiting --- documentation/wiki/ChangeWaves.md | 1 + src/Utilities/ToolTask.cs | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/documentation/wiki/ChangeWaves.md b/documentation/wiki/ChangeWaves.md index c30d03cea0f..6ac2db97d29 100644 --- a/documentation/wiki/ChangeWaves.md +++ b/documentation/wiki/ChangeWaves.md @@ -28,6 +28,7 @@ A wave of features is set to "rotate out" (i.e. become standard functionality) t - [Convert.ToString during a property evaluation uses the InvariantCulture for all types](https://github.com/dotnet/msbuild/pull/9874) - [Fix oversharing of build results in ResultsCache](https://github.com/dotnet/msbuild/pull/9987) - [Add ParameterName and PropertyName to TaskParameterEventArgs](https://github.com/dotnet/msbuild/pull/10130) +- [The ToolTask only waits for its child process to end before returning, instead of waiting for grandchildren](https://github.com/dotnet/msbuild/pull/10297) ### 17.10 - [AppDomain configuration is serialized without using BinFmt](https://github.com/dotnet/msbuild/pull/9320) - feature can be opted out only if [BinaryFormatter](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.serialization.formatters.binary.binaryformatter) is allowed at runtime by editing `MSBuild.runtimeconfig.json` diff --git a/src/Utilities/ToolTask.cs b/src/Utilities/ToolTask.cs index 2443ff50c43..b2587a2db17 100644 --- a/src/Utilities/ToolTask.cs +++ b/src/Utilities/ToolTask.cs @@ -1053,7 +1053,16 @@ private void TerminateToolProcess(Process proc, bool isBeingCancelled) /// private static void WaitForProcessExit(Process proc) { - proc.WaitForExit(); + if (ChangeWaves.AreFeaturesEnabled(ChangeWaves.Wave17_12)) + { + // Using overload with timeout prevents hanging in case that grandchild process is still running + // See https://github.com/dotnet/runtime/issues/51277 and https://github.com/dotnet/msbuild/issues/2981#issuecomment-818581362 + proc.WaitForExit(int.MaxValue); + } + else + { + proc.WaitForExit(); + } // Process.WaitForExit() may return prematurely. We need to check to be sure. while (!proc.HasExited)