-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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
os/exec: Wait behavior changed from Go 1.9 to Go 1.10 on Windows #25835
Comments
/cc @ianlancetaylor |
Ah, I have also tripped over this recently! I have been observing the output of subprocesses writing to stderr (by the parent's |
Sorry, my mistake. My situation also has |
@kgadams I can't recreate the problem. On my GNU/Linux system, the example program shown above behaves the same with Go 1.9.6, 1.10.3, and tip. In all cases it prints What system are you running on? What exact version of Go are you using? Thanks. |
I've got what I believe is a simpler reproduction: package main
import (
"context"
"fmt"
"log"
"os/exec"
"time"
)
func main() {
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
cmd := exec.CommandContext(ctx, "sh", "-c", "echo hello world && sleep 5")
start := time.Now()
output, err := cmd.CombinedOutput()
d := time.Since(start)
fmt.Printf("output: %q\n", output)
fmt.Printf("err: %v\n", err)
fmt.Printf("d: %v\n", d)
if err == nil {
log.Fatalf("command didn't fail after %v", d)
}
if d.Seconds() >= 3 {
log.Fatalf("Cancelation took too long: %v", d)
}
fmt.Println("Success!")
} This fails (with the "Cancelation took too long" message) on |
The possible connection to the case reported up the top is this: if I change from |
I think we are seeing shell dependent behavior. What is |
|
I tested all go/os combinations I could get my hands on, and I found that the version of @dsymonds fails consistently on all of them.
It fails on:
So it looks like a windows only problem to me. And somehow there is a difference between using CombinedOutput() and StdoutPipe() FWIW: I run it with $GOROOT/bin/go run cmd.go under a git environment, so the sh used on Windows is |
There is definitely a significant difference between |
@kgadams Thanks for explaining that your failure is only on Windows. That makes a huge difference. |
The reason @dsymonds 's program works for me is indeed a shell feature. With the shell I am using (bash 4.4.12(1)-release on GNU/Linux) the |
There is more about exec on Windows with child processes in #17245. I don't know why it would have changed between 1.9 and 1.10, though. |
@ianlancetaylor: Thanks, but #23019 doesn't seem to have much to say about the provided context not being respected. In my real case, I'm running a real binary with a 5s context timeout, and it runs for several minutes. That's running on Linux, not Windows. Is there a bug open that would be relevant to that? I couldn't find one with a bit of searching. |
The behavior changing comes from 382d492
Line 478 in f4e4ec2
In Go1.10,
https://golang.org/pkg/os/exec/#Cmd.StdoutPipe |
Does anybody know of a way to work around this problem on Windows? |
@kgadams This problem only arises when pointing the |
@ianlancetaylor: First I thought it works, but in the real code it does not. |
Sure, use If this doesn't solve the problem then I don't understand what the problem is. |
See the opening post in this thread. It uses StdoutPipe(). |
Ah, OK, |
The problem is that Go doesn't use the runtime poller to operate pipe on Windows. So the problem itself is how to
How about make |
Can we just fix the os package to add pipes to the poller when you call |
That is #19098
|
When closing a pipe, use CancelIoEx to cancel pending I/O. This makes concurrent Read and Write calls to return os.ErrClosed. This change also enables pipe_test on Windows. Fixes golang#28477, golang#25835 Change-Id: If52bb7d80895763488a61632e4682a78336e8420
When closing a pipe, use CancelIoEx to cancel pending I/O. This makes concurrent Read and Write calls to return os.ErrClosed. This change also enables some pipe tests on Windows. Fixes golang#28477, golang#25835 Change-Id: If52bb7d80895763488a61632e4682a78336e8420
Change https://golang.org/cl/164721 mentions this issue: |
Copying from #23019 (comment)
Here is the reproduction as a main function with correct markdown :-)
THX @ysmolsky!
Result does not change: works with go 1.9, breaks with go 1.10.
The text was updated successfully, but these errors were encountered: