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

os/exec: CombinedOutput hangs when exec'd task forks a "daemon" #13155

Closed
tych0 opened this issue Nov 5, 2015 · 5 comments
Closed

os/exec: CombinedOutput hangs when exec'd task forks a "daemon" #13155

tych0 opened this issue Nov 5, 2015 · 5 comments

Comments

@tych0
Copy link

tych0 commented Nov 5, 2015

Consider https://gist.github.com/felixge/452a5a192e217a2a51c0

I get a similar stack trace:

goroutine 1 [chan receive]:
os/exec.(*Cmd).Wait(0xc82008a000, 0x0, 0x0)
    /usr/lib/go/src/os/exec/exec.go:385 +0x2c9
os/exec.(*Cmd).Run(0xc82008a000, 0x0, 0x0)
    /usr/lib/go/src/os/exec/exec.go:258 +0x64
os/exec.(*Cmd).CombinedOutput(0xc82008a000, 0x0, 0x0, 0x0, 0x0, 0x0)
    /usr/lib/go/src/os/exec/exec.go:424 +0x310
main.main()
    /home/tycho/bug.go:22 +0x130

goroutine 6 [syscall]:
syscall.Syscall(0x0, 0x4, 0xc820090000, 0x200, 0x0, 0x0, 0x40eea9)
    /usr/lib/go/src/syscall/asm_linux_amd64.s:18 +0x5
syscall.read(0x4, 0xc820090000, 0x200, 0x200, 0x40f078, 0x0, 0x0)
    /usr/lib/go/src/syscall/zsyscall_linux_amd64.go:783 +0x5f
syscall.Read(0x4, 0xc820090000, 0x200, 0x200, 0xc82002e4e8, 0x0, 0x0)
    /usr/lib/go/src/syscall/syscall_unix.go:160 +0x4d
os.(*File).read(0xc820030038, 0xc820090000, 0x200, 0x200, 0xc820090000, 0x0, 0x0)
    /usr/lib/go/src/os/file_unix.go:211 +0x53
os.(*File).Read(0xc820030038, 0xc820090000, 0x200, 0x200, 0x0, 0x0, 0x0)
    /usr/lib/go/src/os/file.go:95 +0x8a
bytes.(*Buffer).ReadFrom(0xc82001a150, 0x7fa3eff92210, 0xc820030038, 0x0, 0x0, 0x0)
    /usr/lib/go/src/bytes/buffer.go:173 +0x23f
io.copyBuffer(0x7fa3eff921c0, 0xc82001a150, 0x7fa3eff92210, 0xc820030038, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
    /usr/lib/go/src/io/io.go:375 +0x180
io.Copy(0x7fa3eff921c0, 0xc82001a150, 0x7fa3eff92210, 0xc820030038, 0x0, 0x0, 0x0)
    /usr/lib/go/src/io/io.go:351 +0x64
os/exec.(*Cmd).writerDescriptor.func1(0x0, 0x0)
    /usr/lib/go/src/os/exec/exec.go:232 +0x8b
os/exec.(*Cmd).Start.func1(0xc82008a000, 0xc82000e300)
    /usr/lib/go/src/os/exec/exec.go:340 +0x1d
created by os/exec.(*Cmd).Start
    /usr/lib/go/src/os/exec/exec.go:341 +0x96d

which for me is roughly:

c.errch <- fn()

Based on a cursory glance through the code, it seems like what is happening is that the std{in,out,err} reading/writing goroutines are blocking on reading the stdin of the process, which isn't closed when the child exits, because the grandchild shares the same fds (and doesn't close them). Wait() attempts to address this with a call to closeDescriptors, but it is after a blocking wait on the goroutines exiting, so it doesn't work either.

The behavior I'd expect is that CombinedOutput() reports exactly what the child task printed, and returns when it exits. At least in the example above, I think it can be resolved by closing the stdin fd for the child once the child exits (but before waiting on the goroutines). However, I haven't tried it and I can imagine other cases where it would still hang.

@adg adg changed the title CombinedOutput hangs when exec'd task forks a "daemon" os/exec: CombinedOutput hangs when exec'd task forks a "daemon" Nov 5, 2015
@ianlancetaylor ianlancetaylor added this to the Unplanned milestone Nov 5, 2015
@rakyll
Copy link
Contributor

rakyll commented Nov 5, 2015

What's your go version? I can't reproduce it on go version devel +321cf6f Thu Nov 5 16:16:41 2015 +0000 darwin/amd64.

@tych0
Copy link
Author

tych0 commented Nov 5, 2015

On Thu, Nov 05, 2015 at 10:11:26AM -0800, Burcu Dogan wrote:

What's your go version? I can't reproduce it on go version devel +321cf6f Thu Nov 5 16:16:41 2015 +0000 darwin/amd64.

go version go1.5.1 linux/amd64

tych0 pushed a commit to tych0/lxd that referenced this issue Jan 9, 2016
See comments, this is another instance of:
golang/go#13155

Signed-off-by: Tycho Andersen <tycho.andersen@canonical.com>
@noxiouz
Copy link

noxiouz commented Jul 13, 2016

I have the same behavior here https://groups.google.com/forum/#!topic/golang-nuts/cwEk8lfV_e8
with a way to reproduce. Should I create a new issue?

@ianlancetaylor
Copy link
Member

This issue is still open; I don't see a need to create a new issue unless you think it is a different problem.

@agnivade
Copy link
Contributor

This is working as intended. Killing a process does NOT kill any child process that it may have started.

https://golang.org/pkg/os/#Process.Kill

This only kills the Process itself, not any other processes it may have started.

Also see @ianlancetaylor's comment on this - #24220 (comment).

@golang golang locked and limited conversation to collaborators Sep 30, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants