mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime: add hook to register coverage-instrumented packages
Add support to the runtime for registering coverage-instrumented packages, using a new hook that can be called from the init function of an instrumented package. The hook records the meta-data symbol for the package (chaining it onto a list), and returns a package ID to be used to identify functions in the package. This new hook is not yet called; that will be added in a subsequent patch. The list of registered meta-data objects will be used (again in a future patch) as part of coverage data file writing. Special handling is required for packages such as "runtime" or "internal/cpu", where functions in the package execute before the package "init" func runs. For these packages hard-code the package ID, then record the position of the package in the overall list so that we can fix things up later on. Updates #51430. Change-Id: I6ca3ddf535197442a2603c6d7a0a9798b8496f40 Reviewed-on: https://go-review.googlesource.com/c/go/+/401234 Reviewed-by: Michael Knyszek <mknyszek@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Than McIntosh <thanm@google.com>
This commit is contained in:
parent
efa3f1749f
commit
cf83a490e4
5 changed files with 190 additions and 2 deletions
80
src/internal/coverage/pkid.go
Normal file
80
src/internal/coverage/pkid.go
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
// 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
|
||||
|
||||
// Building the runtime package with coverage instrumentation enabled
|
||||
// is tricky. For all other packages, you can be guaranteed that
|
||||
// the package init function is run before any functions are executed,
|
||||
// but this invariant is not maintained for packages such as "runtime",
|
||||
// "internal/cpu", etc. To handle this, hard-code the package ID for
|
||||
// the set of packages whose functions may be running before the
|
||||
// init function of the package is complete.
|
||||
//
|
||||
// Hardcoding is unfortunate because it means that the tool that does
|
||||
// coverage instrumentation has to keep a list of runtime packages,
|
||||
// meaning that if someone makes changes to the pkg "runtime"
|
||||
// dependencies, unexpected behavior will result for coverage builds.
|
||||
// The coverage runtime will detect and report the unexpected
|
||||
// behavior; look for an error of this form:
|
||||
//
|
||||
// internal error in coverage meta-data tracking:
|
||||
// list of hard-coded runtime package IDs needs revising.
|
||||
// registered list:
|
||||
// slot: 0 path='internal/cpu' hard-coded id: 1
|
||||
// slot: 1 path='internal/goarch' hard-coded id: 2
|
||||
// slot: 2 path='runtime/internal/atomic' hard-coded id: 3
|
||||
// slot: 3 path='internal/goos'
|
||||
// slot: 4 path='runtime/internal/sys' hard-coded id: 5
|
||||
// slot: 5 path='internal/abi' hard-coded id: 4
|
||||
// slot: 6 path='runtime/internal/math' hard-coded id: 6
|
||||
// slot: 7 path='internal/bytealg' hard-coded id: 7
|
||||
// slot: 8 path='internal/goexperiment'
|
||||
// slot: 9 path='runtime/internal/syscall' hard-coded id: 8
|
||||
// slot: 10 path='runtime' hard-coded id: 9
|
||||
// fatal error: runtime.addCovMeta
|
||||
//
|
||||
// For the error above, the hard-coded list is missing "internal/goos"
|
||||
// and "internal/goexperiment" ; the developer in question will need
|
||||
// to copy the list above into "rtPkgs" below.
|
||||
//
|
||||
// Note: this strategy assumes that the list of dependencies of
|
||||
// package runtime is fixed, and doesn't vary depending on OS/arch. If
|
||||
// this were to be the case, we would need a table of some sort below
|
||||
// as opposed to a fixed list.
|
||||
|
||||
var rtPkgs = [...]string{
|
||||
"internal/cpu",
|
||||
"internal/goarch",
|
||||
"runtime/internal/atomic",
|
||||
"internal/goos",
|
||||
"runtime/internal/sys",
|
||||
"internal/abi",
|
||||
"runtime/internal/math",
|
||||
"internal/bytealg",
|
||||
"internal/goexperiment",
|
||||
"runtime/internal/syscall",
|
||||
"runtime",
|
||||
}
|
||||
|
||||
// Scoping note: the constants and apis in this file are internal
|
||||
// only, not expected to ever be exposed outside of the runtime (unlike
|
||||
// other coverage file formats and APIs, which will likely be shared
|
||||
// at some point).
|
||||
|
||||
// NotHardCoded is a package pseudo-ID indicating that a given package
|
||||
// is not part of the runtime and doesn't require a hard-coded ID.
|
||||
const NotHardCoded = -1
|
||||
|
||||
// HardCodedPkgId returns the hard-coded ID for the specified package
|
||||
// path, or -1 if we don't use a hard-coded ID. Hard-coded IDs start
|
||||
// at -2 and decrease as we go down the list.
|
||||
func HardCodedPkgID(pkgpath string) int {
|
||||
for k, p := range rtPkgs {
|
||||
if p == pkgpath {
|
||||
return (0 - k) - 2
|
||||
}
|
||||
}
|
||||
return NotHardCoded
|
||||
}
|
||||
25
src/internal/coverage/rtcov/rtcov.go
Normal file
25
src/internal/coverage/rtcov/rtcov.go
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
// 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 rtcov
|
||||
|
||||
// This package contains types whose structure is shared between
|
||||
// the runtime package and the "runtime/coverage" package.
|
||||
|
||||
// CovMetaBlob is a container for holding the meta-data symbol (an
|
||||
// RODATA variable) for an instrumented Go package. Here "p" points to
|
||||
// the symbol itself, "len" is the length of the sym in bytes, and
|
||||
// "hash" is an md5sum for the sym computed by the compiler. When
|
||||
// the init function for a coverage-instrumented package executes, it
|
||||
// will make a call into the runtime which will create a covMetaBlob
|
||||
// object for the package and chain it onto a global list.
|
||||
type CovMetaBlob struct {
|
||||
P *byte
|
||||
Len uint32
|
||||
Hash [16]byte
|
||||
PkgPath string
|
||||
PkgID int
|
||||
CounterMode uint8 // coverage.CounterMode
|
||||
CounterGranularity uint8 // coverage.CounterGranularity
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue