-
Notifications
You must be signed in to change notification settings - Fork 18.5k
Description
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 usefgto 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,
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.- This is likely a result of some termios adjustments done for
pprof's command line. It's possible thatpprof -httpdoes some or all of those termios adjustments. - For reference, Delve had similar ^Z ignored behavior, but wanted to support ^Z in its command line, which it did via pkg/terminal: support ctrlz for shell job control go-delve/delve#2806 and follow-up fix go-delve/liner@4726ab1.
- This is likely a result of some termios adjustments done for
-
Surprisingly, adding an additional layer of indirection via the
golang.org/dlwrappers 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
$