Skip to content

cmd/exec: Wait hangs on DragonflyBSD if child has a PTY that has been written to #56132

Open
@prattmic

Description

@prattmic

What version of Go are you using (go version)?

tip at 6a9aaf1

Does this issue reproduce with the latest release?

Yes, 1.19.2

What operating system and processor architecture are you using (go env)?

dragonfly-amd64. Specifically, the dragonfly-amd64-622 builder/gomote.

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/root/.cache/go-build"
GOENV="/root/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="dragonfly"
GOINSECURE=""
GOMODCACHE="/root/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="dragonfly"
GOPATH="/root/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/tmp/workdir/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/tmp/workdir/go/pkg/tool/dragonfly_amd64"
GOVCS=""
GOVERSION="devel gomote.XXXXX"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/tmp/workdir/go/src/go.mod"
GOWORK=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build2229047134=/tmp/go-build -gno-record-gcc-switches"

What did you do?

Run TestDragonfly from CL 441916.

$ git fetch https://go.googlesource.com/go refs/changes/16/441916/1 && git checkout FETCH_HEAD
$ ./make.bash
$ ../bin/go test -run=TestDragonfly -v os/signal

This test:

  1. Creates psuedo-terminal parent and child FDs (with posix_openpt et al via cgo in os/signal/internal/pty).
  2. Starts a child process which inherits the child end of the PTY.
    1. Starting a new session (Setsid), process group (Setpgid), setting the controlling terminal (Setctty), and setting foreground (Foreground) don't seem to make a difference either way, so the repro skips them.
  3. The child immediately exits (reading from the PTY does not make a difference).
  4. The parent writes a byte to the parent end of the PTY (if nothing is written hang does not occur).
  5. The parent waits on the child with cmd.Wait.

What did you expect to see?

Test passes.

Note that TryBots passed on all other Unix OSes.

What did you see instead?

Test hangs, and eventually times out.

$ ../bin/go test -run=TestDragonfly -v -count=1 os/signal
=== RUN   TestDragonfly
    signal_cgo_test.go:301: Waiting for exit...
child exiting
<hung>

Specifically, the child exits (CALL exit(0) according to ktrace), but the parent wait6 call never returns. Full ktrace dump is attached here.

This feels like an OS bug, though I attempted to recreate this in C (dragonfly.c in CL 441916) and was not able to reproduce. That said, there are some differences from Go, most notably that both the parent and child are multithreaded in Go.

cc @golang/dragonfly

Metadata

Metadata

Assignees

No one assigned

    Labels

    NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.OS-Dragonfly

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions