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

Revert "Use socketpair to implement Process.Start redirection (#34861)" #40832

Closed

Conversation

eiriktsarpalis
Copy link
Member

Reverts commit c44dc40, introduced by #34861.

Fixes #40727.

Please don't merge while I test the changes in WSL1.

@eiriktsarpalis eiriktsarpalis added NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons) area-System.Diagnostics.Process labels Aug 14, 2020
@eiriktsarpalis eiriktsarpalis added this to the 5.0.0 milestone Aug 14, 2020
@ghost
Copy link

ghost commented Aug 14, 2020

Tagging subscribers to this area: @eiriktsarpalis
See info in area-owners.md if you want to be subscribed.

@stephentoub
Copy link
Member

If we go ahead with this reverting, we need to have an issue to redo it in .NET 6.0. This was fixing a real issue.
cc: @davidfowl

@stephentoub
Copy link
Member

(I'd also love it if we could do a bit more debugging and see whether there's a simple fix that would enable this to work in WSL1, such as being a bit more forgiving of various error conditions.)

@adamsitnik
Copy link
Member

How about not reverting it but adding a fallback based on whether to socket is connected or not?

private static Stream OpenStream(int fd, FileAccess access)
{
    var socket = new Socket(new SafeSocketHandle((IntPtr)fd, ownsHandle: true));
    if (socket.IsConnected)
    {
        return new NetworkStream(socket, access, ownsSocket: true);
    }
    else //WSL1
    {
        return new FileStream(
            new SafeFileHandle((IntPtr)fd, ownsHandle: true),
            access, StreamBufferSize, isAsync: false);
    }
}

@stephentoub @eiriktsarpalis what do you think?

@stephentoub
Copy link
Member

stephentoub commented Aug 14, 2020

Thanks, Adam. My preference would be to actually fix the Socket ctor; both reverting this and working around it in Process will still leave the ctor buggy in WSL1 for any other consumption. But short of that, yes, I'd prefer a (temporary) workaround in Process rather than reverting. (But note a workaround like above would be a little more complicated, e.g. the FileStream would need to keep the Socket alive.)

@eiriktsarpalis
Copy link
Member Author

Do we have reliable platform detection for WSL1? We could just use that to switch to the old implementation.

@adamsitnik
Copy link
Member

My preference would be to actually fix the Socket ctor

same here

Do we have reliable platform detection for WSL1

The problem is that it can also occur on other Unixes, like FreeBSD here: #33051

@eiriktsarpalis
Copy link
Member Author

My preference would be to actually fix the Socket ctor

I don't believe this is really possible at the socket layer for WSL1. We'd need to somehow infer the address family and there's a lot of other weird behaviour going on, for instance calling getpeername on a socket pair will sometimes return ENOTCONN. Our safest bet is addressing this at the process layer.

For the fallback logic, it might make sense to do some form of platform detection for WSL1. The best known approach is reading the /proc/version file, honestly though this is a heurestic I'm not confident putting in production code.

cc @wfurt

@stephentoub
Copy link
Member

@eiriktsarpalis, did you debug into

int32_t SystemNative_GetSocketType(intptr_t socket, int32_t* addressFamily, int32_t* socketType, int32_t* protocolType, int32_t* isListening)
to see where things were going awry?

@eiriktsarpalis
Copy link
Member Author

Sure, it looks like the getsockopt call in line 2522 is returning a non-zero value. The same seems to happen in line 2532 which results in an unknown socket type being returned.

@stephentoub
Copy link
Member

Presumably -1. Can you see what errno is?

@eiriktsarpalis
Copy link
Member Author

It's EINVAL.

@stephentoub
Copy link
Member

It's EINVAL.

Thanks. I suspect the right fix is to be more forgiving of such errors, as we do later in the method:

case SocketError.InvalidArgument:
// On some OSes (e.g. macOS), EINVAL means the socket has been shut down.
// This can happen if, for example, socketpair was used and the parent
// process closed its copy of the child's socket. Since we don't know
// whether we're actually connected or not, err on the side of saying
// we're connected.
_isConnected = true;

@eiriktsarpalis
Copy link
Member Author

Closing in favor of #40851

@ghost ghost locked as resolved and limited conversation to collaborators Dec 7, 2020
@eiriktsarpalis eiriktsarpalis deleted the revert-proc-socketpair branch June 2, 2021 20:21
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Diagnostics.Process NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Redirecting stdout/stderr of a process throws exception with .NET 5 preview.6 on WSL1
3 participants