From 232b2e3352b0e3913421dc43cb29003eac1c5130 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Fri, 1 Dec 2017 13:19:39 -0500 Subject: [PATCH] cmd/go: fix reuse of cached objects during cover The cover variable indices could vary from build to build, but they were not included in the build ID hash, so that reusing the previously built package was not safe. Make the indices no longer vary from build to build, so that caching is safe. Fixes #22652. Change-Id: Ie26d73c648aadd285f97e0bf39619cabc3da54f2 Reviewed-on: https://go-review.googlesource.com/81515 Run-TryBot: Russ Cox TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- src/cmd/go/go_test.go | 16 ++++++++++++++++ src/cmd/go/internal/test/test.go | 3 +-- src/cmd/go/internal/work/buildid.go | 5 ++++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go index 691945b9ef..c2fe8b09b4 100644 --- a/src/cmd/go/go_test.go +++ b/src/cmd/go/go_test.go @@ -4908,6 +4908,22 @@ func TestCacheOutput(t *testing.T) { } } +func TestCacheCoverage(t *testing.T) { + if strings.Contains(os.Getenv("GODEBUG"), "gocacheverify") { + t.Skip("GODEBUG gocacheverify") + } + + tg := testgo(t) + defer tg.cleanup() + tg.parallel() + tg.setenv("GOPATH", filepath.Join(tg.pwd(), "testdata")) + tg.makeTempdir() + + tg.setenv("GOCACHE", filepath.Join(tg.tempdir, "c1")) + tg.run("test", "-cover", "strings") + tg.run("test", "-cover", "math", "strings") +} + func TestIssue22588(t *testing.T) { // Don't get confused by stderr coming from tools. tg := testgo(t) diff --git a/src/cmd/go/internal/test/test.go b/src/cmd/go/internal/test/test.go index 1513a8083f..a14a3f4438 100644 --- a/src/cmd/go/internal/test/test.go +++ b/src/cmd/go/internal/test/test.go @@ -1173,8 +1173,6 @@ func recompileForTest(pmain, preal, ptest *load.Package) { } } -var coverIndex = 0 - // isTestFile reports whether the source file is a set of tests and should therefore // be excluded from coverage analysis. func isTestFile(file string) bool { @@ -1186,6 +1184,7 @@ func isTestFile(file string) bool { // to the files, to be used when annotating the files. func declareCoverVars(importPath string, files ...string) map[string]*load.CoverVar { coverVars := make(map[string]*load.CoverVar) + coverIndex := 0 for _, file := range files { if isTestFile(file) { continue diff --git a/src/cmd/go/internal/work/buildid.go b/src/cmd/go/internal/work/buildid.go index 7c09b0d8e5..3c90c15a70 100644 --- a/src/cmd/go/internal/work/buildid.go +++ b/src/cmd/go/internal/work/buildid.go @@ -474,7 +474,10 @@ func (b *Builder) updateBuildID(a *Action, target string, rewrite bool) error { if a.output == nil { panic("internal error: a.output not set") } - c.Put(a.actionID, r) + outputID, _, err := c.Put(a.actionID, r) + if err == nil && cfg.BuildX { + b.Showcmd("", "%s # internal", joinUnambiguously(str.StringList("cp", target, c.OutputFile(outputID)))) + } c.PutBytes(cache.Subkey(a.actionID, "stdout"), a.output) r.Close() }