Skip to content

runtime: darwin CPU profiles omit systemstack callers during syscalls #80921

Open

Description

@rhysh

Go version

go version go1.28-devel_82065aa34d Mon Aug 17 10:35:04 2026 -0700 darwin/arm64

Output of go env in your module/workspace:

AR='ar'
CC='clang'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='clang++'
GCCGO='gccgo'
GO111MODULE=''
GOARCH='arm64'
GOARM64='v8.0'
GOAUTH='netrc'
GOBIN='/Users/rhysh/go/bin'
GOCACHE='/Users/rhysh/Library/Caches/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/Users/rhysh/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/pw/d_qmtcrd3vs0890gvmrq8qx80000gn/T/go-build3165146723=/tmp/go-build -gno-record-gcc-switches -fno-common'
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMOD='/dev/null'
GOMODCACHE='/Users/rhysh/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='darwin'
GOPACKAGESDRIVER=''
GOPATH='/Users/rhysh/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTELEMETRY='on'
GOTELEMETRYDIR='/Users/rhysh/Library/Application Support/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.28-devel_82065aa34d Mon Aug 17 10:35:04 2026 -0700'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you do?

I took a CPU profile on darwin/arm64: a platform that uses SIGPROF for threads to profile themselves, and which also uses libcall for some syscalls.

I looked at the CPU profile samples that make particular syscalls and attempted to find their root, past a systemstack call.

$ go test runtime -bench=BenchmarkChanCreation -run=NONE -cpuprofile ./cpu.pb.gz
goos: darwin
goarch: arm64
pkg: runtime
cpu: Apple M1
BenchmarkChanCreation-8         40789101                28.87 ns/op
PASS
ok      runtime 2.533s

$ go tool pprof -focus=runtime.usleep -peek=runtime.systemstack ./cpu.pb.gz 
File: runtime.test
Type: cpu
Time: 2026-08-17 11:02:52 PDT
Duration: 2.11s, Total samples = 8.26s (391.66%)
Active filters:
   focus=runtime.usleep
Showing nodes accounting for 2.22s, 26.88% of 8.26s total
----------------------------------------------------------+-------------
      flat  flat%   sum%        cum   cum%   calls calls% + context              
----------------------------------------------------------+-------------
         0     0%     0%      0.45s  5.45%                | runtime.systemstack
                                             0.40s 88.89% |   runtime.(*mheap).freeSpan.func1
                                             0.02s  4.44% |   runtime.(*mheap).alloc.func1
                                             0.02s  4.44% |   runtime.(*pageAlloc).scavenge.func1
                                             0.01s  2.22% |   runtime.forEachP.func1
----------------------------------------------------------+-------------

What did you see happen?

The CPU profile samples that end in libcall syscalls don't follow the call stack past runtime.systemstack; note the lack of callers in the go tool pprof -peek=runtime.systemstack output above.

What did you expect to see?

I expected CPU profile samples to trace back past systemstack just as well when in syscalls as they do when executing Go code.

It looks like there's an unwindJumpStack flag missing in the usesLibcall branch of the SIGPROF handler: https://github.com/golang/go/blob/82065aa34d/src/runtime/proc.go#L5862-L5872

I see that @prattmic ran into some trouble in that area in #50936, leading to the full revert of CL 358900. That appears to have been permanently fixed by CL 428656.

Activity

  1. added
    NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.
    on Aug 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.compiler/runtimeIssues related to the Go compiler and/or runtime.

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions