summaryrefslogtreecommitdiffstats
path: root/src/internal/coverage/pkid.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/internal/coverage/pkid.go')
-rw-r--r--src/internal/coverage/pkid.go81
1 files changed, 81 insertions, 0 deletions
diff --git a/src/internal/coverage/pkid.go b/src/internal/coverage/pkid.go
new file mode 100644
index 0000000..372a9cb
--- /dev/null
+++ b/src/internal/coverage/pkid.go
@@ -0,0 +1,81 @@
+// 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",
+ "internal/chacha8rand",
+ "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
+}