Than McIntosh has uploaded this change for review.
runtime/coverage: apis to emit counter data under user control
DO NOT SUBMIT
Add hooks to allow writing of coverage counter data and meta-data
under user control, so as to provide hooks for collecting coverage
data from programs that do not terminate.
Change-Id: I34ee6cee52e5597fa3698b8b04f1b34a2a2a418f
---
M api/next/51430.txt
A src/runtime/coverage/apis.go
M src/runtime/coverage/emit.go
A src/runtime/coverage/emitdata_test.go
A src/runtime/coverage/testdata/harness.go
5 files changed, 472 insertions(+), 72 deletions(-)
diff --git a/api/next/51430.txt b/api/next/51430.txt
index 46fdf21..19bbd83 100644
--- a/api/next/51430.txt
+++ b/api/next/51430.txt
@@ -1 +1,5 @@
+pkg runtime/coverage, func CoverageCounterDataEmitToDir(string) error #51430
+pkg runtime/coverage, func CoverageCounterDataEmitToWriter(io.Writer) error #51430
+pkg runtime/coverage, func CoverageMetaDataEmitToDir(string) error #51430
+pkg runtime/coverage, func CoverageMetaDataEmitToWriter(io.Writer) error #51430
pkg testing, func RegisterCover(Cover) (**string, **string) #51430
diff --git a/src/runtime/coverage/apis.go b/src/runtime/coverage/apis.go
new file mode 100644
index 0000000..9cce715
--- /dev/null
+++ b/src/runtime/coverage/apis.go
@@ -0,0 +1,70 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package coverage
+
+import (
+ "fmt"
+ "io"
+)
+
+// CoverageMetaDataEmitToDir writes a coverage meta-data file for the
+// currently running program to the directory specified in 'dir'. An
+// error will be returned if operation can't be completed successfully
+// (for example, if the currently running program was not built with
+// "-cover", or if the directory does not exist).
+func CoverageMetaDataEmitToDir(dir string) error {
+ if !finalHashComputed {
+ return fmt.Errorf("error: no meta-data available (binary not built with -cover?)")
+ }
+ return emitMetaDataToDirectory(dir)
+}
+
+// CoverageMetaDataEmitToWriter writes the meta-data content (the
+// payload that would normally be emitted to a meta-data file) for
+// currently running program to the the writer 'w'. An error will be
+// returned if operation can't be completed successfully (for example,
+// if the currently running program was not built with "-cover", or if
+// a write fails).
+func CoverageMetaDataEmitToWriter(w io.Writer) error {
+ if !finalHashComputed {
+ return fmt.Errorf("error: no meta-data available (binary not built with -cover?)")
+ }
+ ml := runtime_getcovmetalist()
+ return emitMetaDataToWriter(w, ml, cmode, finalHash)
+}
+
+// CoverageCounterDataEmitToDir writes a coverage counter-data file for the
+// currently running program to the directory specified in 'dir'. An
+// error will be returned if operation can't be completed successfully
+// (for example, if the currently running program was not built with
+// "-cover", or if the directory does not exist). The counter data written
+// will be a snapshot taken at the point of the invocation.
+func CoverageCounterDataEmitToDir(dir string) error {
+ return emitCounterDataToDirectory(dir)
+}
+
+// CoverageCounterDataEmitToWriter writes coverage counter-data
+// content for the currently running program to the writer 'w'. An
+// error will be returned if operation can't be completed successfully
+// (for example, if the currently running program was not built with
+// "-cover", or if a write fails). The counter data written will be a
+// snapshot taken at the point of the invocation.
+func CoverageCounterDataEmitToWriter(w io.Writer) error {
+ // Ask the runtime for the list of coverage counter symbols.
+ cl := runtime_getcovcounterlist()
+ if len(cl) == 0 {
+ return fmt.Errorf("program not built with -coverage")
+ }
+ if !finalHashComputed {
+ return fmt.Errorf("meta-data not written yet, unable to write counter data")
+ }
+
+ pm := runtime_getcovpkgmap()
+ s := &emitState{
+ counterlist: cl,
+ pkgmap: pm,
+ }
+ return s.emitCounterDataToWriter(w)
+}
diff --git a/src/runtime/coverage/emit.go b/src/runtime/coverage/emit.go
index 3a6d578..33e493e 100644
--- a/src/runtime/coverage/emit.go
+++ b/src/runtime/coverage/emit.go
@@ -10,6 +10,7 @@
"internal/coverage"
"internal/coverage/encodecounter"
"internal/coverage/encodemeta"
+ "io"
"os"
"path/filepath"
"reflect"
@@ -59,7 +60,7 @@
func runtime_getcovpkgmap() map[int]int
//go:linkname runtime_reportInsanityInHardcodedList runtime.reportInsanityInHardcodedList
-func runtime_reportInsanityInHardcodedList(pkgId int32)
+func runtime_reportInsanityInHardcodedList(slot int32, pkgId int32)
// emitState holds useful state information during the emit process.
type emitState struct {
@@ -89,9 +90,11 @@
// symbols registered during init. It is used both for writing the
// meta-data file and counter-aata files.
var finalHash [16]byte
+var metaDataEmitAttempted bool
var finalHashComputed bool
var finalMetaLen uint64
var cmode coverage.CounterMode
+var gocoverdir string
type fileType int
@@ -102,18 +105,36 @@
)
// emitMetaData emits the meta-data output file for this coverage run.
+// This entry point is intended to be invoked by the compiler from
+// an instrumented program's main package init func.
func emitMetaData() {
+ gocoverdir = os.Getenv("GOCOVERDIR")
+ if gocoverdir == "" {
+ fmt.Fprintf(os.Stderr, "warning: GOCOVERDIR not set, no coverage data emitted\n")
+ return
+ }
+ if err := emitMetaDataToDirectory(gocoverdir); err != nil {
+ fmt.Fprintf(os.Stderr, "error: coverage data emit failed: %v\n", err)
+ }
+}
+
+// emitMetaData emits the meta-data output file to the specified
+// directory, returning an error if something went wrong.
+func emitMetaDataToDirectory(outdir string) error {
+
+ metaDataEmitAttempted = true
// Ask the runtime for the list of coverage meta-data symbols.
ml := runtime_getcovmetalist()
if len(ml) == 0 {
- return
+ return fmt.Errorf("program not built with -coverage")
}
s := &emitState{
metalist: ml,
debug: os.Getenv("GOCOVERDEBUG") != "",
+ outdir: outdir,
}
if s.debug {
@@ -121,7 +142,7 @@
for k, b := range ml {
fmt.Fprintf(os.Stderr, "=+= slot: %d path: %s ", k, b.pkgpath)
if b.pkid != -1 {
- fmt.Fprintf(os.Stderr, " hard-coded id: %d", b.pkid)
+ fmt.Fprintf(os.Stderr, " hcid: %d", b.pkid)
}
fmt.Fprintf(os.Stderr, "\n")
}
@@ -145,9 +166,7 @@
cmode = entry.cmode
} else {
if cmode != entry.cmode {
- // Should this be panic or throw?
- fmt.Fprintf(os.Stderr, "error: coverage counter mode clash: packge %s uses mode=%d, but package %s uses mode=%s\n", ml[0].pkgpath, cmode, entry.pkgpath, entry.cmode)
- return
+ return fmt.Errorf("coverage counter mode clash: packge %s uses mode=%d, but package %s uses mode=%s\n", ml[0].pkgpath, cmode, entry.pkgpath, entry.cmode)
}
}
}
@@ -158,27 +177,34 @@
finalMetaLen = tlen
// Open output files.
- s.openOutputFiles(finalHash, tlen, metaDataFile)
+ if err := s.openOutputFiles(finalHash, tlen, metaDataFile); err != nil {
+ return err
+ }
- // Emit meta-data file if needed.
+ // Emit meta-data file only if needed (may already be present).
if s.mf != nil {
- if !s.emitMetaDataFile(tlen, finalHash) {
- return
+ if err := s.emitMetaDataFile(tlen, finalHash); err != nil {
+ return err
}
}
+ return nil
+}
+
+// emitCounterData emits the counter data output file for this coverage run.
+func emitCounterData() {
+ if gocoverdir == "" || !finalHashComputed {
+ return
+ }
+ emitCounterDataToDirectory(gocoverdir)
}
// emitMetaData emits the counter-data output file for this coverage run.
-func emitCounterData() {
-
- if !finalHashComputed {
- return
- }
+func emitCounterDataToDirectory(outdir string) error {
// Ask the runtime for the list of coverage counter symbols.
cl := runtime_getcovcounterlist()
if len(cl) == 0 {
- return
+ return fmt.Errorf("program not built with -coverage")
}
// Ask the runtime for the list of coverage counter symbols.
@@ -186,25 +212,41 @@
s := &emitState{
counterlist: cl,
pkgmap: pm,
+ outdir: outdir,
debug: os.Getenv("GOCOVERDEBUG") != "",
}
// Open output file.
- s.openOutputFiles(finalHash, finalMetaLen, counterDataFile)
+ if err := s.openOutputFiles(finalHash, finalMetaLen, counterDataFile); err != nil {
+ return err
+ }
if s.cf == nil {
- // something went wrong, bail here.
- return
+ return fmt.Errorf("counter data output file open failed (no additional info")
}
// Emit counter data file.
- s.emitCounterDataFile(finalHash)
+ if err := s.emitCounterDataFile(finalHash, s.cf); err != nil {
+ return err
+ }
+ if err := s.cf.Close(); err != nil {
+ return fmt.Errorf("closing counter data file: %v", err)
+ }
+ return nil
+}
+
+// emitMetaData emits counter data for this coverage run to an io.Writer.
+func (s *emitState) emitCounterDataToWriter(w io.Writer) error {
+ if err := s.emitCounterDataFile(finalHash, w); err != nil {
+ return err
+ }
+ return nil
}
// openMetaFile determines whether we need to emit a meta-data output
// file, or whether we can reuse the existing file in the coverage out
// dir. It updates mfname/mftmp/mf fields in 'od', returning false on
// error and true for success.
-func (s *emitState) openMetaFile(metaHash [16]byte, metaLen uint64) bool {
+func (s *emitState) openMetaFile(metaHash [16]byte, metaLen uint64) error {
// Open meta-outfile for reading to see if it exists.
fn := fmt.Sprintf("%s.%x", coverage.MetaFilePref, metaHash)
@@ -215,28 +257,25 @@
s.mftmp = s.mfname + fmt.Sprintf("%d", time.Now().UnixNano())
s.mf, err = os.OpenFile(s.mftmp, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
if err != nil {
- fmt.Fprintf(os.Stderr, "error opening %s: %v\n", s.mftmp, err)
- return false
+ return fmt.Errorf("opening meta-data file %s: %v", s.mftmp, err)
}
}
- return true
+ return nil
}
// openCounterFile opens an output file for the counter data portion of a
// test coverage run. If updates the 'cfname' and 'cf' fields in the
-// passed in state struct, returning false on error (if there was an
-// error opening the file) or true for success.
-func (s *emitState) openCounterFile(metaHash [16]byte) bool {
+// passed in state struct, returning an error if something went wrong.
+func (s *emitState) openCounterFile(metaHash [16]byte) error {
processID := os.Getpid()
fn := fmt.Sprintf(coverage.CounterFileTempl, coverage.CounterFilePref, metaHash, processID, time.Now().UnixNano())
s.cfname = filepath.Join(s.outdir, fn)
var err error
s.cf, err = os.OpenFile(s.cfname, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
if err != nil {
- fmt.Fprintf(os.Stderr, "error opening %s: %v\n", s.cfname, err)
- return false
+ return fmt.Errorf("opening counter data file %s: %v", s.cfname, err)
}
- return true
+ return nil
}
// openOutputFiles opens output files in preparation for emitting
@@ -250,43 +289,54 @@
// 'mf', close it, and then rename 'mftmp' to 'mfname'. This function
// also opens the counter data output file, setting 'cf' and 'cfname'
// in the state struct.
-func (s *emitState) openOutputFiles(metaHash [16]byte, metaLen uint64, which fileType) bool {
- s.outdir = os.Getenv("GOCOVERDIR")
- if s.outdir == "" {
- if which == metaDataFile {
- fmt.Fprintf(os.Stderr, "warning: GOCOVERDIR not set, no coverage data emitted\n")
- }
- return false
- }
+func (s *emitState) openOutputFiles(metaHash [16]byte, metaLen uint64, which fileType) error {
fi, err := os.Stat(s.outdir)
if err != nil {
- fmt.Fprintf(os.Stderr, "warning: GOCOVERDIR setting %q inaccessible (err: %v); no coverage data emtted\n", s.outdir, err)
- return false
+ return fmt.Errorf("output directory %q inaccessible (err: %v); no coverage data emtted", s.outdir, err)
}
if !fi.IsDir() {
- fmt.Fprintf(os.Stderr, "warning: GOCOVERDIR setting %q not a directory; no coverage data emtted\n", s.outdir)
- return false
+ return fmt.Errorf("output directory %q not a directory; no coverage data emtted", s.outdir)
}
- if (which&metaDataFile) != 0 && !s.openMetaFile(metaHash, metaLen) {
- return false
+ if (which & metaDataFile) != 0 {
+ if err := s.openMetaFile(metaHash, metaLen); err != nil {
+ return err
+ }
}
- if (which&counterDataFile) != 0 && !s.openCounterFile(metaHash) {
- return false
+ if (which & counterDataFile) != 0 {
+ if err := s.openCounterFile(metaHash); err != nil {
+ return err
+ }
}
- return true
+ return nil
}
// emitMetaDataFile emits coverage meta-data to a previously opened
// temporary file (s.mftmp), then renames the generated file to the
// final path (s.mfname).
-func (s *emitState) emitMetaDataFile(tlen uint64, finalHash [16]byte) bool {
- mfw := encodemeta.NewCoverageMetaFileWriter(s.mftmp, s.mf)
+func (s *emitState) emitMetaDataFile(tlen uint64, finalHash [16]byte) error {
+
+ if err := emitMetaDataToWriter(s.mf, s.metalist, cmode, finalHash); err != nil {
+ return fmt.Errorf("writing %s: %v\n", s.mftmp, err)
+ }
+
+ // Temp file has now been flushed and closed. Rename the temp to the
+ // final desired path.
+ if err := os.Rename(s.mftmp, s.mfname); err != nil {
+ return fmt.Errorf("writing %s: rename from %s failed: %v\n", s.mfname, s.mftmp, err)
+ }
+
+ // We're done.
+ return nil
+}
+
+func emitMetaDataToWriter(w io.Writer, metalist []covmetablob, cmode coverage.CounterMode, finalHash [16]byte) error {
+ mfw := encodemeta.NewCoverageMetaFileWriter("<io.Writer>", w)
blobs := [][]byte{}
var sd []byte
bufHdr := (*reflect.SliceHeader)(unsafe.Pointer(&sd))
- for _, e := range s.metalist {
+ for _, e := range metalist {
bufHdr.Data = uintptr(unsafe.Pointer(e.p))
bufHdr.Len = int(e.len)
bufHdr.Cap = int(e.len)
@@ -297,21 +347,7 @@
if ok {
moduleName = bip.Main.Path
}
- err := mfw.Write(finalHash, moduleName, blobs, cmode)
- if err != nil {
- fmt.Fprintf(os.Stderr, "error writing %s: %v\n", s.mftmp, err)
- return false
- }
-
- // Temp file has now been flushed and closed. Rename the temp to the
- // final desired path.
- if err = os.Rename(s.mftmp, s.mfname); err != nil {
- fmt.Fprintf(os.Stderr, "error writing %s: rename from %s failed: %v\n", s.mfname, s.mftmp, err)
- return false
- }
-
- // We're done.
- return true
+ return mfw.Write(finalHash, moduleName, blobs, cmode)
}
func (s *emitState) NumFuncs() (int, error) {
@@ -375,7 +411,7 @@
fmt.Fprintf(os.Stderr, "\n=+= %d: pk=%d visit live fcn",
i, pkgId)
}
- fmt.Fprintf(os.Stderr, " {F%d NC%d}", funcId, nCtrs)
+ fmt.Fprintf(os.Stderr, " {i=%d F%d NC%d}", i, funcId, nCtrs)
}
// Vet and/or fix up package ID. A package ID of zero
@@ -386,12 +422,14 @@
// Go development (e.g. tip).
ipk := int32(pkgId)
if ipk == 0 {
- runtime_reportInsanityInHardcodedList(ipk)
+ fmt.Fprintf(os.Stderr, "\n")
+ runtime_reportInsanityInHardcodedList(int32(i), ipk)
} else if ipk < 0 {
if newId, ok := s.pkgmap[int(ipk)]; ok {
pkgId = uint32(newId)
} else {
- runtime_reportInsanityInHardcodedList(int32(pkgId))
+ fmt.Fprintf(os.Stderr, "\n")
+ runtime_reportInsanityInHardcodedList(int32(i), ipk)
}
} else {
pkgId--
@@ -422,15 +460,15 @@
// emitCounterDataFile emits the counter data portion of a
// coverage output file (to the file 's.cf').
-func (s *emitState) emitCounterDataFile(finalHash [16]byte) {
+func (s *emitState) emitCounterDataFile(finalHash [16]byte, w io.Writer) error {
// FIXME: do we want to copy os.Args early (during init) so as to
// avoid any user program modifications? Or maybe we want to see
// modifications.
- cfw := encodecounter.NewCoverageDataFileWriter(s.cf, coverage.CtrULeb128)
- defer s.cf.Close()
+ cfw := encodecounter.NewCoverageDataFileWriter(w, coverage.CtrULeb128)
if err := cfw.Write(finalHash, captureOsArgs(), s); err != nil {
- fmt.Fprintf(os.Stderr, "error writing coverage data: %v\n", err)
+ return err
}
+ return nil
}
diff --git a/src/runtime/coverage/emitdata_test.go b/src/runtime/coverage/emitdata_test.go
new file mode 100644
index 0000000..712aa7f
--- /dev/null
+++ b/src/runtime/coverage/emitdata_test.go
@@ -0,0 +1,191 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package coverage
+
+import (
+ "fmt"
+ "internal/coverage"
+ "internal/testenv"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "strings"
+ "testing"
+)
+
+// Set to true for debugging.
+const fixedTestDir = false
+
+func TestCoverageApis(t *testing.T) {
+ testenv.MustHaveGoBuild(t)
+ dir := t.TempDir()
+ if fixedTestDir {
+ dir = "/tmp/zzz"
+ os.RemoveAll(dir)
+ mkdir(t, dir)
+ }
+
+ // Build harness.
+ bdir := mkdir(t, filepath.Join(dir, "build"))
+ rdir := mkdir(t, filepath.Join(dir, "runDir"))
+ edir := mkdir(t, filepath.Join(dir, "emitDir"))
+ wdir := mkdir(t, filepath.Join(dir, "writerDir"))
+ harnessPath := buildHarness(t, bdir, []string{"-cover"})
+
+ t.Logf("harness path is %s", harnessPath)
+
+ // Sub-tests for each API we want to inspect, plus
+ // extras for error testing.
+ t.Run("emitToDir", func(t *testing.T) {
+ t.Parallel()
+ testEmitToDir(t, harnessPath, rdir, edir)
+ })
+ t.Run("emitToWriter", func(t *testing.T) {
+ t.Parallel()
+ testEmitToWriter(t, harnessPath, rdir, wdir)
+ })
+}
+
+// buildHarness builds the helper program "dwdumploc.exe".
+func buildHarness(t *testing.T, dir string, opts []string) string {
+ harnessPath := filepath.Join(dir, "harness.exe")
+ harnessSrc := filepath.Join("testdata", "harness.go")
+ args := []string{"build", "-gcflags=all=-l -N", "-o", harnessPath}
+ args = append(args, opts...)
+ args = append(args, harnessSrc)
+ cmd := exec.Command(testenv.GoToolPath(t), args...)
+ if b, err := cmd.CombinedOutput(); err != nil {
+ t.Fatalf("build failed (%v): %s", err, b)
+ }
+ return harnessPath
+}
+
+func mkdir(t *testing.T, d string) string {
+ if err := os.Mkdir(d, 0777); err != nil {
+ t.Fatalf("mkdir failed: %v", err)
+ }
+ return d
+}
+
+func TestApisOnNocoverBinary(t *testing.T) {
+ testenv.MustHaveGoBuild(t)
+ dir := t.TempDir()
+
+ // Build harness with no -cover.
+ bdir := mkdir(t, filepath.Join(dir, "nocover"))
+ edir := mkdir(t, filepath.Join(dir, "emitDirNo"))
+ harnessPath := buildHarness(t, bdir, nil)
+ output, err := runHarness(t, harnessPath, "emitToDir", edir, edir)
+ if err == nil {
+ t.Fatalf("expected error on TestApisOnNocoverBinary harness run")
+ }
+ const want = "not built with -cover"
+ if !strings.Contains(output, want) {
+ t.Errorf("error output does not contain %q: %s", want, output)
+ }
+}
+
+func addGoCoverDir(env []string, gcd string) []string {
+ rv := []string{}
+ found := false
+ for _, v := range env {
+ if strings.HasPrefix(v, "GOCOVERDIR=") {
+ v = "GOCOVERDIR=" + gcd
+ found = true
+ }
+ rv = append(rv, v)
+ }
+ if !found {
+ rv = append(rv, "GOCOVERDIR="+gcd)
+ }
+ return rv
+}
+
+func runHarness(t *testing.T, harnessPath string, tp string, rdir, edir string) (string, error) {
+ t.Logf("running: %s -tp %s -o %s with GOCOVERDIR=%s", harnessPath, tp, edir, rdir)
+ cmd := exec.Command(harnessPath, "-tp", tp, "-o", edir)
+ cmd.Dir = rdir
+ cmd.Env = addGoCoverDir(os.Environ(), rdir)
+ b, err := cmd.CombinedOutput()
+ t.Logf("harness run output: %s\n", string(b))
+ return string(b), err
+}
+
+func testEmitToDir(t *testing.T, harnessPath string, rdir, edir string) {
+ output, err := runHarness(t, harnessPath, "emitToDir", rdir, edir)
+ if err != nil {
+ t.Logf("%s", output)
+ t.Fatalf("running 'harness -tp emitDir': %v", err)
+ }
+
+ // Just check to make sure meta-data file and counter data file were
+ // written. Another alternative would be to run "go tool covdata"
+ // or equivalent, but for now, this is what we've got.
+ dents, err := os.ReadDir(edir)
+ if err != nil {
+ t.Fatalf("os.ReadDir(%s) failed: %v", edir, err)
+ }
+ mfc := 0
+ cdc := 0
+ for _, e := range dents {
+ if e.IsDir() {
+ continue
+ }
+ if strings.HasPrefix(e.Name(), coverage.MetaFilePref) {
+ mfc++
+ } else if strings.HasPrefix(e.Name(), coverage.CounterFilePref) {
+ cdc++
+ }
+ }
+ wantmf := 1
+ wantcf := 1
+ if mfc != wantmf {
+ t.Errorf("EmitToDir: want %d meta-data files, got %d\n", wantmf, mfc)
+ }
+ if cdc != wantcf {
+ t.Errorf("EmitToDir: want %d counter-data files, got %d\n", wantcf, cdc)
+ }
+}
+
+func testForSpecificFunctions(t *testing.T, dir string, want []string, avoid []string) string {
+ args := []string{"tool", "covdata", "dump",
+ "-live", "-emitdump", "-pkg=^main$", "-i=" + dir}
+ t.Logf("running: go %v\n", args)
+ cmd := exec.Command(testenv.GoToolPath(t), args...)
+ b, err := cmd.CombinedOutput()
+ if err != nil {
+ t.Fatalf("'go tool covdata failed (%v): %s", err, b)
+ }
+ output := string(b)
+ rval := ""
+ for _, f := range want {
+ wf := "Func: " + f
+ if strings.Contains(output, wf) {
+ continue
+ }
+ rval += fmt.Sprintf("error: output should contain %q but does not\n", wf)
+ }
+ for _, f := range avoid {
+ wf := "Func: " + f
+ if strings.Contains(output, wf) {
+ rval += fmt.Sprintf("error: output should not contain %q but does\n", wf)
+ }
+ }
+ return rval
+}
+
+func testEmitToWriter(t *testing.T, harnessPath string, rdir, edir string) {
+ tp := "emitToWriter"
+ output, err := runHarness(t, harnessPath, tp, rdir, edir)
+ if err != nil {
+ t.Logf("%s", output)
+ t.Fatalf("running 'harness -tp %s': %v", tp, err)
+ }
+ want := []string{"main", tp}
+ avoid := []string{"final"}
+ if msg := testForSpecificFunctions(t, edir, want, avoid); msg != "" {
+ t.Errorf("coverage data from %q output match failed: %s", tp, msg)
+ }
+}
diff --git a/src/runtime/coverage/testdata/harness.go b/src/runtime/coverage/testdata/harness.go
new file mode 100644
index 0000000..6fe8971
--- /dev/null
+++ b/src/runtime/coverage/testdata/harness.go
@@ -0,0 +1,82 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "flag"
+ "internal/coverage/slicewriter"
+ "io/ioutil"
+ "log"
+ "path/filepath"
+ "runtime/coverage"
+)
+
+// Good cases to handle:
+// - emit to directory
+// - emit to writer, then dump to named file
+//
+// Bad cases to handle:
+// - emit to non-existent dir
+// - emit to non-writable dir
+// - emit to nil writer
+// - emit to writer that fails somewhere along the line
+
+var verbflag = flag.Int("v", 0, "Verbose trace output level")
+var testpointflag = flag.String("tp", "", "Testpoint to run")
+var outdirflag = flag.String("o", "", "Output dir into which to emit")
+
+func emitToWriter() {
+ var slwm slicewriter.WriteSeeker
+ if err := coverage.CoverageMetaDataEmitToWriter(&slwm); err != nil {
+ log.Fatalf("error: CoverageMetaDataEmitToWriter returns %v", err)
+ }
+ mf := filepath.Join(*outdirflag, "covmeta.0abcdef")
+ if err := ioutil.WriteFile(mf, slwm.Payload(), 0666); err != nil {
+ log.Fatalf("error: writing %s: %v", mf, err)
+ }
+ var slwc slicewriter.WriteSeeker
+ if err := coverage.CoverageCounterDataEmitToWriter(&slwc); err != nil {
+ log.Fatalf("error: CoverageCounterDataEmitToWriter returns %v", err)
+ }
+ cf := filepath.Join(*outdirflag, "covcounters.0abcdef.99.77")
+ if err := ioutil.WriteFile(cf, slwc.Payload(), 0666); err != nil {
+ log.Fatalf("error: writing %s: %v", cf, err)
+ }
+}
+
+func emitToDir() {
+ if err := coverage.CoverageMetaDataEmitToDir(*outdirflag); err != nil {
+ log.Fatalf("error: CoverageMetaDataEmitToDir returns %v", err)
+ }
+ if err := coverage.CoverageCounterDataEmitToDir(*outdirflag); err != nil {
+ log.Fatalf("error: CoverageCounterDataEmitToDir returns %v", err)
+ }
+}
+
+func final() int {
+ println("I run last.")
+ return 43
+}
+
+func main() {
+ log.SetFlags(0)
+ log.SetPrefix("harness: ")
+ flag.Parse()
+ if *testpointflag == "" {
+ log.Fatalf("error: no testpoint (use -tp flag)")
+ }
+ if *outdirflag == "" {
+ log.Fatalf("error: no output dir specified (use -o flag)")
+ }
+ switch *testpointflag {
+ case "emitToDir":
+ emitToDir()
+ case "emitToWriter":
+ emitToWriter()
+ default:
+ log.Fatalf("error: unknown testpoint %q", *testpointflag)
+ }
+ final()
+}
To view, visit change 401236. To unsubscribe, or for help writing mail filters, visit settings.
Patch set 2:Run-TryBot +1
Patch set 3:Run-TryBot +1
Patch set 5:Run-TryBot +1
Patch set 6:Run-TryBot +1
Attention is currently required from: Than McIntosh.
Than McIntosh uploaded patch set #7 to this change.
runtime/coverage: apis to emit counter data under user control
DO NOT SUBMIT
Add hooks to allow writing of coverage counter data and meta-data
under user control, so as to provide hooks for collecting coverage
data from programs that do not terminate.
Change-Id: I34ee6cee52e5597fa3698b8b04f1b34a2a2a418f
---
M api/next/51430.txt
A src/runtime/coverage/apis.go
M src/runtime/coverage/emit.go
A src/runtime/coverage/emitdata_test.go
A src/runtime/coverage/testdata/harness.go
5 files changed, 477 insertions(+), 72 deletions(-)
To view, visit change 401236. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Than McIntosh.
Than McIntosh uploaded patch set #8 to this change.
runtime/coverage: apis to emit counter data under user control
DO NOT SUBMIT
Add hooks to allow writing of coverage counter data and meta-data
under user control, so as to provide hooks for collecting coverage
data from programs that do not terminate.
Change-Id: I34ee6cee52e5597fa3698b8b04f1b34a2a2a418f
---
M api/next/51430.txt
A src/runtime/coverage/apis.go
M src/runtime/coverage/emit.go
A src/runtime/coverage/emitdata_test.go
A src/runtime/coverage/testdata/harness.go
5 files changed, 371 insertions(+), 0 deletions(-)
To view, visit change 401236. To unsubscribe, or for help writing mail filters, visit settings.
Patch set 8:Run-TryBot +1
Patch set 9:Run-TryBot +1
Than McIntosh uploaded patch set #14 to this change.
runtime/coverage: apis to emit counter data under user control
DO NOT SUBMIT
Add hooks to allow writing of coverage counter data and meta-data
under user control, so as to provide hooks for collecting coverage
data from programs that do not terminate.
Change-Id: I34ee6cee52e5597fa3698b8b04f1b34a2a2a418f
---
M api/next/51430.txt
A src/runtime/coverage/apis.go
M src/runtime/coverage/emit.go
A src/runtime/coverage/emitdata_test.go
A src/runtime/coverage/testdata/harness.go
5 files changed, 371 insertions(+), 0 deletions(-)
To view, visit change 401236. To unsubscribe, or for help writing mail filters, visit settings.
Patch set 14:Run-TryBot +1
Than McIntosh uploaded patch set #15 to this change.
runtime/coverage: apis to emit counter data under user control
DO NOT SUBMIT
Add hooks to allow writing of coverage counter data and meta-data
under user control, so as to provide hooks for collecting coverage
data from programs that do not terminate.
Change-Id: I34ee6cee52e5597fa3698b8b04f1b34a2a2a418f
---
M api/next/51430.txt
A src/runtime/coverage/apis.go
M src/runtime/coverage/emit.go
A src/runtime/coverage/emitdata_test.go
A src/runtime/coverage/testdata/harness.go
5 files changed, 371 insertions(+), 0 deletions(-)
To view, visit change 401236. To unsubscribe, or for help writing mail filters, visit settings.
Than McIntosh uploaded patch set #16 to this change.
runtime/coverage: apis to emit counter data under user control
DO NOT SUBMIT
Add hooks to allow writing of coverage counter data and meta-data
under user control, so as to provide hooks for collecting coverage
data from programs that do not terminate.
Change-Id: I34ee6cee52e5597fa3698b8b04f1b34a2a2a418f
---
M api/next/51430.txt
A src/runtime/coverage/apis.go
M src/runtime/coverage/emit.go
A src/runtime/coverage/emitdata_test.go
A src/runtime/coverage/testdata/harness.go
5 files changed, 371 insertions(+), 0 deletions(-)
To view, visit change 401236. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Than McIntosh.
Than McIntosh uploaded patch set #18 to this change.
runtime/coverage: apis to emit counter data under user control
DO NOT SUBMIT
Add hooks to allow writing of coverage counter data and meta-data
under user control, so as to provide hooks for collecting coverage
data from programs that do not terminate.
Change-Id: I34ee6cee52e5597fa3698b8b04f1b34a2a2a418f
---
M api/next/51430.txt
A src/runtime/coverage/apis.go
M src/runtime/coverage/emit.go
A src/runtime/coverage/emitdata_test.go
A src/runtime/coverage/testdata/harness.go
5 files changed, 375 insertions(+), 0 deletions(-)
To view, visit change 401236. To unsubscribe, or for help writing mail filters, visit settings.
Patch set 20:Run-TryBot +1
Attention is currently required from: Than McIntosh.
Than McIntosh uploaded patch set #21 to this change.
runtime/coverage: apis to emit counter data under user control
DO NOT SUBMIT
Add hooks to allow writing of coverage counter data and meta-data
under user control, so as to provide hooks for collecting coverage
data from programs that do not terminate.
Change-Id: I34ee6cee52e5597fa3698b8b04f1b34a2a2a418f
---
M api/next/51430.txt
A src/runtime/coverage/apis.go
M src/runtime/coverage/emit.go
A src/runtime/coverage/emitdata_test.go
A src/runtime/coverage/testdata/harness.go
5 files changed, 375 insertions(+), 0 deletions(-)
To view, visit change 401236. To unsubscribe, or for help writing mail filters, visit settings.
Patch set 21:Run-TryBot +1
Attention is currently required from: Than McIntosh.
Than McIntosh uploaded patch set #22 to this change.
runtime/coverage: apis to emit counter data under user control
DO NOT SUBMIT
Add hooks to allow writing of coverage counter data and meta-data
under user control, so as to provide hooks for collecting coverage
data from programs that do not terminate.
Change-Id: I34ee6cee52e5597fa3698b8b04f1b34a2a2a418f
---
M api/next/51430.txt
A src/runtime/coverage/apis.go
M src/runtime/coverage/emit.go
A src/runtime/coverage/emitdata_test.go
A src/runtime/coverage/testdata/harness.go
5 files changed, 375 insertions(+), 0 deletions(-)
To view, visit change 401236. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Than McIntosh.
Than McIntosh uploaded patch set #27 to this change.
runtime/coverage: apis to emit counter data under user control
DO NOT SUBMIT
Add hooks to allow writing of coverage counter data and meta-data
under user control, so as to provide hooks for collecting coverage
data from programs that do not terminate.
Change-Id: I34ee6cee52e5597fa3698b8b04f1b34a2a2a418f
---
M api/next/51430.txt
A src/runtime/coverage/apis.go
M src/runtime/coverage/emit.go
A src/runtime/coverage/emitdata_test.go
A src/runtime/coverage/testdata/harness.go
5 files changed, 375 insertions(+), 0 deletions(-)
To view, visit change 401236. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Than McIntosh.
Than McIntosh uploaded patch set #28 to this change.
runtime/coverage: apis to emit counter data under user control
DO NOT SUBMIT
Add hooks to allow writing of coverage counter data and meta-data
under user control, so as to provide hooks for collecting coverage
data from programs that do not terminate.
Updates #51430.
Change-Id: I34ee6cee52e5597fa3698b8b04f1b34a2a2a418f
---
M api/next/51430.txt
A src/runtime/coverage/apis.go
M src/runtime/coverage/emit.go
A src/runtime/coverage/emitdata_test.go
A src/runtime/coverage/testdata/harness.go
5 files changed, 377 insertions(+), 0 deletions(-)
To view, visit change 401236. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Than McIntosh.
Than McIntosh uploaded patch set #29 to this change.
runtime/coverage: apis to emit counter data under user control
DO NOT SUBMIT
Add hooks to allow writing of coverage counter data and meta-data
under user control, so as to provide hooks for collecting coverage
data from programs that do not terminate.
Updates #51430.
Change-Id: I34ee6cee52e5597fa3698b8b04f1b34a2a2a418f
---
M api/next/51430.txt
A src/runtime/coverage/apis.go
M src/runtime/coverage/emit.go
A src/runtime/coverage/emitdata_test.go
A src/runtime/coverage/testdata/harness.go
5 files changed, 377 insertions(+), 1 deletion(-)
To view, visit change 401236. To unsubscribe, or for help writing mail filters, visit settings.
Patch set 32:Run-TryBot +1
Attention is currently required from: Than McIntosh.
Than McIntosh uploaded patch set #37 to this change.
runtime/coverage: apis to emit counter data under user control
DO NOT SUBMIT
Add hooks/apis to support writing of coverage counter data and
meta-data under user control (from within an executing "-cover"
binary), so as to provide a way to obtain coverage data from programs
that do not terminate.
Updates #51430.
Change-Id: I34ee6cee52e5597fa3698b8b04f1b34a2a2a418f
---
M api/next/51430.txt
A src/runtime/coverage/apis.go
M src/runtime/coverage/emit.go
A src/runtime/coverage/emitdata_test.go
A src/runtime/coverage/testdata/harness.go
5 files changed, 669 insertions(+), 1 deletion(-)
To view, visit change 401236. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Than McIntosh.
Than McIntosh uploaded patch set #40 to this change.
runtime/coverage: apis to emit counter data under user control
DO NOT SUBMIT
Add hooks/apis to support writing of coverage counter data and
meta-data under user control (from within an executing "-cover"
binary), so as to provide a way to obtain coverage data from programs
that do not terminate.
Updates #51430.
Change-Id: I34ee6cee52e5597fa3698b8b04f1b34a2a2a418f
---
M api/next/51430.txt
A src/runtime/coverage/apis.go
M src/runtime/coverage/emit.go
A src/runtime/coverage/emitdata_test.go
A src/runtime/coverage/testdata/harness.go
5 files changed, 672 insertions(+), 1 deletion(-)
To view, visit change 401236. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Than McIntosh.
Than McIntosh uploaded patch set #41 to this change.
runtime/coverage: apis to emit counter data under user control
DO NOT SUBMIT
Add hooks/apis to support writing of coverage counter data and
meta-data under user control (from within an executing "-cover"
binary), so as to provide a way to obtain coverage data from programs
that do not terminate.
Updates #51430.
Change-Id: I34ee6cee52e5597fa3698b8b04f1b34a2a2a418f
---
M api/next/51430.txt
A src/runtime/coverage/apis.go
M src/runtime/coverage/emit.go
A src/runtime/coverage/emitdata_test.go
A src/runtime/coverage/testdata/harness.go
5 files changed, 677 insertions(+), 1 deletion(-)
To view, visit change 401236. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Than McIntosh.
Than McIntosh uploaded patch set #43 to this change.
runtime/coverage: apis to emit counter data under user control
DO NOT SUBMIT
Add hooks/apis to support writing of coverage counter data and
meta-data under user control (from within an executing "-cover"
binary), so as to provide a way to obtain coverage data from programs
that do not terminate.
Updates #51430.
Change-Id: I34ee6cee52e5597fa3698b8b04f1b34a2a2a418f
---
M api/next/51430.txt
A src/runtime/coverage/apis.go
M src/runtime/coverage/emit.go
A src/runtime/coverage/emitdata_test.go
A src/runtime/coverage/testdata/harness.go
5 files changed, 689 insertions(+), 1 deletion(-)
To view, visit change 401236. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Than McIntosh.
Than McIntosh uploaded patch set #47 to this change.
runtime/coverage: apis to emit counter data under user control
DO NOT SUBMIT
Add hooks/apis to support writing of coverage counter data and
meta-data under user control (from within an executing "-cover"
binary), so as to provide a way to obtain coverage data from programs
that do not terminate.
Updates #51430.
Change-Id: I34ee6cee52e5597fa3698b8b04f1b34a2a2a418f
---
A src/runtime/coverage/apis.go
M src/runtime/coverage/emit.go
A src/runtime/coverage/emitdata_test.go
A src/runtime/coverage/testdata/harness.go
4 files changed, 685 insertions(+), 0 deletions(-)
To view, visit change 401236. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Than McIntosh.
Than McIntosh uploaded patch set #52 to this change.
runtime/coverage: apis to emit counter data under user control
Add hooks/apis to support writing of coverage counter data and
meta-data under user control (from within an executing "-cover"
binary), so as to provide a way to obtain coverage data from programs
that do not terminate. This patch also adds a hook for clearing the
coverage counter data for a running program, something that can be
helpful when the intent is to capture coverage info from a specific
window of program execution.
Updates #51430.
Change-Id: I34ee6cee52e5597fa3698b8b04f1b34a2a2a418f
---
A src/runtime/coverage/apis.go
M src/runtime/coverage/emit.go
A src/runtime/coverage/emitdata_test.go
A src/runtime/coverage/testdata/harness.go
4 files changed, 829 insertions(+), 1 deletion(-)
To view, visit change 401236. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Than McIntosh.
Than McIntosh uploaded patch set #54 to this change.
runtime/coverage: apis to emit counter data under user control
Add hooks/apis to support writing of coverage counter data and
meta-data under user control (from within an executing "-cover"
binary), so as to provide a way to obtain coverage data from programs
that do not terminate. This patch also adds a hook for clearing the
coverage counter data for a running program, something that can be
helpful when the intent is to capture coverage info from a specific
window of program execution.
Updates #51430.
Change-Id: I34ee6cee52e5597fa3698b8b04f1b34a2a2a418f
---
A api/next/51430.txt
A src/runtime/coverage/apis.go
M src/runtime/coverage/emit.go
A src/runtime/coverage/emitdata_test.go
A src/runtime/coverage/testdata/harness.go
5 files changed, 834 insertions(+), 1 deletion(-)
To view, visit change 401236. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Than McIntosh.
Patch set 54:Code-Review +2
10 comments:
Patchset:
I have questions, but LGTM.
File src/runtime/coverage/apis.go:
Patch Set #54, Line 17: if operation
"if [the] operation"
for
// currently
"for [the] currently"
Patch Set #54, Line 30: if operation
"if [the] operation"
Patch Set #54, Line 46: if operation
"if [the] operation"
Patch Set #54, Line 56: if operation
same
Patch Set #54, Line 69: if !finalHashComputed {
Comparing this with above, are these error messages consistent? Is final hash a product of building with -cover, or of doing something with the metadata?
Patch Set #54, Line 116: corresponding the
"corresponding [to] the"
Patch Set #54, Line 133: nCtrs := sd[i]
Is it possible (depending on the architecture) that this requires some sort of a barrier between reading sd[i] and the data that follows? E.g., this might be dodgy on arm64.
File src/runtime/coverage/emit.go:
is 3 the same as coverage.FirstCtrOffset?
To view, visit change 401236. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: David Chase.
10 comments:
Patchset:
Thanks for the comments.
File src/runtime/coverage/apis.go:
Patch Set #54, Line 17: if operation
"if [the] operation"
Done
for
// currently
"for [the] currently"
Done
Patch Set #54, Line 30: if operation
"if [the] operation"
Done
Patch Set #54, Line 46: if operation
"if [the] operation"
Done
Patch Set #54, Line 56: if operation
same
Done
Patch Set #54, Line 69: if !finalHashComputed {
Comparing this with above, are these error messages consistent? Is final hash a product of building […]
This is more of an insanity or an internal error, as opposed to something simple like not building with "-cover".
The final hash computation takes place in a call made from the main package "init" function, so if you try to write counter data before, then you'll hit this error. E.g.
main.go:
package main
import "p"
func main() {
p.Foo()
}
p.go:
package p
import (
"bytes"
"fmt"
"os"
"runtime/coverage"
)
func init() {
var b bytes.Buffer
err := coverage.EmitCounterDataToWriter(&b)
if err != nil {
fmt.Fprintf(os.Stderr, "=-= err %v\n", err)
}
}
func Foo() {
println("foo")
}
This weird thing above would trigger the error, for example.
Patch Set #54, Line 116: corresponding the
"corresponding [to] the"
Done
Patch Set #54, Line 133: nCtrs := sd[i]
Is it possible (depending on the architecture) that this requires some sort of a barrier between rea […]
The only value that is ever written to this slot is the number of counters for the function, so while technically you have a data race (since program is still executing), there is never any danger of seeing an inconsistent value.
Maybe you can say more about what the bad scenario might be on arm64?
File src/runtime/coverage/emit.go:
is 3 the same as coverage. […]
Yes. I'll fix that up...
To view, visit change 401236. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: David Chase.
Than McIntosh uploaded patch set #55 to this change.
runtime/coverage: apis to emit counter data under user control
Add hooks/apis to support writing of coverage counter data and
meta-data under user control (from within an executing "-cover"
binary), so as to provide a way to obtain coverage data from programs
that do not terminate. This patch also adds a hook for clearing the
coverage counter data for a running program, something that can be
helpful when the intent is to capture coverage info from a specific
window of program execution.
Updates #51430.
Change-Id: I34ee6cee52e5597fa3698b8b04f1b34a2a2a418f
---
A api/next/51430.txt
A src/runtime/coverage/apis.go
M src/runtime/coverage/emit.go
A src/runtime/coverage/emitdata_test.go
A src/runtime/coverage/testdata/harness.go
5 files changed, 836 insertions(+), 1 deletion(-)
To view, visit change 401236. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Than McIntosh.
Patch set 55:Code-Review +2
1 comment:
File src/runtime/coverage/apis.go:
Patch Set #54, Line 133: nCtrs := sd[i]
The only value that is ever written to this slot is the number of counters for the function, so whil […]
The bad scenario I imagine is that the counter-number write somehow falls behind the write of the counters themselves (at least to an observer in another thread), and you run into the same problem you describe in zeroing -- that the function scanner misinterprets counter values as the function header because the actual function header is still zero.
And arm64, because to my knowledge that architecture tends more finicky about its read/write fences.
To view, visit change 401236. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: David Chase.
1 comment:
File src/runtime/coverage/apis.go:
Patch Set #54, Line 133: nCtrs := sd[i]
The bad scenario I imagine is that the counter-number write somehow falls behind the write of the co […]
OK thanks, that makes sense. I'll mull this over and see what I can come up with.
To view, visit change 401236. To unsubscribe, or for help writing mail filters, visit settings.
File src/runtime/coverage/apis.go:
Patch Set #54, Line 133: nCtrs := sd[i]
OK thanks, that makes sense. I'll mull this over and see what I can come up with.
David, one thing that we could do is require that for relaxed memory model architectures (e.g. arm64), ClearCoverageCounters could simply return an error if the program in question was not built with -covermode=atomic, and could then use atomic writes for counter clearing. Does this sound reasonable to you?
To view, visit change 401236. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Than McIntosh.
Patch set 62:Code-Review +2
2 comments:
Patchset:
more thoughts on races
File src/runtime/coverage/apis.go:
Patch Set #54, Line 133: nCtrs := sd[i]
David, one thing that we could do is require that for relaxed memory model architectures (e.g. […]
Had a thought -- the function header is not written often, so maybe, a write barrier after you do that? And/or, some synchronization between ClearCoverage Counters and writing a new function header? Or maybe ClearCoverage counters does a read barrier before every function header read?
To view, visit change 401236. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Than McIntosh.
Than McIntosh uploaded patch set #64 to this change.
runtime/coverage: apis to emit counter data under user control
Add hooks/apis to support writing of coverage counter data and
meta-data under user control (from within an executing "-cover"
binary), so as to provide a way to obtain coverage data from programs
that do not terminate. This patch also adds a hook for clearing the
coverage counter data for a running program, something that can be
helpful when the intent is to capture coverage info from a specific
window of program execution.
Updates #51430.
Change-Id: I34ee6cee52e5597fa3698b8b04f1b34a2a2a418f
---
A api/next/51430.txt
A src/runtime/coverage/apis.go
M src/runtime/coverage/emit.go
A src/runtime/coverage/emitdata_test.go
A src/runtime/coverage/testdata/harness.go
5 files changed, 840 insertions(+), 1 deletion(-)
To view, visit change 401236. To unsubscribe, or for help writing mail filters, visit settings.
1 comment:
File src/runtime/coverage/apis.go:
Patch Set #54, Line 133: nCtrs := sd[i]
Had a thought -- the function header is not written often, so maybe, a write barrier after you do th […]
For the time being I have set things up (in next patchset) so that using the clear API is only supported with -covermode=atomic, which should handle things at the moment. Maybe we can brainstorm some more offline about read barriers, that sounds like it might be a more general solution.
To view, visit change 401236. To unsubscribe, or for help writing mail filters, visit settings.
Than McIntosh uploaded patch set #66 to this change.
runtime/coverage: apis to emit counter data under user control
Add hooks/apis to support writing of coverage counter data and
meta-data under user control (from within an executing "-cover"
binary), so as to provide a way to obtain coverage data from programs
that do not terminate. This patch also adds a hook for clearing the
coverage counter data for a running program, something that can be
helpful when the intent is to capture coverage info from a specific
window of program execution.
Updates #51430.
Change-Id: I34ee6cee52e5597fa3698b8b04f1b34a2a2a418f
---
A api/next/51430.txt
A src/runtime/coverage/apis.go
M src/runtime/coverage/emit.go
A src/runtime/coverage/emitdata_test.go
A src/runtime/coverage/testdata/harness.go
5 files changed, 906 insertions(+), 1 deletion(-)
To view, visit change 401236. To unsubscribe, or for help writing mail filters, visit settings.
Patch set 72:Run-TryBot +1