Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Process.Start() can fail due to what appears to be a race condition between the process exiting and standard input being configured #8478

Closed
madelson opened this issue Apr 26, 2018 · 2 comments

Comments

@madelson
Copy link

I got a bug report for my MedallionShell .NET library on Mono (see madelson/MedallionShell#22 for the full description).

Looking at the posted code and stack trace, this seems like the root cause is a bug in Mono's Process.Start implementation.

Steps to Reproduce

  1. Configure a process to have streams redirected, and such that it will exit immediately (e. g. calling ffmpeg with invalid arguments).
  2. Call Process.Start()

Example code using the MedallionShell NuGet package, which calls the Process API under the hood:

var cmd = Command.Run(ffmpegPath, (new string[]
{
"-hide_banner",
"-some_invalid_option",
}), ((options) =>
{
	options.WorkingDirectory(workingDir);
}));
var tasks = new List<Task>
{
	cmd.Task,
	cmd.StandardOutput.PipeToAsync(stdOutCollection),
	cmd.StandardError.PipeToAsync(stdErrCollection)
};
Task.WaitAll(tasks.ToArray());
exitCode = cmd.Result.ExitCode;

Current Behavior

Process.Start() fails with IOException. Here's the relevant stack trace:

MonoDroid] System.IO.IOException: Write fault on path /[Unknown]
[MonoDroid]   at System.IO.FileStream.WriteInternal (System.Byte[] src, System.Int32 offset, System.Int32 count) [0x00077] in <fa70666c4440451cb5ca34569f933bb4>:0 
[MonoDroid]   at System.IO.FileStream.Write (System.Byte[] array, System.Int32 offset, System.Int32 count) [0x00090] in <fa70666c4440451cb5ca34569f933bb4>:0 
[MonoDroid]   at System.IO.StreamWriter.Flush (System.Boolean flushStream, System.Boolean flushEncoder) [0x00042] in <fa70666c4440451cb5ca34569f933bb4>:0 
[MonoDroid]   at System.IO.StreamWriter.set_AutoFlush (System.Boolean value) [0x00010] in <fa70666c4440451cb5ca34569f933bb4>:0 
[MonoDroid]   at System.Diagnostics.Process.StartWithCreateProcess (System.Diagnostics.ProcessStartInfo startInfo) [0x00353] in <5a97d41d36694fb19855c17429527b10>:0 
[MonoDroid]   at System.Diagnostics.Process.Start () [0x0003a] in <5a97d41d36694fb19855c17429527b10>:0 
[MonoDroid]   at (wrapper remoting-invoke-with-check) System.Diagnostics.Process.Start()

It seems like setting up the AutoFlush property on the standard input StreamReader triggers a Write call on the underlying stream which then fails with a write fault because the process is dead.

Expected Behavior

I've observed in other cases that unlike .NET framework Mono process streams throw if written to after the process exits (undesirable behavior if you ask me since then there's no way to safely touch those streams without try-catch).

That said, this behavior is worse because Process.Start itself fails, even though the process started just fine; it simply exited quickly.

On which platforms did you notice this

The original poster saw this on Android. I haven't succeeded in reproducing on Windows, but windows is kinda slow to create processes so it may just be that this race condition doesn't happen.

Version Used:

Mono 5.10.1, Xamarin.Android Version: 8.3.0.17

Stacktrace

See above.

@migueldeicaza
Copy link
Contributor

It looks like this is rooted on the same problem as this:

#8417

@marek-safar
Copy link
Member

It indeed looks like the same issue. I'm close it but feel free to reopen if you can still reproduce it with the fix included.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants