Go version
go version go1.25.3 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='/usr/local/google/home/mpratt/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/usr/local/google/home/mpratt/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build707894335=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/dev/null'
GOMODCACHE='/usr/local/google/home/mpratt/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/usr/local/google/home/mpratt/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/google/home/mpratt/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.25.3.linux-amd64'
GOSUMDB='sum.golang.org'
GOTELEMETRY='on'
GOTELEMETRYDIR='/usr/local/google/home/mpratt/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='go1.25.3'
GOTOOLDIR='/usr/local/google/home/mpratt/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.25.3.linux-amd64/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.25.3'
GOWORK=''
PKG_CONFIG='pkg-config'
What did you do?
- Generate a dummy pprof file to use as input (you can also use one you have laying around):
$ GOTOOLCHAIN=go1.25.3 go test -cpuprofile in.pprof bytes
- Build a standalone version of
cmd/pprof:
$ GOTOOLCHAIN=go1.25.3 go build cmd/pprof
- Run
pprof -http, and then suspend it with ^Z (Control + z). This should drop you back to the shell, at which point you can use fg to resume execution and then exit with ^C.
$ ./pprof -http=:8080 in.pprof
Serving web UI on http://localhost:8080
^Z
$ fg
./pprof -http=:8080 in.pprof
^C
$
This is working as intended.
- Now attempt the same thing through
go tool:
$ GOTOOLCHAIN=go1.25.3 go tool pprof -http=:8080 in.pprof
Serving web UI on http://localhost:8080
^Z
What did you see happen?
When run through go tool, the ^Z does not return control to the shell. It does still seem to suspend the process, as ^C and ^\ (SIGQUIT) have no effect. You need to run pkill -CONT pprof from another terminal to resume execution and regain the ability to exit pprof.
What did you expect to see?
Behavior should be the same when running through go tool as when running directly.
This reproduces with Go 1.25.3 and 1.24.9.
This reproduces with bash (GNU bash, version 5.2.37(1)-release (x86_64-pc-linux-gnu)) and zsh (zsh 5.9 (x86_64-debian-linux-gnu)).
This was originally reported in #tools on Gopher Slack. Some additional findings there:
-
Without any flags, pprof has its own mini-repl command line mode. In that mode, it ignores ^Z entirely (i.e., it does not suspend and keeps working). This behaves the same standalone or via go tool.
-
Surprisingly, adding an additional layer of indirection via the golang.org/dl wrappers fixes the problem?
$ go install golang.org/dl/go1.25.3@latest
$ go1.25.3 download
$ go1.25.3 tool pprof -http=:8080 in.pprof
Serving web UI on http://localhost:8080
^Z
$ fg
go1.25.3 tool pprof -http=:8080 in.pprof
^C
$
Go version
go version go1.25.3 linux/amd64
Output of
go envin your module/workspace:What did you do?
cmd/pprof:pprof -http, and then suspend it with^Z(Control + z). This should drop you back to the shell, at which point you can usefgto resume execution and then exit with^C.This is working as intended.
go tool:What did you see happen?
When run through
go tool, the^Zdoes not return control to the shell. It does still seem to suspend the process, as^Cand^\(SIGQUIT) have no effect. You need to runpkill -CONT pproffrom another terminal to resume execution and regain the ability to exitpprof.What did you expect to see?
Behavior should be the same when running through
go toolas when running directly.This reproduces with Go 1.25.3 and 1.24.9.
This reproduces with bash (
GNU bash, version 5.2.37(1)-release (x86_64-pc-linux-gnu)) and zsh (zsh 5.9 (x86_64-debian-linux-gnu)).This was originally reported in #tools on Gopher Slack. Some additional findings there:
Without any flags,
pprofhas its own mini-repl command line mode. In that mode, it ignores ^Z entirely (i.e., it does not suspend and keeps working). This behaves the same standalone or viago tool.pprof's command line. It's possible thatpprof -httpdoes some or all of those termios adjustments.Surprisingly, adding an additional layer of indirection via the
golang.org/dlwrappers fixes the problem?