Repository navigation
cmd/go: test -coverprofile writes cached coverage blocks again when the cached test result is invalid #81824
Copy link
Copy link
Open
Labels
NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Description
Go version
go version go1.27.1 darwin/arm64
Output of go env in your module/workspace:
AR='ar'
CC='clang'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS='-I/opt/homebrew/include'
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-L/opt/homebrew/lib'
CXX='clang++'
GCCGO='gccgo'
GO111MODULE=''
GOARCH='arm64'
GOARM64='v8.0'
GOAUTH='netrc'
GOBIN='/Users/elton/go/bin'
GOCACHE='/Users/elton/lab/repro/cache'
GOCACHEPROG=''
GODEBUG=''
GOENV='/Users/elton/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/h1/kf1j70fs3d9g7g2lm_t8c45w0000gn/T/go-build3078940608=/tmp/go-build -gno-record-gcc-switches -fno-common'
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMOD='/Users/elton/lab/repro/go.mod'
GOMODCACHE='/Users/elton/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='darwin'
GOPACKAGESDRIVER=''
GOPATH='/Users/elton/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/Users/elton/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.27.1.darwin-arm64'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/Users/elton/Library/Application Support/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/Users/elton/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.27.1.darwin-arm64/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.27.1'
GOWORK=''
PKG_CONFIG='pkg-config'What did you do?
go test -coverprofile can reuse a cached test result and produce an incorrect coverage profile.
cat > go.mod <<'EOF'
module m
go 1.27.1
EOF
cat > main.go <<'EOF'
package main
func Abs(x int) int {
if x < 0 {
return -x
}
return x
}
EOF
cat > main_test.go <<'EOF'
package main
import "testing"
func TestAbs(t *testing.T) {
Abs(-1)
}
EOF
go test -coverprofile=c1.out .
go test -coverprofile=c2.out . # (cached)
go clean -testcache
go test -coverprofile=c3.out .
wc -l c1.out c2.out c3.out
sort c3.out | uniq -cWhat did you see happen?
c3.out triples the output of c1.out / c2.out
$ wc -l c1.out c2.out c3.out
4 c1.out
4 c2.out
10 c3.out
18 total
$ sort c3.out | uniq -c
3 m/main.go:4.2,4.11 1 1
3 m/main.go:5.3,6.1 1 1
3 m/main.go:7.2,7.10 1 0
1 mode: set
go tool cover -func=c3.out accepts the file with the duplicated lines and reports the normal percentage, silencing the corruption. However, when using go test with -covermode=count or atomic, the hit counts are tripled.
In a multi-package run, only the affected package is duplicated.
What did you expect to see?
The c3.out output should be identical to c1.out, containing each block once. The cached profile should be merged only when tryCacheWithID returns true.
Impact: the profile is corrupted silently. Tools that reject duplicate blocks fail (for example a CI step that merges shard profiles).
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Activity
cmd/go: merge cached cover profile only when the cached result is used
gopherbot commentedon Sep 28, 2026
Change https://go.dev/cl/840485 mentions this issue:
cmd/go: merge cached cover profile only when the cached result is usedgabyhelp commentedon Sep 28, 2026
Related Issues
Related Code Changes
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)
prattmic commentedon Sep 29, 2026
cc @golang/command-line