mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime/coverage: restrict use of all counter-related APIs to atomic mode
The existing runtime/coverage API set includes a "ClearCounters()" function that zeros out the counter values in a running process so as enable capturing of a coverage profile from a specific execution time segment. Calling this function is only permitted if the program is built with "-covermode=atomic", due (in part) to concerns about processors with relaxed memory models in which normal stores can be reordered. In the bug in question, a test that stresses a different set of counter-related APIs was hitting an invalid counter segment when running on a machine (ppc64) which does indeed have a relaxed memory consistency model. From a post-mortem examination of the counter array for the harness from the ppc64 test run, it was clear that the thread reading values from the counter array was seeing the sort of inconsistency that could result from stores being reordered (specifically the prolog "packageID" and "number-of-counters" stores). To preclude the possibility of future similar problems, this patch extends the "atomic mode only" restriction from ClearCounters to the other APIs that deal with counters (WriteCounters, WriteCountersDir). Fixes #56197. Change-Id: Idb85d67a84d69ead508e0902ab46ab4dc82af466 Reviewed-on: https://go-review.googlesource.com/c/go/+/463695 Reviewed-by: David Chase <drchase@google.com> Run-TryBot: Than McIntosh <thanm@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
d20e688fcf
commit
61e5ea4929
2 changed files with 131 additions and 78 deletions
|
|
@ -50,11 +50,14 @@ func WriteMeta(w io.Writer) error {
|
|||
// counter data written will be a snapshot taken at the point of the
|
||||
// call.
|
||||
func WriteCountersDir(dir string) error {
|
||||
if cmode != coverage.CtrModeAtomic {
|
||||
return fmt.Errorf("WriteCountersDir invoked for program built with -covermode=%s (please use -covermode=atomic)", cmode.String())
|
||||
}
|
||||
return emitCounterDataToDirectory(dir)
|
||||
}
|
||||
|
||||
// WriteCounters writes coverage counter-data content for
|
||||
// the currently running program to the writer 'w'. An error will be
|
||||
// WriteCounters writes coverage counter-data content for the
|
||||
// currently running program to the writer 'w'. An error will be
|
||||
// returned if the 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
|
||||
|
|
@ -63,6 +66,9 @@ func WriteCounters(w io.Writer) error {
|
|||
if w == nil {
|
||||
return fmt.Errorf("error: nil writer in WriteCounters")
|
||||
}
|
||||
if cmode != coverage.CtrModeAtomic {
|
||||
return fmt.Errorf("WriteCounters invoked for program built with -covermode=%s (please use -covermode=atomic)", cmode.String())
|
||||
}
|
||||
// Ask the runtime for the list of coverage counter symbols.
|
||||
cl := getCovCounterList()
|
||||
if len(cl) == 0 {
|
||||
|
|
@ -92,7 +98,7 @@ func ClearCounters() error {
|
|||
return fmt.Errorf("program not built with -cover")
|
||||
}
|
||||
if cmode != coverage.CtrModeAtomic {
|
||||
return fmt.Errorf("ClearCounters invoked for program build with -covermode=%s (please use -covermode=atomic)", cmode.String())
|
||||
return fmt.Errorf("ClearCounters invoked for program built with -covermode=%s (please use -covermode=atomic)", cmode.String())
|
||||
}
|
||||
|
||||
// Implementation note: this function would be faster and simpler
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue