[xbuild] Fix ProcessWrapper to WaitForExit(..) before accessing ExitCode
authorAnkit Jain <ankit.jain@xamarin.com>
Wed, 11 May 2016 20:54:46 +0000 (16:54 -0400)
committerAnkit Jain <ankit.jain@xamarin.com>
Wed, 11 May 2016 21:43:23 +0000 (17:43 -0400)
Process.Exited event can get invoked before the process has really
exited. So, accessing process.ExitCode before the real exit can throw:

Error executing task Exec: System.InvalidOperationException: Process must exit before requested information can be determined.
  at System.Diagnostics.Process.EnsureState (System.Diagnostics.Process+State state) [0x000b9] in /Users/ankit/dev/mono/mcs/class/referencesource/System/services/monitoring/system/diagnosticts/Process.cs:1439
  at System.Diagnostics.Process.get_ExitCode () [0x00000] in /Users/ankit/dev/mono/mcs/class/referencesource/System/services/monitoring/system/diagnosticts/Process.cs:219
  at (wrapper remoting-invoke-with-check) System.Diagnostics.Process:get_ExitCode ()
  at Microsoft.Build.Utilities.ToolTask.ExecuteTool (System.String pathToTool, System.String responseFileCommands, System.String commandLineCommands) [0x00101] in /Users/ankit/dev/mono/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/ToolTask.cs:185
  at Microsoft.Build.Tasks.Exec.ExecuteTool (System.String pathToTool, System.String responseFileCommands, System.String commandLineCommands) [0x00026] in /Users/ankit/dev/mono/mcs/class/Microsoft.Build.Tasks/Microsoft.Build.Tasks/Exec.cs:83
  at Microsoft.Build.Utilities.ToolTask.Execute () [0x0001c] in /Users/ankit/dev/mono/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/ToolTask.cs:128
  at Microsoft.Build.BuildEngine.TaskEngine.Execute () [0x00000] in /Users/ankit/dev/mono/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/TaskEngine.cs:134
  at Microsoft.Build.BuildEngine.BuildTask.Execute () [0x0008f] in /Users/ankit/dev/mono/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/BuildTask.cs:101

ProcessWrapper.WaitForOutput depends on the
`endEventExit`(ManualResetEvent) to be set, which is done in the event
handler for Process.Exited . So, effectively, WaitForOutput can return
before the process has really exited and ToolTask ends up throwing an
exception when it accesses the ExitCode.

Fix: Add a WaitForExit in WaitForOutput, to be sure!

mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/ProcessWrapper.cs

index 1674ff8b5dc3095f027cd6ffd60d1562e5e056d4..ddd58939912356a89d16d5323b6b28e5580f6b93 100644 (file)
@@ -74,6 +74,7 @@ namespace Microsoft.Build.Utilities
                public void WaitForOutput (int milliseconds)
                {
                        CheckDisposed ();
+                       WaitForExit (milliseconds);
                        WaitHandle.WaitAll (new WaitHandle[] { endEventOut, endEventErr, endEventExit }, milliseconds);
                }