Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

cmd/go: go tool signal forwarding does not play nice with foreground tools #75152

Open
Labels
GoCommandcmd/go NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone
@agis

Description

Go version

go version go1.25.0 linux/amd64

Output of go env in your module/workspace:

AR='ar'
CC='gcc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='g++'
GCCGO='gccgo'
GO111MODULE=''
GOAMD64='v1'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/home/agis/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/home/agis/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build2541113073=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/home/agis/dev/x/go.mod'
GOMODCACHE='/home/agis/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/agis/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/home/agis/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.25.0.linux-amd64'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/home/agis/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/home/agis/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.25.0.linux-amd64/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.25.0'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you do?

Brief

The way go tool traps and forwards signals might cause tools that stay in the foreground to misbehave.

Note: I'm not sure if this is considered a bug or a "work as intended" situation. If there's intention of changing the behavior, I'd be happy to take a stab at it.

Description

go tool traps signals and forwards them to the spawned tool:

c := make(chan os.Signal, 100)
signal.Notify(c)
go func() {
for sig := range c {
toolCmd.Process.Signal(sig)
}
}()
err = toolCmd.Wait()
signal.Stop(c)
close(c)

However, if the spawned tool is a process that's in the foreground of the TTY, hitting Ctrl-C in the terminal will cause 2 SIGINT signals to be delivered to the spawned tool: one from the kernel (the tool is in the same process group ID as go tool) and one from go tool itself.

This is problematic for tools that assign special meaning to a second SIGINT. overmind (a process supervisor) is an example of this. The second signal causes it to forcefully kill all its processes.

Reproduction

// main.go
package main
func main() {}
// go.mod
module foo
go 1.25
toolchain go1.25.0
tool github.com/agis/gotool-sig
require github.com/agis/gotool-sig v0.0.0-20250826124522-e922fff2b3fb // indirect

Run go tool gotool-sig 1 and then hit Ctrl-C in the terminal. You'll get the following output:

$ go tool gotool-sig 1
PID: 176199, PPID: 176162, PGID: 176162
Signal monitor started with buffer size 1...
^CReceived signal: interrupt (2)
Received signal: interrupt (2)

You'll notice that 2 interrupt signals were delivered to the tool, instead of one.

What did you see happen?

N/A (see above)

What did you expect to see?

Only 1 SIGINT should be delivered.

Metadata

Metadata

Assignees

No one assigned

    Labels

    GoCommandcmd/go NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      AltStyle によって変換されたページ (->オリジナル) /